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