servervariable 보기

for each key in request.servervariables Response.Write(key & ":" & request.servervariables(key)&"
") next Response.End()

** 상기와 같은 방식으로 처리하면 post 로 받는 값도 구할수 있다 for each key in upload Response.Write(key & ":" & upload(""&key&"")&"
") next

저장프로시저 문법 (IF)

저장 프로시저 IF 구문

IF ... ELSE ...

  • 주의 : END 가 존재하시 않음. 저장 프로시저에서 IF ~ ELSE 를 사용할때의 유효 범위는 다음 1개의 쿼리문 까지 입니다. 만약 1개를 넘는 쿼리문이 필요한 경우에는 BEGIN ~ END 로 묶어주시면 됩니다.

IF ( subString( @var, 3, 1 ) = '1' ) BEGIN ... ... END ELSE BEGIN ... ... END

에러메세지 모음

[ASP] 에러메세지 모음 ASP


Microsoft VBScript 런타임 오류 error '800a01a8'

개체가 필요합니다.: 에러내용

/파일명.asp, line 에러라인번호

  • 개체이름이 잘못되었을 경우 (option explicit 상태일때는 '변수가 정의되지 않았습니다') Ex) resopnse.write "test"

Microsoft VBScript 런타임 오류 error '800a000d'

형식이 일치하지 않습니다.: 에러내용

/파일명.asp, line 에러라인번호

  • 알 수 없는 함수
  • 알 수 없는 명령어
  • 소스 중간에 임의의 문자가 들어간 경우
  • 데이터형식이 잘못됨(Ex. 매개변수에 배열이 들어가야하는데 배열이 아닌 변수가 들어감)
  • 함수가 아닌 서브로 리턴값을 받으려 할때

Microsoft VBScript 런타임 오류 error '800a01f4'

변수가 정의되지 않았습니다.: 변수명

/파일명.asp, line 에러라인번호

  • 알 수 없는 명령어, 소스 중간에 임의의 문자가 들어간 경우, 변수선언이 안되어있을때(option explicit 상태일때)

Microsoft VBScript 컴파일 오류 error '800a0400'

문장이 필요합니다.

/파일명.asp, line 에러라인번호

에러소스내용

  • 소스중간에 숫자가 변수나 서브처럼 사용되었을 경우

Microsoft VBScript 런타임 오류 error '800a01c2'

인수의 개수나 속성 할당이 잘못되었습니다.: 함수명 or 서브명

/파일명.asp, line 에러라인번호

  • 함수나 서브의 매개변수 갯수가 다름

Microsoft VBScript 컴파일 오류 error '800a0414'

Sub를 호출할 때는 괄호를 사용할 수 없습니다.

/파일명.asp, line 에러라인번호

에러소스내용

  • 함수를 리턴값을 받지 않고 사용하거나 서브를 call 없이 단독으로 사용하였을 경우

Microsoft VBScript 컴파일 오류 error '800a0408'

유효하지 않은 문자입니다.

/파일명.asp, line 에러라인번호

에러소스내용

  • 소스 중간에 한글, 한문, 특수문자 등이 들어갔을 경우

Microsoft VBScript 런타임 오류 error '800a01b6'

개체가 이 속성 또는 메서드를 지원하지 않습니다.: 해당개채

/파일명.asp, line 에러라인번호

  • 해당개체의 잘못된(없는) 메서드나 속성을 사용하려할때

Ex) response.wtite "test" response.write request.servervariable("REMOTE_ADDR")

  • set 없이 변수에 리턴값이 오브젝트인 것을 넣으려할때 Ex) mail = Server.CreateObject("CDO.Message") => set mail = Server.CreateObject("CDO.Message")

서버 개체 error 'ASP 0177 : 800401f3'

Server.CreateObject 실패

/파일명.asp, line 에러라인번호

잘못된 프로그램 ID입니다. 이 메시지에 대한 추가 정보를 보려면 다음 Microsoft 온라인 지원 사이트를 방문하십시오: http://www.microsoft.com/contentredirect.asp.

  • Server.CreateObject 로 알수없는 서버개체를 생성하려 할때 (Ex. Windows 2000 Server 가 아닌 서버에서 Server.CreateObject("CDONT.Newmail") 등을 하려할때
  • 서버컴포넌트를 서버에 등록하지 않고서 해당 서버개체를 생성하려할때

Microsoft VBScript 런타임 오류 error '800a000b'

0으로 나누기

/파일명.asp, line 에러라인번호

  • 어떤값을 0으로 나누려 할때(0을 다른값으로 나누기는 가능)

ADODB.Connection error '800a0e7a'

공급자를 찾을 수 없습니다. 올바르게 설치되지 않았을 수 있습니다.

/파일명.asp, line 에러라인번호

  • DB연결문자열에서 지정한 공급자(provider)가 없는 경우 or 오타 (--;) Ex) sConnectionString = "provider=SQLOELDB;Data Source=localhost;Initial Catalog=Northwind;User ID=sa;Password=12345;"

Microsoft OLE DB Provider for SQL Server error '80004005'

[DBNETLIB][ConnectionOpen (Connect()).]SQL Server가 없거나 액세스할 수 없습니다.

/파일명.asp, line 에러라인번호

  • 지정한 DB서버 주소가 잘못되었거나 DB가 중지상태인 경우

Microsoft OLE DB Provider for SQL Server error '80004005'

'DB명' 로그인에서 요청한 데이터베이스를 열 수 없습니다. 로그인이 실패했습니다.

/파일명.asp, line 에러라인번호

  • DB연결문자열에서 지정한 Initial Catalog (시작DB)의 DB명이 잘못되거나 없는 경우.

Microsoft OLE DB Provider for SQL Server error '80040e4d'

'DB계정명' 사용자가 로그인하지 못했습니다.

/파일명.asp, line 에러라인번호

  • 해당 DB계정이 없는 경우
  • 해당 계정의 패스워드가 잘못된 경우

Microsoft OLE DB Provider for SQL Server error '80040e2f'

'테이블명' 테이블, '컬럼명' 열에 NULL 값을 삽입할 수 없습니다. 열에서 null을 사용할 수 없습니다. INSERT이(가) 실패했습니다.

/파일명.asp, line 에러라인번호

  • NOT NULL 로 설정된 컬럼에 NULL 값을 넣으려고 할 경우( option explicit을 설정하지 않은 상태에서 해당 컬럼에 들어갈 변수명이 오타인 경우)

ADODB.Parameters error '800a0e7c'

매개 변수 개체를 잘못 정의했습니다. 제공된 정보가 일치하지 않거나 완전하지 않습니다.

/파일명.asp, line 에러라인번호

  • 파라메터 컬렉션의 매개변수의 형식을 잘못설정한 경우 (Ex. Cmd.Parameters.Append = Cmd.CreateParameter("MEM_ID", adnvarchar, adParamInput, 20, sMemId)

  • 타입 라이브러리를 지정하지 않고 타입변수(adChar, adVarchar, adInteger, adParamInput 등등.. )를 사용한 경우 (페이지 상단에 이 지정되어 있어야 타입변수 사용가능)


ADODB.Command error '800a0d5d'

응용 프로그램이 현재 작업에 대해 잘못된 형식을 가진 값을 사용하고 있습니다.

/파일명.asp, line 에러라인번호

  • 입력된 값의 형식과 지정한 형식이 다른 경우

Ex)

sAge = "23세" Cmd.Parameters.Append = Cmd.CreateParameter("MEM_AGE", adInteger, adParamInput, 4, sAge)

  • 입력될 값의 길이가 지정한 길이보다 클 경우

Ex)

sMemId = "Administrator" Cmd.Parameters.Append = Cmd.CreateParameter("MEM_ID", advarchar, adParamInput, 10, sMemId)


Microsoft OLE DB Provider for SQL Server error '80040e57'

문자열이나 이진 데이터는 잘립니다.

/파일명.asp, line 에러라인번호

  • 입력될 값의 길이와 지정한 값의 길이가 실제 컬럼의 길이보다 클 경우

Ex) 'MEM_ID varchar(20) 일 경우

sMemId = "ThisIsSuperAdministrator" Cmd.Parameters.Append = Cmd.CreateParameter("MEM_ID", advarchar, adParamInput, 30, sMemId)


Microsoft OLE DB Provider for SQL Server error '80040e0c'

명령 텍스트가 명령 개체에 대하여 설정되지 않았습니다.

/파일명.asp, line 에러라인번호

  • Command 객체에 대해여 CommandText 속성이 지정되지 않은 경우

Ex)

sSql = "" ' 쿼리가 비어있다 set Cmd = server.createobject("adodb.command") Cmd.activeconnection = sConnectionString Cmd.CommandText = sSql '변수명이 맞는지 확인


Microsoft OLE DB Provider for SQL Server 오류 '80004005' 정밀도가 잘못되었습니다.

  • 파라메터 컬렉션의 매개변수의 형식을 잘못설정한 경우 (Ex. Cmd.Parameters.Append = Cmd.CreateParameter("AGE", AdNumeric, adParamInput, 10, age) ADO type의 상수에서 일치를 하지 않을 경우 발생

상기에서는 AdNumeric를 adInteger로 변경하면 해결 자세한 내용은 http://www.shop-wiz.com/wizboard.php?BID=asp2&GID=root&mode=view&adminmode=&optionmode=&UID=26&CURRENT_PAGE=1&BOARD_NO=1&SEARCHTITLE=CONTENTS&searchkeyword=AdNumeric&category= 참조하세요

출처 : http://blog.naver.com/oyt98?Redirect=Log&logNo=100061678565

참조 : http://blueamor.tistory.com/53

또한 참조로 http://www.taeyo.net/lecture/20_Tips/DBHelper.asp 를 봐주시기 바랍니다. db관련 class입니다.

ByVal.ByRef

ByVal - 함수에 넘겨준 매개 변수 값이 함수 안에서 변하더라도 매개 변수 값은 변하지 않는다.

ByRef - 함수에 넘겨준 매개 변수 값이 함수 안에서 변하면, 매개 변수 역시 값이 변한다.

Asp에서는 주로 생략해서 사용하고, 기본적으로 ByVal이 적용되는 걸 알 수 있다.

함수안에 변수인 testNum1, testNum2를 Num1, Num2로 바꿔도 같은 결과가 나온다.

<% Dim Num1, Num2 Num1 = 10 Num2 = 20

Function Test_Return(ByVal tesNum1, ByRef tesNum2)

Test_Return = tesNum1 + tesNum2
tesNum1 = 30
tesNum2 = 50

End Function

Response.Write Test_Return(Num1, Num2) &"
" Response.Write Num1 &"
" Response.Write Num2 &"
" %>

ASP에서 사용되는 Visual Basic Procedure에서는 변수를 입력받을 때 다음 두가지 모드로 받을 수 있다.

ByRef : 호출된 프로시저가 호출 코드에서 내부 인수로 사용하는 변수의 값을 변경할 수 있도록 하는 방식으로 인수가 전달되도록 지정합니다.

ByVal : 호출된 프로시저나 속성은 호출 코드에서 내부 인수로 사용하는 변수의 값을 변경할 수 없도록 하는 방식으로 인수가 전달되도록 지정합니다.

음. 다음과 같이 쓰일 수 있다는 의미라고 보면 된다.

'// ■■ 레코드셋으로부터 Option Source를 구하는 프로시저 ■■ Function MakeOptionSourceFromRecSet(ByRef RecSet,Objnm,FirstValue) Dim ReturnSource Dim ArrV,ArrN If RecSet.EOF Then ReturnSource = "" Else ... 중략 ... RecSet.close Set RecSet = Nothing MakeOptionSourceFromRecSet = ReturnSource End Function

위와 같은 소스에서 RecSet 레코드셋을 변수로 받았다면 ByRef로 받았을 때 프로시저 안에서 해당 레코드셋을 닫으면 실 소스에서 닫을 수 없다.

예를 들어

qrystr = "select code, name from sale" set Res = Conn.Execute(qrystr) optionSrc = MakeOptionSourceFromRecSet(Res, "code", "A") Res.close Set Res = nothing

위와 같이 하면 에러가 난다는 얘기다. Res라는 변수는 MakeOptionSourceFromRecSet라는 프로시저에 주소값을 직접 참조하는 형태로 넘어갔고, 해당 프로시저 내에서 이미 Nothing 시켜주었기 때문이다.

참조 : http://monorism.com/zbxe/?mid=board&listStyle=webzine&document_srl=5413

알파벳출력(A B ..)

<% alpa = "A" do until alpa = "[" response.write ""&alpa&""&Chr(13)&Chr(10) alpa = Chr(Asc(alpa)+1) loop %>

sub, function, call 의 사용법

sub, function, call 의 사용법

프로그램에 따라 sub 나 function 을 사용하고 어떤 곳에서는 call 을 사용하고 하는 것들이 있습니다. 가장 큰 차이점은 return 값을 가지느냐 안가지느냐의 차이점입니다.

Sub abc() ''단순 처리만을 함 End Sub

Function def() ''처리결과값 리턴 ghi = def() End Function

Call 의 사용법도 상기와 같습니다. Function 을 사용하더라도 리턴값 없이 단순 처리만으로도 사용할 수 있습니다. Sub를 사용하던 Function 을 사용하던간에 리턴값이 있으면 Call을 없으면 리턴값을 받으면 됩니다.

Call abc() ghi = def()

CDO.Message.1 오류 '80040220' (window2003 에서 메일 보내기 시)

CDO.Message.1 오류 '80040220'

"SendUsing" ±¸¼º °ªAI A߸øμC¾u½A´I´U.

오류...

[해결] Set objSendMail = Server.CreateObject("CDO.Message") Set objConfig = Server.CreateObject("CDO.configuration")

Set Flds = objConfig.Fields

Flds.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 Flds.item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25 Flds.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "localhost" Flds.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverpickupdirectory") = "c:\Inetpub\mailroot\Pickup" Flds.Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 30 Flds.update

Set objSendMail.Configuration = objConfig

[출처] CDO.Message.1 오류 '80040220' 메일보내기 오류|작성자 눌린만두

ASP 해킹 방지 보안 방법

출처 : http://blog.naver.com/essbihan?Redirect=Log&logNo=100044055011 원출처 : http://www.mungchung.com/mianamssi/zboard/view.php?id=protip&page=1&sn1=&divpage=1&category=3&sn=off&ss=on&sc=off&select_arrange=headnum&desc=asc&no=366<% '//////////////////////////////////////////////////////////////////// '//가. 명령어 삽입(Command Injection) 가능성 '//////////////////////////////////////////////////////////////////// Dim title, str title = "What's Up!!! Oh my god!!!! & goodness" str = "" //변환을 수행할 함수 Sub ReplaceStr(content, byref str) content = replace(content, "'", """) content = replace(content, "&", "&") content = replace(content, "<", "<") content = replace(content, ">", ">")

str = content

End Sub

ReplaceStr title, str response.write str

%>

'//////////////////////////////////////////////////////////////////// '//나. 크로스 사이트 스크립팅 (XSS) 가능성 '//////////////////////////////////////////////////////////////////// /include/config.inc.asp <% atag = "p,br" 'XSS 허용할 태그 리스트 UploadedPath = "/Uploaded_Files/" '업로드 기본 경로 fileext = "jpg,gif,png,pcx" '허용할 확장자 리스트 %>

/include/secure.inc.asp <% '공격 위험성이 존재하는 문자들을 필터링 '문자열 입력값을 검증 '숫자형은 데이터 타입을 별도로 체크하도록 한다. Function sqlFilter(search) Dim strSearch(5), strReplace(5), cnt, data

'SQL Injection 특수문자 필터링
'필수 필터링 문자 리스트
strSearch(0)="'"
strSearch(1)=""""
strSearch(2)="\"
strSearch(3)=null
strSearch(4)="#"
strSearch(5)="--"
strSearch(6)=";"

'변환될 필터 문자  
strReplace(0)="''"
strReplace(1)=""""""
strReplace(2)="\\"
strReplace(3)="\"&null
strReplace(4)="\#"
strReplace(5)="\--"
strReplace(6)="\;"

data = search
For cnt = 0 to 6 '필터링 인덱스를 배열 크기와 맞춰준다.
    data = replace(data, LCASE(strSearch(cnt)), strReplace(cnt))
Next

sqlFilter = data

End Function

'XSS 출력 필터 함수 'XSS 필터 함수 '$str - 필터링할 출력값 '$avatag - 허용할 태그 리스트 예) $avatag = "p,br" Function clearXSS(strString, avatag) 'XSS 필터링 strString = replace(strString, "<", "<") strString = replace(strString, "\0", "")

'허용할 태그 변환
avatag = replace(avatag, " ", "")       '공백 제거
If (avatag <> "") Then
    taglist = split(avatag, ",")

    for each p in taglist
        strString = replace(strString, "<"&p&" ", "<"&p&" ", 1, -1, 1)
        strString = replace(strString, "<"&p&">", "<"&p&">", 1, -1, 1)
        strString = replace(strString, "</"&p&" ", "</"&p&" ", 1, -1, 1)
    next
End If

clearXSS = strString

End Function

'확장자 검사 '$filename: 파일명 '$avaext: 허용할 확장자 예) $avaext = "jpg,gif,pdf" '리턴값: true-"ok", false-"error" Function Check_Ext(filename,avaext) Dim bad_file, FileStartName, FileEndName

If instr(filename, "\0") Then
    Response.Write "허용하지 않는 입력값"
    Response.End
End If

'업로드 금지 확장자 체크
bad_file = "asp,html,htm,asa,hta"

filename = Replace(filename, " ", "")
filename = Replace(filename, "%", "")

FileStartName = Left(filename,InstrRev(filename,".")-1)
FileEndName = Mid(filename, InstrRev(filename, ".")+1)
    
bad_file = split(bad_file, ",")

for each p in bad_file
    if instr(FileEndName, p)>0 then
        Check_Ext = "error"
        Exit Function
    end if
next

'허용할 확장자 체크
if avaext <> "" Then
    ok_file = split(avaext, ",")

    for each p in ok_file
        if instr(FileEndName, p)>0 then
            Check_Ext = "ok"
            Exit Function
        End If
    next
End If

Check_Ext = "error"

End Function

'다운로드 경로 체크 함수 '$dn_dir - 다운로드 디렉토리 경로(path) '$fname - 다운로드 파일명 '리턴 - true:파운로드 파일 경로, false: "error" Function Check_Path(dn_dir, fname) '디렉토리 구분자를 하나로 통일 dn_dir = Replace(dn_dir, "/", "") fname = Replace(fname, "/", "")

strFile = Server.MapPath(dn_dir) & "\" & fname '서버 절대경로

strFname = Mid(fname,InstrRev(fname,"\")+1) '파일 이름 추출, ..\ 등의 하위 경로 탐색은 제거 됨
Response.Write strFname

strFPath = Server.MapPath(dn_dir) & "\" & strFname '웹서버의 파일 다운로드 절대 경로

If strFPath = strFile Then
    Check_Path = strFile '정상일 경우 파일 경로 리턴
Else
    Check_Path = "error"
End If

End Function

'IP 체크 함수 Function Check_IP(IP_Addr) If Request.Servervariables("REMOTE_ADDR") = IP_Addr Then Check_IP = "TRUE" Else Check_IP = "FALSE" End If End Function %>

/head.asp <% '페이지에서 에러가 발생하여도 페이지 오류를 외부로 출력하지 않기위해 사용 On Error Resume Next 'On Error GoTo 0도 가능하나 2003에서는 실행되지 않음 if err.number <> 0 then 'Response.Write err.description & "<BR>" & err.source & "<BR>" err.clear End if %>

/content.asp

<% 'DB연결 헤더 %> <% '보안관련라이브러리 %> <% '전역변수리스트 %> <% '초기 설정 페이지(에러 메세지 미출력) %>

<% Dim strSQL Dim intSeq, strName, strEmail, strSubject, strContent, intCount, dtmReg_Date, intExist Dim blnTag, strUserIP Dim atag

'입력값이 숫자형인 경우 IsNumeric 함수를 사용한다. If IsNumeric(seq) Then intSeq = Request.QueryString("seq") Else Response.Write "허용하지 않는 입력값입니다." Reponse.End End If

'문자(열)인 경우 sqlfilter 사용 'intSeq = sqlFilter(Request.QueryString("seq")) 'SQL Injection 필터링

'읽은 횟수 검색 strSQL = "SELECT count(*) FROM board WHERE intSeq='" & intSeq & "'"

objRs.Open strSQL, objDBConn

intExist = objRs(0) objRs.Close

If intExist <> 1 Then Response.Write "해당글이 없습니다." Else '읽은 횟수 증가 strSQL = "UPDATE board SET intCount=intCount+1 WHERE intSeq='" & intSeq & "'" objRs.Open strSQL, objDBConn

'게시물 SELECTZ
strSQL = "SELECT strName,strEmail,strSubject,strContent,intCount,strUserIP,blnTag,dtmReg_Date FROM board WHERE intSeq='" & intSeq & "'"
objRs.Open strSQL, objDBConn

strName = objRs(0)
strEmail = objRs(1)
strSubject = objRs(2)
strContent = objRs(3)
intCount = objRs(4)
strUserIP = objRs(5)
blnTag = objRs(6)
dtmReg_Date = objRs(7)

objRs.Close
Set objRs = Nothing

objDBConn.Close
Set objDBConn = Nothing

'게시물 출력값에 XSS 필터링
'사용자가 입력하는 출력되는 값은 strName, strEmail, strSubject, strContent으로 이 부분은 XSS 공격이 가능한 부분들이다.
'일반적으로 본문만 선택적으로 HTML 태그 사용을 허용하며 나머지 부분들은 사용할 수 없도록 하는것이 바람직하다.
strName = clearXSS(strName, atag)
strEmail = clearXSS(strEmail, atag)
strSubject = clearXSS(strSubject, atag)
strContent = clearXSS(strContent, atag)

'줄넘김 처리
strContent = replace(strContent, vbLf, vbLf & "<br>")

%>

내용보기
이름 <%=strName%> 등록일 <%=dtmReg_Date%>
이메일 <%=strEmail%> 조회 <%=intCount%>
제목 <%=strSubject%>
내용 <%=strContent%>
목록으로 수정하기 삭제하기
<% End If %>

'//////////////////////////////////////////////////////////////////// '//다. SQL 구문 삽입 가능성 '//////////////////////////////////////////////////////////////////// SQL Injection은 쿼리문의 잘못 해석함에서 발생하는 문제이다. 이를 해결하기 위해서는 쿼리문을 생성시에 입력된 값에 대한 유효성 검사를 수행하면 된다. ‘, “ 문자를 \’, \”로 변경해 주거나 아예 공백으로 처리하는 방법이다.

삭제해야 할 프로시저 xp_cmdshell xp_stratmail xp_sendmail xp_grantlogin xp_makewebtask

'//////////////////////////////////////////////////////////////////// '//사. 다운로드 취약성 '////////////////////////////////////////////////////////////////////

<% 'DB연결 헤더 %> <% '보안관련라이브러리 %> <% '전역변수리스트 %> <% '초기 설정 페이지(에러 메세지 미출력) %>

<% Dim dn_dir, fname, val_ok Dim UploadedPath

dn_dir = Request("dir") fname = Request("fname") '파일 이름

' IE 5.01에서는 이 방식을 사용할때 메모리 관련 문제가 발생할 수 있다. strUA = Request.ServerVariables("HTTP_USER_AGENT") If Instr(strUA, "MSIE") Then intVersion = CDbl(mid(strUA, Instr(strUA, "MSIE")+5, 3))

If intVersion < 5.01 Then
    Response.Write "error"
End If

End If

if fname = "" Then Response.Write "" End If

dn_dir = UploadedPath & dn_dir val_ok = Check_Path(dn_dir, fname)

If val_ok <> "error" Then '사용자가 다운 받는 파일과 웹서버의 파일 다운로드 경로가 맞는지 비교 Set objStream = Server.CreateObject("ADODB.Stream") 'Stream 이용

Response.ContentType = "application/unknown"    'ContentType 선언
Response.AddHeader "Content-Disposition","attachment; filename=" & fname

objStream.Open
objStream.Type = 1
objStream.LoadFromFile val_ok

download = objStream.Read
Response.BinaryWrite download

End If

Set objstream = nothing '객체 초기화 %>

[마이크로소프트웨어] - 해킹을 당한 것 같아요! (Windows편)

참조 http://nimsgern.pe.kr/blogs/nims/archive/2007/05/04/2005-05-windows.aspx

[마이크로소프트웨어] - 해킹을 당한 것 같아요! (Windows편) 이글은 2005년 05월 마이크로소프트웨어 의 파이팅어드민 란에 게재된 본인의 글입니다.

마이크로소프트의 개인용 PC 운영체제인 Windows XP나 서버계열의 OS들의 버전이 업그레이드 되면서 가장 큰 변화중의 하나가 보안의 강화이다. 실례로 XP계열 OS의 최근 서비스팩에서는 기본방화벽기능을 내장했으며, Windows 2003 서버계열의 OS에서는 2000에서는 default로 “사용가능” 하였던 서비스가 “중지상태”로 바뀌어져 있는 것을 볼 수 있다.

단적으로 표현을 하자면, “모두 열어 놓을 테니 사용하지 않으면 막아두시오!” 에서 “최대한 막아놓을 테니, 필요하면 열어서 사용하시오!” 로 그 입장이 완전히 바뀌었습니다.
문제는 필요한 서비스를 위한 명령을 숙지하지 못하고 있는 관리자가 그 기능들을 모두 Open 시켜버릴 수도 있다는 것입니다.

이로 인하여 필자에게 “윈도우 서버를 운영 중 이며, 특정 프로세스가 CPU 점유율이 너무 높습니다. 해킹을 당한 건 아닌지, 리부팅을 해도 해당 현상이 지속됩니다.” 혹은 “터미널 서비스 접속이 되지 않습니다. 터미널서비스 기본 포트인 3389 포트는 Listen 되어있는 상태이지만, 접속할 수 없습니다.”와 같은 문의가 상당수를 차지하고 있습니다.

이 경우 습관처럼 가장 먼저 의심 해야 하는 것은 Windows 서버가 해킹을 당했거나, 시스템의 성능을 저하시키는 worm에 감염된 경우 등을 의심 해보아야 합니다.

먼저 터미널 서비스가 되지 않으니, 원격접속을 해볼 수가 없습니다. 그럼 터미널 서비스부터 접속 가능하도록 해보자. 아래의 작업이 번거롭다면, 별도의 원격관리 툴을 설치해서 작업을 해야 합니다.

예로 freeware중에 VNC 라는 원격 관리 툴이 있습니다. freeware라고 해서 원격관리 툴로서의 역할을 다하지 못하는 것은 아닙니다. 접속불능인 터미널 서비스를 사용 가능하게 하자.Windows 서버를 관리하는 User의 PC는 대부분이 윈도우 계열 PC 일 것이다. 해당서버에 Netbios 포트(135,139,445 등)가 오픈 되어 있다면 해당 서버에 Session 연결 -Command 창에서 아래와 같이 입력- 을 한다.

그림1. command창을 이용한 원격서버에 Session 연결하기

이제 해당 서버의 관리자 권한을 획득하였다. 포트가 오픈 되어 있지 않거나, 사용자 이름 또는 암호를 잘못 입력하면 정상적인 연결은되지 않는다. 터미널 서비스 연결이 제대로 되지 않을 경우는 대부분이 터미널 서비스 포트가 변조되어 연결이 되지 않았을 경우가 많다. 터미널 서비스 포트 설정 정보는 Windows 레지스트리의 아래 키 값에서 확인 할 수 있다.레지스트리 실행은 command창에서 regedit 실행하면 된다. HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TerminalServer\Wds\Rdpwd\Tds\TcpPortNumber REG_DWORD 0x00000d3d(3389)

위의 정보를 확인해보면 3389 포트가 기본포트이다.

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TerminalServer\WinStations\RDP-TcpPortNumber REG_DWORD 0x00000d3d(3389)

터미널 서비스를 사용하지 않는 상태에서, 3389 포트가 Listen 이 되어있는 상태라면 대부분이 불법적인 프로그램이 터미널 서비스 포트인 3389 포트를 대체하여 사용 중 일 경우가 많다. 우선 서버의 3389포트로 커넥션 체크를 해본다.

그림 2. 포트 접속 확인하기

위와 같이 command 창에서 실행했을 때 정상적이라면 빈 화면으로 커넥션만 되어야 한다. 하지만 경험상으로 대부분 QOS-Controller Server (불특정) 라는 이름으로 연결이 될 경우 터미널 서비스가 해당 프로그램으로 대체된 것이다.

그럼 관리도구의 컴퓨터 관리 -command 창에서 compmgmt.msc명령을 입력- 를 연다.

원격 서버에 연결하려면, 컴퓨터 관리(로컬) 부분을 클릭 한 후 오른쪽 마우스 버튼 클릭 시 다른 서버로 연결항목이 있을 것 이다. 이 부분에 서버 IP Address를 입력한다.

그림 3. 원격 서버의 컴퓨터 관리 열기이후 서비스 항목을 클릭합니다.

변조된 서버에서 작업이 가능한 경우, 서버의 console로 command 창에서 “services.msc” 명령을 입력합니다 . 해당 서비스 항목에는 기본적으로 Windows 서버에서 제공하는 서비스 및 관리자가 설치한 실행 가능한 서비스 항목들이 나타납니다.

아래 URL을 참조로 기본적으로 제공되는 서비스 항목을 숙지합니다.http://www.microsoft.com/korea/technet/security/prodtech/windows/windows2000/staysecure/secopsb.asp

좋은 방법 중에 하나는 정상적인 운영되는 Windows 시스템의 서비스 부분과 해킹이 의심되는 시스템의 서비스를 비교하며 문제되는 서비스를 찾는 것 입니다. 즉, UNIX계열의 명령어 중에서 “diff file1 file2” 와 같이 변조된 서비스를 찾는 것입니다. 서비스 이름을 정상적으로 만들고 불법적인 프로세스가 실행되도록 만들어놓은 서비스가 있을 것 입니다. 아래는 불법적인 프로그램이 서비스에 등록되어있는 예입니다.

그림 4. 변조된 서비스의 예

해당 서비스를 “사용안함” 으로 변경 한 후 실행중인 서비스를 중지합니다. 변조된 서비스를 삭제하는 방법은 레지스트리에서 삭제를 하게 됩니다.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

서비스 항목 중 Remote Registry 서비스가 있습니다. 이 서비스가 실행 중일 경우 원격에서 레지스트리를 관리할 수 있습니다. 관리 측면에서는 편리하겠지만 외부에서 불법 접근한다면 시스템에 심각한 영향을 줄 수 있는 아주 취약한 서비스가 될 것이므로 주의하십시오.

그림 5. Remete Registry 서비스 확인

원격 레지스트리 연결하여 변조된 레지스트리 수정하기 먼저, 위에서 원격서버에 Session연결한 것과 같이 Administrator 권한 계정이 있어야 합니다. 시작 -> 실행 -> regedit 명령을 입력하여 레지스트리 편집기를 엽니다.

그림6. 레지스트리 편집기

그림 7. 내 컴퓨터에서 원격서버의 레지스트리를 연결한 화면

그리고 아래는 레지스트리에서 시스템 부팅 시 자동 시작되는 프로그램이 위치하는 키입니다. 해당위치에 불법적인 프로세스가 나열될 수 있습니다. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceExHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServicesHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunservicesOnce HKEY_CURRENT_USER\ SOFTWARE\Microsoft\Windows\CurrentVersion\Run

그림 8. 레지스트리에서 변조된 서비스 확인

서버에 접속이 가능하다면, 정상 접속이 되었을 경우 확인할 사항입니다. 시작 -> 실행 -> CMD 입력 -> Command 에서 아래와 같이 netstat 명령으로 현재 서버의 네트워크 연결과 프로토콜 상태를 확인할 수 있습니다. 아래의 예시 서버에서와 같이 무수히 많은 포트들과 연결 상태를 볼 수 있는데, 과연 아래 포트들은 어떤 역할을 하고 있으며, 정상적으로 사용되는 포트인지 의심스러울 경우도 있습니다.

그림 9. netstat 명령을 이용한 사용중인 포트정보 보기

이 경우 해당포트와 프로세스들이 어떻게 연결되어있는지를 확인해 볼 수 있는 툴이 있습니다. Foundstone 에서 제공하는 [freeware]fport라는 프로그램입니다. 아래 URL 에서 다운로드 받으십시오.

http://www.foundstone.com/resources/termsofuse.htm?file=fport.zip

fport 를 실행해 보자 fport 프로그램을 실행을 해보면 포트들이 하고 있는 일이 무엇인지 알 수 있을 것입니다. 이중 정상적으로 시스템파일과 mapping된 포트도 있겠지만, 의심스러운 파일로 실행되는 포트들도 볼 수 있을 것이다. 이런 프로세스를 찾아서 제거를 해야 합니다.

그림 10. fport 프로그램을 실행한 화면 서버 사용자의 계정을 확인하자.

그림 11. 사용자 계정 확인

Guest 계정은 기본적으로 “사용안함” 으로 설정 되어있습니다. 하지만 시스템이 해킹으로 인해 위와 같이 “사용가능” 하도록 되어있거나 “Administrators 그룹” 에 포함되어 있는 경우도 있습니다. 해당부분을 체크하여 Admin 권한제거 및 Guest 계정 “사용안함” 으로 설정을 하십시오.

그림 12. Guest 유저의 등록정보

에서 Administrators그룹에 등록되어 있는 경우그리고 위에서 안내한 net use 명령을 이용한 Session연결이 제한되지 않는다면, 위와 같은 문제는계속될 것 이다. 네트워크 기본 공유 중 IPC$ 는 Netbios 포트가 Open 되어 있다면 패스워드없이 목적한 서버의 Session을 얻을 수 있습니다.

그림 13. net use 명령을 이용한 IPC$ 권한 획득

특정서버의 패스워드 없이 위와 같은 명령을 실행한다면 위와 같이 IPC$ 권한을 쉽게 얻을 수 있게 됩니다. 여기에 nbtdump.exe 라는 툴이 더해진다면, 서버의 계정정보를 쉽게 확인할 수 있다.

그림 14. nbtdump 프로그램을 이용한 계정정보 확인

위 툴로 생성된 10.30.101.153.html 파일을 열어보면, 아래 그림 15와 같이 계정정보 및 아이디와 패스워드가 동일할 경우 친절하게 WARNING 메시지로 아이디 패스워드를 알려준다.

그림 15. nbtdump 프로그램을 이용한 계정 취약성

그렇다면, 취약한 포트들을 막아야 한다. 아래의 URL에서는 서버의 앞단에 별도로 방화벽을 설치하지않더라도 서버내에서 보안설정을 할 수 있는 “IPSEC”을 통하여 포트를 차단하는 방법을 설명한다. IPSEC은 *nix 계열에서 ipchain 이나 iptable과 같은 역할 한다.

http://support.microsoft.com/default.aspx?scid=kb;ko;813878

ipsecpol -w REG -p "Netbios포트필터링" -r "NetBIOS-BLOCK" -f *+0:135:TCP -f *+0:137:UDP -f *+0:138:UDP -f *+0:139:TCP -f *+0:445:TCP -n BLOCK

위에서 나열한 내용들을 모두 점검하였다면, 백신제공 웹사이트에서 제공하는 바이러스 스캔 서비스가 있다. 바이러스 검사를 실행한다. 대부분의 문제되는 서버들은 이미 백신 프로그램이 실행 중 임에도 위와 같은 문제점이 나타나 있는경우가 많다. 몇 개의 사이트에서 중복 체크하도록 하자. 위와 같은 경우로 해킹을 당하여 변조된 시스템을 대부분 치료할 수 있습니다. 의심스럽다면 시스템을 재 설치할 수도 있을 것입니다.

ASP Base64 encode/decode Source 한글 지원

출처 : http://cafe.naver.com/loveq24.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=1507 <% Option Explicit Dim sBASE_64_CHARACTERS, sBASE_64_CHARACTERSansi sBASE_64_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" sBASE_64_CHARACTERSansi = strUnicode2Ansi(sBASE_64_CHARACTERS) Function strUnicodeLen(asContents) Dim asContents1 : asContents1 ="a" & asContents Dim Len1 : Len1=Len(asContents1) Dim K : K=0 Dim I, Asc1 For I=1 To Len1 Asc1 = asc(mid(asContents1,I,1)) IF Asc1 < 0 Then Asc1 = 65536 + Asc1 IF Asc1 > 255 Then K = K + 2 ELSE K = K + 1 End IF Next strUnicodeLen = K - 1 End Function

Function strUnicode2Ansi(asContents) Dim Len1 : Len1 = Len(asContents) Dim I, VarCHAR, VarASC, VarHEX, VarLOW, VarHIGH

strUnicode2Ansi	= ""

For I = 1 to Len1
	VarCHAR	= Mid(asContents,I,1)
	VarASC	= Asc(VarCHAR)
	IF VarASC < 0 Then VarASC = VarASC + 65536
	IF VarASC > 255 Then
		VarHEX		= Hex(VarASC)
		VarLOW		= Left(VarHEX,2)
		VarHIGH		= Right(VarHEX,2)
		strUnicode2Ansi	= strUnicode2Ansi & ChrB("&H" & VarLOW ) & ChrB("&H" & VarHIGH )
	Else
		strUnicode2Ansi	= strUnicode2Ansi & ChrB(VarASC)
	End IF
Next

End Function

Function strAnsi2Unicode(asContents) Dim Len1 : Len1 = LenB(asContents) Dim VarCHAR, VarASC, I

strAnsi2Unicode	= ""

IF Len1=0 Then	Exit Function

For I=1 To Len1
	VarCHAR	= MidB(asContents,I,1)
	VarASC	= AscB(VarCHAR)
	IF VarASC > 127 Then
		strAnsi2Unicode	= strAnsi2Unicode & Chr(AscW(MidB(asContents,I+1,1) & VarCHAR))
		I		= I + 1
	Else
		strAnsi2Unicode	= strAnsi2Unicode & Chr(VarASC)
	End IF
Next

End function

Function Base64encode(asContents) Dim lnPosition Dim lsResult Dim Char1 Dim Char2 Dim Char3 Dim Char4 Dim Byte1 Dim Byte2 Dim Byte3 Dim SaveBits1 Dim SaveBits2 Dim lsGroupBinary Dim lsGroup64 Dim M3, M4, Len1, Len2

Len1			=LenB(asContents)

IF Len1 < 1 Then
	Base64encode	= ""
	Exit Function
End IF

M3=Len1 Mod 3

IF M3 > 0 Then asContents = asContents & String(3 - M3, ChrB(0))

IF m3 > 0 Then
	Len1	= Len1 + (3 - M3)
	Len2	= Len1 - 3
Else
	Len2	= Len1
End IF

lsResult	= ""

For lnPosition = 1 To Len2 Step 3
	lsGroup64	= ""
	lsGroupBinary	= MidB(asContents, lnPosition, 3)

	Byte1		= AscB(MidB(lsGroupBinary, 1, 1))	: SaveBits1	= Byte1 And 3
	Byte2		= AscB(MidB(lsGroupBinary, 2, 1))	: SaveBits2	= Byte2 And 15
	Byte3		= AscB(MidB(lsGroupBinary, 3, 1))

	Char1		= MidB(sBASE_64_CHARACTERSansi, ((Byte1 And 252) \ 4) + 1, 1)
	Char2		= MidB(sBASE_64_CHARACTERSansi, (((Byte2 And 240) \ 16) Or (SaveBits1 * 16) And &HFF) + 1, 1)
	Char3		= MidB(sBASE_64_CHARACTERSansi, (((Byte3 And 192) \ 64) Or (SaveBits2 * 4) And &HFF) + 1, 1)
	Char4		= MidB(sBASE_64_CHARACTERSansi, (Byte3 And 63) + 1, 1)
	lsGroup64	= Char1 & Char2 & Char3 & Char4

	lsResult		= lsResult & lsGroup64
Next

IF M3 > 0 Then
	lsGroup64	= ""
	lsGroupBinary	= MidB(asContents, Len2 + 1, 3)

	Byte1		= AscB(MidB(lsGroupBinary, 1, 1))	: SaveBits1	= Byte1 And 3
	Byte2		= AscB(MidB(lsGroupBinary, 2, 1))	: SaveBits2	= Byte2 And 15
	Byte3		= AscB(MidB(lsGroupBinary, 3, 1))

	Char1		= MidB(sBASE_64_CHARACTERSansi, ((Byte1 And 252) \ 4) + 1, 1)
	Char2		= MidB(sBASE_64_CHARACTERSansi, (((Byte2 And 240) \ 16) Or (SaveBits1 * 16) And &HFF) + 1, 1)
	Char3		= MidB(sBASE_64_CHARACTERSansi, (((Byte3 And 192) \ 64) Or (SaveBits2 * 4) And &HFF) + 1, 1)

	IF M3=1 Then
		lsGroup64	= Char1 & Char2 & ChrB(61) & ChrB(61)
	Else
		lsGroup64	= Char1 & Char2 & Char3 & ChrB(61)
	End IF

	lsResult		= lsResult & lsGroup64
End IF

Base64encode = lsResult

End Function

Function Base64decode(asContents) Dim lsResult Dim lnPosition Dim lsGroup64, lsGroupBinary Dim Char1, Char2, Char3, Char4 Dim Byte1, Byte2, Byte3 Dim M4, Len1, Len2

Len1	= LenB(asContents)
M4	= Len1 Mod 4

IF Len1 < 1 Or M4 > 0 Then
	Base64decode = ""
	Exit Function
End IF

IF MidB(asContents, Len1, 1) = ChrB(61) Then	M4 = 3
IF MidB(asContents, Len1-1, 1) = ChrB(61) Then	M4 = 2

IF M4 = 0 Then
	Len2	= Len1
Else
	Len2	= Len1 - 4
End IF

For lnPosition = 1 To Len2 Step 4
	lsGroupBinary	= ""
	lsGroup64	= MidB(asContents, lnPosition, 4)

	Char1		= InStrB(sBASE_64_CHARACTERSansi, MidB(lsGroup64, 1, 1)) - 1
	Char2		= InStrB(sBASE_64_CHARACTERSansi, MidB(lsGroup64, 2, 1)) - 1
	Char3		= InStrB(sBASE_64_CHARACTERSansi, MidB(lsGroup64, 3, 1)) - 1
	Char4		= InStrB(sBASE_64_CHARACTERSansi, MidB(lsGroup64, 4, 1)) - 1

	Byte1		= ChrB(((Char2 And 48) \ 16) Or (Char1 * 4) And &HFF)
	Byte2		= lsGroupBinary & ChrB(((Char3 And 60) \ 4) Or (Char2 * 16) And &HFF)
	Byte3		= ChrB((((Char3 And 3) * 64) And &HFF) Or (Char4 And 63))
	lsGroupBinary	= Byte1 & Byte2 & Byte3

	lsResult		= lsResult & lsGroupBinary
Next

IF M4 > 0 Then
	lsGroupBinary	= ""
	lsGroup64	= MidB(asContents, Len2 + 1, M4) & ChrB(65)
	IF M4=2 Then
		lsGroup64	= lsGroup64 & chrB(65)
	End IF
	Char1	= InStrB(sBASE_64_CHARACTERSansi, MidB(lsGroup64, 1, 1)) - 1
	Char2	= InStrB(sBASE_64_CHARACTERSansi, MidB(lsGroup64, 2, 1)) - 1
	Char3	= InStrB(sBASE_64_CHARACTERSansi, MidB(lsGroup64, 3, 1)) - 1
	Char4	= InStrB(sBASE_64_CHARACTERSansi, MidB(lsGroup64, 4, 1)) - 1

	Byte1	= ChrB(((Char2 And 48) \ 16) Or (Char1 * 4) And &HFF)
	Byte2	= lsGroupBinary & ChrB(((Char3 And 60) \ 4) Or (Char2 * 16) And &HFF)
	Byte3	= ChrB((((Char3 And 3) * 64) And &HFF) Or (Char4 And 63))

	IF M4=2 Then
		lsGroupBinary	= Byte1
	elseIF M4=3 Then
		lsGroupBinary	= Byte1 & Byte2
	end IF

	lsResult			= lsResult & lsGroupBinary
End IF

Base64decode			= lsResult

End Function

'################################## 사용 샘플 ################################## Dim ORIGNvalue : ORIGNvalue = "하완어환오라ㅓ고ㅓ엉ㅁㄹ22ㅁㅁ@@ㅇㅁㄹ;ㄴㅇ aabcsdfaeerdfadf" Dim EncodeA : EncodeA = strAnsi2Unicode(Base64encode(strUnicode2Ansi(ORIGNvalue))) Dim DecodeA : DecodeA = strAnsi2Unicode(Base64decode(strUnicode2Ansi(EncodeA))) response.write "------------------------------------------------------------------------<BR>" response.write "lsResult : " & ORIGNvalue & "<BR>" response.write "lsResult : " & EncodeA & "<BR>" response.write "lsResult : " & DecodeA & "<BR>" response.write "------------------------------------------------------------------------<BR>" %>

Request/Response 객체 - Cookies 컬렉션

참조 : http://blog.naver.com/jjang2121?Redirect=Log&logNo=120004097865

Request / Response 객체의 컬렉션으로 서버가 클라이언트 컴퓨터에 저장해 놓은 정보를 말하며 클라이언트가 서버에 정보를 요청시 자동으로 서버로 보내진다 (HTTP HEAD부분에서 전송)

서버는 이를 cookies 컬렉션에서 가져오기만 하면 된다

순서는 Response 객체를 이용하여 보냄 -> Request 객체를 이용하여 가져옴->사용

보낼 때는 response.cookies("쿠키이름")="값" 받을 때는 request.cookies("쿠키이름")

  • Session 객체와 마찬가지로 클라이언트와 서버간 연결상태를 유지할 수 있다
  • 로그온에 사용할 수 있다
  • 클라이언트가 쿠키를 삭제 또는 거부할 수 있다
  • Session 객체는 세션 차원, Cookies는 클라이언트컴퓨터차원이다
  • 서버의 자원절약및 부하 감소에 도움이 된다
  • 브라우저 종료/시스템 다운 과는 상관없이 Expires속성 기간만큼 존재한다

★ 쿠키 만료 날짜를 설정하면 해당 페이지를 방문할 때 사용한 컴퓨터에 쿠키가 저장됩니다. 따라서 인터넷 카페의 컴퓨터와 같은 공용 컴퓨터에서 해당 페이지로 이동하면 쿠키가 공용 컴퓨터에 저장되어 다른 누군가가 이 정보를 읽거나 복사할 가능성이 생깁니다. 쿠키 만료 날짜를 설정하지 않으면 컴퓨터의 하드 디스크가 아닌 메모리에만 쿠키가 저장되기 때문에 사용자가 브라우저를 닫자마자 컴퓨터 메모리에서 삭제됩니다.

속성; Expires 만료될(자동 소멸) 날자 지정 Domain 지정 도메인에서만 사용 Path 지정 도메인 특정 Path에서만 사용 Haskeys 다중 쿠키인지 리턴

어떤 방문자의 마지막 방문시간을 쿠키로 활용하는 예제를 ....

cookies.asp [쿠키보내기]

<% sdate=now()

'쿠키저장 response.cookies("Ltime")=sdate

'만료기간 지정 (절대) 'response.cookies("Ltime").expires=#10/10/2001#

'만료기간 지정 (상대) response.cookies("Ltime").expires=date+5 %>

cookies2.asp [쿠키 확인]

<%

'가져옴 Ltime=request.cookies("Ltime")

' 쿠키 갱신 sdate=now() response.cookies("Ltime")=sdate

if Ltime<>"" then ' 쿠키가 있는 경우 %>

안녕하세요...지난번 방문은 <%=Ltime%>이었군요

<% end if %>

[출처] [asp] Request/Response 객체 - Cookies 컬렉션|작성자 쭈니

ASP_SELF ( PHP_SELF 흉내내기 )

ASP_SELF = Request.ServerVariables("PATH_INFO") Response.Write(ASP_SELF)

현재 접속자 구하기

aspexec사용해서 ffmpeg로 mpeg->flv변경

출처 : http://iamccs.tistory.com/4

aspexec.dll-iamccs.zip

ASPExec Test (ExecuteWinApp)

ASPExec ExecuteWinApp Test

<% Set Executor = Server.CreateObject("ASPExec.Execute") Executor.Application = "ffmpeg -i test.mpeg -ar 22050 -ab 32 -f flv -s 320x240 test.flv" ' Executor.Application = "ffmpeg -i test.flv -an -ss 00:00:03 -an -r 2 -vframes 1 -y test.jpg"

Executor.ShowWindow = True Response.Write "Attempting to execute " & Executor.Application & "
" strResult = Executor.ExecuteWinApp Response.Write "The result of this call was: " & strResult

%>

GetString

GetString(2,5,"|","< BR >","Null") 첫번째는 거의 필수인것 같습니다. adClipString (adovbs.inc에도 정의되어 있지 않습니다. 그래서 2라는 enum값을 사용했구요) 두번째는 보여줄 로우의 개수(생략되면 전체,전체레코드보다 크게 지정하면 전체레코드갯수만큼) 세번째는 컬럼 구분자(생략되면 탭) 네번째는 로우 구분자(생략되면 캐리지리턴) 다섯번째는 필드가 비었을경우의 값(생략되면 빈문자)

GetString 사용예

참조로 개행문자는 chr(13) tab 은 chr(9)

<% SQL = "select * from tablename "
set rs = objCon.execute(SQL) if Rs.EOF or Rs.BOF Then ELse totalRecord = RS.GetString(2)

end if

IF totalRecord = "" or isnull(totalRecord) Then

Response.Write("없음")

ELSE rows = split(totalRecord,"|") for i = 1 to PageSize j = i - 1 'row값에 배열값 k = (cpage-1)*PageSize+i '실제 레코드순서 값

	if k<=Total_count then 
		cols     = split(rows(j),chr(9))
		value1	= cols(0)
		value2	= cols(1)
		value3	= cols(2)	
	else
		value1	= ""
		value2	= ""
		value3	= ""
		
	end if 

	Response.Write("결과출력")

next

END IF %>

ASP에서 연관배열 흉내내기

asp에서 연관배열은 언어적으로 지원하지는 않습니다.

대신 개체를 따로 제공하는데요.

생성은

VBnull: Dim dic Set dic = Server.CreateObject("Scripting.Dictionary")

Jnull: var dic = new ActiveXObject("Scripting.Dictionany")

사용은

in : dic.add("name", "value") out : a = dic("name")

<% Set a = CreateObject("Scripting.Dictionary")

a.Add "spring", "봄" a.Add "summer", "여름" a.Add "fall", "가을"

Response.write a("spring") %>

''추가 상세 사용법

'객체생성 Set dic = Server.CreateObject("Scripting.Dictionary")

'값 추가할 때 사용 dic.Add "key1", "홍길동"

'값 꺼낼 때 사용 vv = dic.Item("key1")

'key1키를 name으로 key명 변경 dic.Key("key1") = "name"

'key에 대한 값 바꾸기 dic.Item("name") = "아무개"

'key 존재여부 확인 if dic.Exists("key1") then 'key 제거
dic.Remove("key1") end if

dic.RemoveAll '모든 키제거

나머지는 속성, 메소드는 메뉴얼 참조하세요(MSDN:http://msdn.microsoft.com/library/kor/default.asp?url=/library/KOR/modcore/html/deconthedictionaryobject.asp)

<%

str1="a=1,b=2,c=3,d=4"

Dim data

Set dic = Server.CreateObject("Scripting.Dictionary")

s=split(str1,",",-1,1)

sc = ubound(s)

ReDim data(sc)

For i=0 To sc

pos = Instr(s(i), "=")

If pos > 0 Then

    temp = split(s(i),"=",-1,1)

    If ubound(temp) = 1 Then

        dic.add temp(0),temp(1)

    End If

End If

Next

Response.Write dic("a") & "<BR>" ' 변수명을 문자열로 넣어주면 값이 있는것은 찍히고 dic("e") 이런건 안찍힙니다.

Response.Write dic("b") & "<BR>"

Response.Write dic("c") & "<BR>"

Response.Write dic("d")

Set dic = Nothing

''For Each 문 사용시 For Each eachitem In wish_pay_arr response.write eachitem & ":" & wish_pay_arr.item(eachitem) & "
" Next

%>

unix time stamp로 변경하기

<% ThisTime = DateSerial(2004, 9, 27) + TimeSerial(0, 0, 0) response.write DateDiff("s", "12/31/1969 00:00:00", ThisTime) %>

<% '' 추천예제 function date2epoch(myDate) date2epoch = DateDiff("s", "01/01/1970 00:00:00", myDate) end function

function epoch2date(myEpoch) epoch2date = DateAdd("s", myEpoch, "01/01/1970 00:00:00") end function

Response.Write date2epoch(Now()) & "
" Response.Write epoch2date("1206364451") & "
" %>

프로시저

스크립트 중 여러 번 반복 실행해야 하는 스크립트가 있을경우 
그것들만 모아서 하나로 모듈화 하는 것
프로시저를 실행하고 나면 결과를 리턴하게 되는데
이를 프로시저 함수라고 함.
서브루틴
Sub (Sub 이름)
~~
End Sub
결과값있는 프로시저 함수
Function (Function 이름)

Function 이름 = 리턴값

End Function </PRE></TD> </TR> </TBODY> </TABLE>

제어문

IF문
IF (조건) Then
(조건값이 True일때 실행될 스크립트)
End IF
====================================================
IF (조건) Then
(조건값이 True일 때 실행될 스크립트)
Else
(조건값이 False일 때 실행될 스크립트)
End IF
Select Case문
(조건)
Select Case(변수 선언)

Case (조건의 값이 True일 때 실행될 스크립트)

~ ~ Case Else (조건의 값이 False일 때 실행될 스크립트)

End Select </PRE></TD> </TR> <TR> <TD>For ~Next문</TD> <TD><PRE>For (조건,범위) (반복될 스크립트) Next

dim Num, inttotal inttotal = 0

For Num = 1 To 10

inttotal = inttotal + Num response.write "+" & CStr(Num)

Next </PRE></TD> </TR> <TR> <TD>Do While~Loop문</TD> <TD><PRE>Do while (조건) (반복될 스크립트) Loop

Do While~Loop문은 조건이 True 값동안일때만 실행 </PRE></TD> </TR> </TBODY> </TABLE>

배열(다차원배열외)

로 구분되고, 각 행은 과 로 구분된다. 이제 실제 코드를 한 번 보도록 하자:

배열선언
dim arrName(3)

arrName(0) = "장동건" arrName(1) = "정우성" arrName(2) = "이연희" arrName(3) = "공효진"

*asp에서 배열은 ()로 표시하며 처음 선언할때 3을 하면 3 + 인덱스1 = 총 4개의 배열이 생성된다. </PRE></TD> </TR> <TR> <TD>다차원 배열</TD> <TD><PRE>dim arrBox(2,2)

arrBox(0,0) arrBox(0,1) arrBox(0,2) arrBox(1,0) arrBox(1,1) arrBox(1,2) arrBox(2,0) arrBox(2,1) arrBox(2,2)

총 3*3의 2차원배열이 생성된다 </PRE></TD> </TR> <TR> <TD>동적배열</TD> <TD><PRE>배열을 선언할 때 지정해야 하는 크기를 정하지 못할경우 매개 변수를 비우고 먼저 선언한 다음 크기가 결정되면 <FONT color=red>Redim</FONT>문을 이용하여 다시 선언 </PRE></TD> </TR> </TBODY> </TABLE>

오늘 본 상품

'오늘 본 최근 5개의 상품 쿠키 입력 count = Request.Cookies("cookieKey")("count") if count = "" then count = 0

Pfid = "상품명g" pPrice = "판매가b"

for i = 1 to count - 1 Response.Cookies("cookieKey" & i)("product") = Request.Cookies("cookieKey" & (i + 1))("product") Response.Cookies("cookieKey" & i)("cost") = Request.Cookies("cookieKey" & (i + 1))("cost") next

count = count + 1 if 5 < count then count = 5 Response.Cookies("cookieKey")("count") = count Response.Cookies("cookieKey" & count)("product") = Pfid '상품별 변수값 Response.Cookies("cookieKey" & count)("cost") = pPrice ' 상품별 판매가

출력 부분

<% count = Request.Cookies("cookieKey")("count")

' 출력부분 for i = count to 1 step - 1 prod = Request.Cookies("cookieKey" & i)("product") cost = Request.Cookies("cookieKey" & i)("cost") %>

<% next %>
<%=prod%>
<%=cost%>

SiteGalaxyUpload.Form.1 오류 '80004005'

window 2003 서버문제 SiteGalaxyUpload.Form.1 오류 '80004005'

ASP 파일 업로드 용량 설정문제로

  1. IIS 서비스 중지
  2. c:\windows\system32\inetsrv\MetaBase.xml (MetaBase.xml 저장시 UTF-8로 저장해야됨...)

ASPMaxRequestEntityAllowed="204800" <-- 업로드 용량제한을 200KB에서 수정해준다 ASPBufferingLimit="204800"

iisreset /stop

iisreset /start

iisreset /restart

GetString을 이용하여 ASP 처리 속도 향상시키는 방법[퍼옮]

GetString을 이용하여 ASP 처리 속도 향상시키는 방법

  <div class="post-view pcol2">
  
  

	
	
	<!-- 포스팅 -->
	이 강좌에서는 Response.Write를 여러 번 사용하는 것보다 GetString을 이용하여 ASP 스크립트의 속도 향상을 올릴 수 있는 방법에 대해 알아볼 것이다. 

대부분의 ASP 개발자들은 데이터베이스에 있는 내용을 HTML의 테이블로 표시를 해야할 경험들을 갖고 있다.

우선 다음과 같은 코드를 한 번 보도록 하자:

<%

'DB 접속 및 레코드 셋을 만든 후'레코드 셋 객체를 반복하면서 내용 출력
%><% Do While not rs.EOF %>                            ...    <% rs.MoveNext   Loop %>
<%=rs("Field1")%><%=rs("Field2")%>
 

만일 상당히 큰 데이터에 대한 쿼리를 하면 ASP 스크립트 처리 속도가 늘려진다. 왜냐하면 많은 Response.Write를 처리해야 하기 때문이다. 만일 출력해야 할 전체 문자열을 단 한 번에 출력할 수 있다면 훨씬 속도면에서 좋은 결과를 얻을 수 있다. 예를 들어 위의 예제에서

부터
사이에 있는 코드의 양이 상당히 많다면 이 부분을 단 한 번에 출력할 수 있다면 성능 향상에 도움이 될 것이다. 이 부분은 ADO 2.0 이상을 사용한다면 쉽게 해결 할 수가 있다.

ADO 2.0 이상에는 GetString이란 메쏘드가 있다. 이 메쏘드는 Response.Write를 단 한 번만 사용하여 원하는 문자열을 출력할 수 있다. 이 메쏘드를 이용하면 Do...LOOP 부분과 레코드셋이 EOF인지를 체크하는 부분이 없어도 된다.

다음은 GetString에 대한 문법이다(모든 파라미터는 옵션 처리된다):

String = recordset.GetString(StringFormat, NumRows, ColumnDelimiter, RowDelimiter, NullExpr)

레코드셋의 결과를 테이블 형태로 표시하려면 위의 GetString 메쏘드의 5개 파라미터 중 다음과 같은 3개 항목만 신경쓰면 된다:

  • ColumDelimeter : 레코드셋의 각 컬럼을 분리시킬 HTML 태그
  • RowDelimeter : 레코드셋의 각 행을 분리시킬 HTML 태그
  • NullExpr : 현재 접근한 컬럼이 NULL일 경우 사용할 HTML 태그

위 예제 코드를 이용하여 설명하자면, 각 컬럼들은

<%@ LANGUAGE="VBSCRIPT" %><% Option Explicit 'Option Explicit를 사용하는 것은 좋은 코딩 습관이다

'DB 접속Dim connSet conn = Server.CreateObject("ADODB.Connection")conn.Open "DSN=Northwind;"'레코드셋 생성Dim rsSet rs = Server.CreateObject("ADODB.Recordset")rs.Open "SELECT * FROM table1", conn'긴 문자열 저장Dim strTablestrTable = rs.GetString(,,"

","
"," ") %>

<% Response.Write(strTable) %>

<%

'클린업rs.CloseSet rs = Nothingconn.CloseSet conn = Nothing
%>
 

여기서 strTable이란 문자열은 "SELECT * FROM table1"이란 SQL문에 의해 반환된 모든 컬럼과 행을 포함하고 있다. 각 컬럼 사이에

가 나타날 것이고 각 행 사이에
가 나타날 것이다.

좀 더 쉽게 생각할 수 있도록 다음과 같은 컬럼과 행이 결과로 나왔다고 가정해 보자:

  Col1 Col2 Col3
Row1 Bob Smith 40
Row1 Ed Frank 43
Row1 Sue Void 42

GetString 메쏘드를 통해 얻은 결과 문자열은 다음과 같을 것이다:

Bob
Smith40
Ed ...

사실 위의 문장만 보면 완전한 HTML 문이 아닌 것 처럼 보이지만 strTable이란 변수 자체가

와 
사이에 있으므로 이 부분까지 합쳐지면 완벽한 HTML문이 되는 것이다.

사이에 출력할 내용이 얼마 없다면 모르지만 출력할 내용이 많을 경우 이 방법을 한 번 사용해볼 것을 권한다.

Include 파일은 부모 디렉터리를 표시하기 위해 '..'를 사용할 수 없습니다

'' 2003 사용시 '../../config/db_connect.asp' Include 파일은 부모 디렉터리를 표시하기 위해 '..'를 사용할 수 없습니다. 라는 메시지가 뜰경우 '' 인터넷정보서비스(IIS)관리 ->웹사이트->작업중인계정->속성->홈디렉토리->구성->옵션->부모경로 사용에 책크바랍니다.

[error] SiteGalaxyUpload.Form.1 error '80070006'

쓰기권한이 없을 경우 발생하는 에러

mssql 용량 및 웹용량 확인하기

데이타베이스 로그 백업 backup log db이름 with truncate_only 데이타베이스 로그 2M로 초기화 dbcc shrinkfile(db이름, 2)

데이타베이스 정보보기 exec sp_helpfile select * from sysfiles

<% dim sql, rs sql = " exec sp_helpfile " set rs = conn.execute(sql)

DBSize=rs("size") ' 사용중인 용량 DBSize=replace(DBSize,"KB","") ' 문자 치환 DBSize=FormatNumber(DBSize/1024,0) '소수점 생략

DBMAXSize=rs("maxsize") ' 총 신청 용량 DBMAXSize=replace(DBMAXSize,"KB","") ' 문자 치환 DBMAXSize=FormatNumber(DBMAXSize/1024,0) '소수점 생략

rs.close set rs = nothing

DB = 1 ' 10M = 0.1 , 20M = 0.2 ... %>

<% SET FSO = Server.CreateObject("Scripting.FileSystemObject") FolderPath = "경로" SET GF = FSO.GetFolder(FolderPath) FSize = GF.Size FSize = FormatNumber(FSize/1024,0) ' 소숫점까지 나옴 FSize = FormatNumber(FSize/1024,0) ' 소숫점 삭제

fullsize=6144000 ' 100M = 102400 , 200M = 204800 , 300M = 307200 , 400M = 409600 , 500M = 512000 fullsize=FormatNumber(fullsize/1024,0) ftpsize=50 ' 100M = 1 , 200M = 2 , 300M = 3 , 400M = 4 , 500M = 5 %>

smalldatetime 을 다른 db에 넣을때

smalldatetime 을 다른 db에 넣을때 Formatdatetime(writedate,2) & " " & Formatdatetime(writedate,4)

프로시져를 이용한 페이징 및 리스트 처리기법

-- 1. 전체 레코드수와 전체페이지수 구하기. (페이징을 위해서 실행함.)

Create Proc USP_SelectCount @TableName varchar(1000) -- 테이블명 ,@PageSize int -- 페이지당 들어가는 리스트의 수 ,@FilterString nvarchar(1000) -- 조건문장. As Begin

Set nocount on set transaction isolation level read uncommitted Set ansi_warnings off

Declare @top int -- SELECT 할 레코드의 개수 ,@sql nvarchar(2000) -- 다이나믹 쿼리문이 저장 될 변수 ,@FilterStrings nvarchar(1000)

IF @FilterString = '' or @FilterString = null Begin Set @FilterStrings = '' End Else Begin Set @FilterStrings = ' Where ' + @FilterString End

Set @sql = N'Select count(1) As TotalCount,CEILING(CAST(Count(1) As Float)/' + Cast(@PageSize As nvarchar) + ')As TotalPage '

  • N'From ' + @TableName + @FilterStrings

Exec Sp_ExecuteSQL @sql

End

  1. 실재 데이터 조회하는 프로시저 (해당페이지의 데이터만 추출함)

CREATE Proc getOderList @TableName varchar(1000) -- 테이블명 ,@PageNo int -- 현재 조회하고자 하는 페이지 ,@PageSize int -- 페이지당 들어가는 리스트의 수 ,@SelectList nvarchar(1000) -- 조회하고자 하는 컬럼목록 ,@PKField nvarchar(100) -- PK ,@FilterString nvarchar(1000) -- 조건문장. ,@SortString nvarchar(1000) -- 정렬문장.

As Begin Set nocount on set transaction isolation level read uncommitted Set ansi_warnings off

Declare @top int -- SELECT 할 레코드의 개수 ,@sql nvarchar(2000) -- 다이나믹 쿼리문이 저장 될 변수 ,@AFilterStrings nvarchar(1000) ,@BFilterStrings nvarchar(1000)

IF @FilterString = '' or @FilterString = null Begin Set @AFilterStrings = '' Set @BFilterStrings = '' End Else Begin Set @AFilterStrings = 'Where ' + @FilterString Set @BFilterStrings = 'And ' + @FilterString End

Set @sql = N'Select Top ' + Cast(@PageSize as nvarchar) + ' ' + @SelectList

  • N' From ' + @TableName + ' '
  • N' Where ' + @PKField + ' Not In '
  • N' (Select Top ' + Cast(@PageSize * (@PageNo-1) As nvarchar)+ ' ' + @PKField + ' '
  • N' From ' + @TableName
  • N' ' + @AFilterStrings + ' Order By ' + @SortString + ')'
  • @BFilterStrings + N' Order By ' + @SortString

Exec Sp_ExecuteSQL @sql -- exec @sql Set nocount off Return End

execute getOderList 'wizbuyer', '1', '10', 'uid', 'uid', '', 'uid desc'

Response.Expires=-1

<% Response.Expires=-1 %>

페이지의 캐쉬만료시간을 과거시간인 -1 로 잡는다는 설정입니다. 말이 어려워 보이는데요. 다르게 설명하면 현재의 ASP 페이지를 사용자가 요청할 때마다.. 서버로부터 새로이 불러오겠다고 설정한다는 것이랍니다. 어떤 특정 ASP 페이지가 자주 수정되는 페이지라고 예상한다면 그 페이지의 상단에.. Response.Expires = -1 처럼 지정해 주시면 그 페이지는 매번 호출될 때마다.. 서버에서 매번 수행되고, 새롭게 만들어진 페이지를 가져오게 됩니다..

하지만, 수정이 자주 일어나지 않는 페이지라면 이러한 설정은 하지 않으시는 것이 좋습니다. 매번 페이지 요청시마다 서버에서 이 ASP를 실행하기에 부하가 걸릴 수 있으니까요

Option Explicit

<% Option Explicit %>

Option Explicit 변수를 선언하고 사용하게끔 제약하는 옵션 이것은 지정하면 이후 모든 페이지레벨의 변수들을 Dim 으로 일단 선언한 뒤에 사용하셔야 합니다. 이것을 사용하는 것이 성능의 향상에 도움이 된다는 것을 다시금 기억하시기 바랍니다.

<% Option Explicit %>

<% Option Explicit %> Option Explicit 변수를 선언하고 사용하게끔 제약하는 옵션 이것은 지정하면 이후 모든 페이지레벨의 변수들을 Dim 으로 일단 선언한 뒤에 사용하셔야 합니다. 이것을 사용하는 것이 성능의 향상에 도움이 된다는 것을 다시금 기억하시기 바랍니다.

2000서버 로그화일 활용

http://www.kr.internet.com/channel/content.asp?kid=22&cid=112&nid=12277

mssql에서 필드추가 및 삭제

mssql도 mysql과 같은 타 sql과 그 구문이 다르지 않습니다.

필드추가예 ALTER TABLE wizMembers ADD [BirthDay] [varchar] (11) COLLATE Korean_Wansung_CI_AS NULL

필드삭제예 ALTER TABLE wizMembers DROP COLUMN [BirthDay]

ASP에서의 페이지 처리 하기

ASP에서는 페이지 처리 하는 방법이 몇개 있습니다. 그중 가장 많이 사용하는 방법중에 하나 입니다.

wherestr = " WHERE ( notice <> 1 or notice is null )" setPageSize = 10 setPageLink = 10 page = Request("page") : IF page = "" or isNull(page) Then page = 1

sqlstr = "SELECT COUNT(uid) FROM " & tablename & wherestr & " " SET list = DBCON.Execute(sqlstr) TotalCount = list(0) TotalPage = TotalCount / setPageSize

IF (TotalPage - (TotalCount \ setPageSize)) > 0 then TotalPage = int(TotalPage) + 1 Else TotalPage = int(TotalPage) End if

sqlstr = "select TOP " & setPageSize & " * from " & tablename & wherestr & " and uid not in (SELECT TOP " & ((page - 1) * setPageSize) & " uid from " & tablename & wherestr & " ORDER BY bd_idx_num desc) ORDER BY bd_idx_num desc "

상기까지는 리스트 보여주는 것이고

<% Dim TransDate TransData = "&bmode=list&bid=" & bid & "&gid=" & gid & "&search_title=" & search_title & "&search_keyword=" & search_keyword %>

<% IntStart = INT((((page - 1) \ setPageLink)) * setPageLink + 1) IntEnd = INT(((((page - 1) + setPageLink) \ setPageLink)) * setPageLink)

IF INT(TotalPage) < intEnd THEN IntEnd = TotalPage
IF INT(page) > INT(setPageLink) THEN
RESPONSE.WRITE "<a href='wizboard.asp?page=" & int(page - setPageLink) & TransData & "'><img src='" & skin_path & "icon/prev_btn.gif' border=0>"
RESPONSE.WRITE "<a href='wizboard.asp?page=1" & TransData & "'></a>.. &nbsp;"
END IF

%>

<% FOR I = IntStart TO IntEnd IF I = IntStart THEN 'TMPSPLIT = "" ELSE 'TMPSPLIT = "/" END IF

IF INT(I) = INT(page) THEN
RESPONSE.WRITE "&nbsp;<b>"&i&"</b>&nbsp;"
ELSE
RESPONSE.WRITE "<a href='wizboard.asp?page=" & I & TransData & "'>&nbsp;"& I & "&nbsp;</a>"
END IF
NEXT

%>

<% IF INT(TotalPage - IntStart + 1) > INT(setPageLink) THEN RESPONSE.WRITE ""

IF INT(page) + setPageLink > TotalPage + 1 THEN
ELSEIF INT(page) + setPageLink < TotalPage + 1 THEN
RESPONSE.WRITE "<a href='wizboard.asp?page=" & INT(page + setPageLink) & TransData & "'><img src='" & skin_path & "icon/next_btn.gif' border=0>"
END IF

%>

////////////////////////////////////////////////////////// 레코드 셑을 이용한 페이지 처리기법

set conn=server.createobject("adodb.connection") conn.provider="sqloledb" conn.connectionstring="server=xxxxxxx;database=xxxxx;uid=xxxx;pwd=xxxxx;" conn.open

sql = " select * from "&table_name&" "&whereis & "order by idx desc" set rs=server.createobject("adodb.recordset") rs.pagesize=15 rs.open sql,conn,1 totalpage = rs.pagecount

if rs.eof and rs.bof then ''없음 else rs.absolutepage=page i = 1 do until rs.eof or i > rs.pagesize mgrade = rs("mgrade") idx = rs("idx") rs.movenext i = i + 1 loop end if

책크박스 처리하기

<% for i = 1 to Request("key").COUNT %> <%=Request("key")(i)%> <% next %>

word/excel/powepoint

Response.ContentType = "application/vnd.ms-excel; name='My_Excel'" Response.AddHeader "Content-Disposition","attachment;filename=subject_sin_excel.xls"

@@identity

mysql+php에서는 inserted_id 와 같은 명령입니다.

create table Tmp(

UID int identity (1,1) primary key , Name varchar(10) )

insert into Tmp values ('3') select @@identity select IDENT_CURRENT('Tmp')

동시접속 방지하기

동시접속 방지하기

전화를 이용하여 PC 통신을 사용해본 사용자들이라면 하나의 아이디를 가지고 동시에 서비스에 접속하고자 할 때 한 사용자가 서비스가 중지되는 동시접속 방지의 기능을 본 적이 있을 것이다. 그러나 인터넷의 회원제 사이트에서는 이런 기능들을 찾아보기 힘들 것이다. 인터넷이라는 특성상 강제로 클라이언트를 종료하기 위한 기능들이 부족하기 때문이다. 그렇지만 실제 상용의 서비스를 하는 사이트라면 한번씩은 이 문제에 대해서 고민을 하게 된다. 만일 인터넷에서 동시접속을 방지하고자 한다면 어떻게 하면 좋을까? 지금부터 그 방법을 공개하도록 하겠다.

  1. 동시접속 방지의 밑그림

인터넷상에서 동시접속을 방지하고자 하면 어떤 알고리즘을 이용하면 가능할까? 지금부터 동시접속 방지를 위한 밑그림을 그려보겠다. 우선 홈페이지에 접속하는 클라이언트가 가지는 고유한 값이 있는지 알아보아야 한다. 크게 하드웨어적인 IP 주소가 있을 것이고, 서버에서 자동으로 할당되는 SessionID 값 등이 있을 것이다. 이중 하드웨어적인 클라이언트의 접속 주소를 나타내는 IP 주소를 동시접속 방지의 핵심 키로 이용해 보도록 하자. 처음 사용자가 접속하여 회원 로그인을 할 때 해당 클라이언트의 IP 주소를 테이블에 저장한다. 한번 사이트에 접속하였으면 동적 IP를 사용하고 있어도 그 IP의 값이 변경되지 않는다. 이런 IP의 값을 사이트 이용 중 수시로 테이블에 저장되어 있는 값과 동일한지 검사하는 과정을 거친다. 한 사용자가 접속하여 사용한다면 아무런 문제가 일어나지 않을 것이다. 그러나 동일한 아이디로 다른 사용자가 사이트의 접근을 시도하는 경우 동시접속 방지의 기능이 수행되게 하여 동시접속을 방지하게 된다. 이미 한 사용자가 neovis라는 아이디로 접속하여 사용하고 있는 상황에서 다른 사용자가 neovis라는 아이디로 접속을 시도한다고 생각해 보자. 앞서 로그인 과정에서 클라이언트의 IP 주소를 저장한다고 하였다. 그렇기 때문에 다른 컴퓨터에서 접속을 하게 되면 이미 저장되어 있는 IP 주소가 현재 접속을 시도하는 사용자의 IP 주소로 변경된다. 이렇게 되면 이미 로그인이 되어 있는 사용자는 어떻게 될까? 사이트 내에서 서비스를 이용할 때마다 현재 클라이언트의 IP 주소와 테이블에 저장되어 있는 값의 비교를 하는 동시접속 체크를 통해 IP 주소가 다른 값을 가지게 때문에 자동으로 접속을 해제시켜 버리게 될 것이다. 이런 원리를 이용하여 인터넷에서 동시접속을 방지할 수 있는 것이다.

두 대의 다른 클라이언트 컴퓨터를 사용하여 같은 사용자가 접속을 시도할 경우라도 먼저 접속한 컴퓨터에서 사이트 접속이 해제되기 때문에 서비스의 이용에서 사용자의 불편함은 없다. 또한 동적 IP를 사용하는 경우나 컴퓨터가 다운되더라도 로그인 과정에서의 동시접속에 대한 확인절차가 없기 때문에 사용자는 아무런 기능의 제약 없이 사이트로 접근할 수 있는 것이다. 단 두 사람이 동시에 접속할 때에만 체크를 하기 때문에 홈페이지 상에서 훌륭히 동시 접속 사용자를 방지할 수 있다고 하겠다.

  1. 동시접속 방지 모듈 구성하기

동시접속을 방지할 수 있는 방법을 알아보았다. 이런 알고리즘을 이용하여 실제 사이트에 적용할 수 있는 코드들을 만들어 보도록 하자. 각각의 코드들이 완벽하게 독립적으로 실행되는 것이 아니기 때문에 필요한 곳에 직접 추가시켜 작업해야 원하는 효과를 얻을 수 있을 것이다.

① 로그인 처리 부분의 IP 주소 저장

회원 테이블이나 다른 로그인에 관련된 테이블에 로그인을 하는 사용자의 IP 주소를 저장하는 부분이 추가되어야 한다. 단순히 기존의 필드의 값을 수정하는 쿼리문을 추가하면 되기 때문에 구현에 큰 문제점은 없을 것이다.


strSQL = "update member set IP = '" & Request.ServerVariables("REMOTE_ADDR") & "' where USER_ID = '" & USER_ID & "'"

IpUpdate = dbCon.execute(SQL)


회원 테이블인 member 테이블에 사용자의 IP 주소를 저장하는 IP 필드에 현재 접속하는 사용자의 IP 주소를 업데이트하는 쿼리문이다. 각 시스템에 맞게 이외의 다른 정보들도 같이 수정할 수 있으니 참고하기 바란다.

② 현재 접속 IP와 저장 IP 비교하기

이렇게 하여 저장된 IP 주소를 이용하여 사이트 이용 중 자신의 현재 IP 주소와 비교하는 과정을 거치게 된다. 실제 IP 주소의 값을 비교하는 코드는 다음과 같다.


<%

if Session("userid") <> "" then

' 접속한 사용자의 IP 주소 필드를 가져와 현재 IP 주소와 비교

strSQL = "select count(user_id) from member "

strSQL = strSQL & " where user_id='" & Session("userid") & "'"

strSQL = strSQL & " and ip = '" & Request.ServerVariables("REMOTE_ADDR") & "'"

Set Count_RS = dbCon.Execute(strSQL)

if Count_RS(0) = 0 then

' 중복 접속한 아이디 처리

' 사용자 사이트 환경에 맞게 에러 구문 처리

end if

end if

%>


위의 코드에서 보듯이 Count_RS(0)의 값이 0이면 처음 로그인을 하였을 때의 IP 주소와 현재 사용하고 있는 IP의 주소가 다른 경우를 나타낸다. 이런 경우에는 앞서 살펴보았듯이 동일한 아이디로 접속하고 있는 경우이기 때문에 해당 사용자에게 현재의 아이디가 중복 사용되고 있다는 메시지와 비밀번호 교환을 당부하는 메시지를 출력하면서 현재 접속되어 있는 세션을 끊고 사이트의 처음으로 다시 이동하면 된다. 실제 이 부분의 코드는 각 해당 사이트마다 환경이 다르므로 직접 넣어보기 바란다. 그리고 실제 동시접속을 방지하기 위해서 위의 코드를 하나의 파일로 만들어 모든 페이지에 인클루드를 시켜 사용하게 된다면 사이트 내에서 어떤 페이지로 접속하더라도 중복 사용자 확인 과정을 거치게 되는 것이다. 각 사이트의 환경에 맞게 인클루드를 직접 넣어 테스트를 해 보자.

이렇게 하여 인터넷의 홈페이지에서 하나의 아이디를 가지고 중복으로 접속하는 것을 방지하는 방법에 대해서 알아보았다. 예를 든 방법은 가장 기초적인 정보만 가지고 이용하기 때문에 부족한 부분이 많이 있을 수 있다. 각 사이트의 관리자라면 IP 주소 이외의 기타 접속 시간이나 클라이언트의 환경을 저장하여 다양한 방법으로 비교를 수행하는 방법들도 고려하여 모듈을 이용하면 더욱더 좋은 결과를 얻을 수 있을 것이다.

2003 기본 업/다운로드 용량 변경

2003 기본 업/다운로드 용량 변경

2000에서는잘 되던 다운로드가 2003 서버에서는 대용량 파일이 다운로드가 제대로 안되는 경우... 2003의 기본 다운로드 버퍼링 용량 설정 떄문인데 IIS6 에서 추가된 것임...

C:\WINDOWS\system32\inetsrv\MetaBase.xml

** 위의 메타베이스 파일을 수정하기 위해서는 관리도구 >> 인터넷정보서비스(IIS)관리 >> 인터넷정보서비스 바로 아래의 서버명(로컬 컴퓨터)의 속성창에서 메타베이스 직접 편집허용(N) 을 체크 해주셔야만 수정이 가능합니다. [출처] 2003 (IIS 6.0) 기본 업/다운로드 용량 변경|작성자 렉스

위의 XML로 작성된 메타베이스 파일에서 해당 AspBufferingLimit부분을 찾아 해당 내용을 변경하세요!! 다운로드 제한 부분 ==> AspBufferingLimit="4194304" ::: 4MByte

업로드 제한 부분 ==> AspMaxRequestEntityAllowed="204800" ::: 200KByte

html 테그 없애기

Function TagToText(inData)
    tmpCChk = Split(inData, ">")
    tmpCChkCnt = UBound(tmpCChk)
    tmpData = ""
    For i = 0 To tmpCChkCnt
        If InStr(tmpCChk(i), "<") > 0 Then
            tmpData = tmpData & Mid(tmpCChk(i), 1, InStr(tmpCChk(i), "<") - 1)
        End If
    Next
    TagToText = tmpData
End Function

CDONTS 사용하여 텍스트 메일 보내기

ASP CDONTS Mail Component

CDONTS 사용하여 텍스트 메일 보내기:

<% dim mail

    'Create the object
    set mail = server.CreateObject("CDONTS.NewMail")
    mail.From = "[email protected]" 'This is the address that the email is
    coming from.
    mail.To = "[email protected]" 'This is the email address that you are
    sending to.
    mail.Subject = "Here is the subject" 'The subject as it will appear in the
    email.
    mail.body = "The body of the email." 'Place the body here.
    'If you want to place a carriage return in the body use vbCrLf.
    mail.Send 'Send the message out.
    set mail = nothing 'Clean up after yourself.
    %></font></p>      </td>
</tr>

CDONTS 사용하여 HTML 메일 보내기:

<% 'Place these before the mail.body. mail.mailFormat = 0 mail.bodyFormat = 0 %>

CDONTS 사용하여 첨부화일 보내기:

<% mail.AttachFile server.MapPath("attachedfile.asp") 'You must use the exact server path. %>

CDONTS를 사용하여 CC(카피본)으로 메일 보내기:

<% mail.Cc = "[email protected]" %>

To display a message in the from section:

<% mail.value("Reply-To") = "[email protected]" mail.from = "I am sending this to you" 'Your message will now display in the from email address instead of your email address. 'If someone replies to your email, they will still reply to [email protected] %>

주소록 엑셀화일 불러와서 메일보내기 소스

Set oConn = Server.CreateObject("ADODB.Connection")

Set objConn = Server.CreateObject("ADODB.Connection") strConn = "Driver={Microsoft Excel Driver (*.xls)}; DBQ=" & DirectoryPath & strFileName objConn.Open strConn

ex_sql="select `Sheet1$`.`이름`, `Sheet1$`.`이메일주소`, `Sheet1$`.`회사명` "
ex_sql=ex_sql & " from `Sheet1$` "
ex_sql=ex_sql & " order by `Sheet1$`.`이름`, `Sheet1$`.`이메일주소`, `Sheet1$`.`회사명` "

Set oRS=objConn.execute(ex_sql)
	   		

Do While not oRS.eof

Set objMail = Server.CreateObject("CDONTS.NewMail")

html = content

objMail.mailformat = cdomailformatmime

if strFileName_ppt <> "" Then 'objMail.Attach objMail.attachFile DirectoryPath & strFileName_ppt end if

objMail.From="[email protected]" objMail.To=oRS("이메일주소") objMail.Subject= oRS("이름") & " 님께 : " & abc("subject")

objMail.BodyFormat = 0 ' HTML일떄 0, 일반 Text일때 1 으로 설정한다. objMail.MailFormat = 0 ' HTML일떄 0, 일반 Text일때 1 으로 설정한다. objMail.body = html
objMail.send '이제 메일을 보낸다. oRS.movenext

Set objMail =Nothing

Loop

저장프로시져 응용예제

프로시저 설명

두개의 테이블 company 및 상관하위 query를 이용한 결과 값을 임시테이블에 저장후 이값을 불러오는 프로시저

CREATE PROC TopCompany @fromcday varchar(10), @tocday varchar(10) AS SET NOCOUNT ON DECLARE @strQuery nvarchar(4000) SET @strQuery = '' Select distinct(mc.company), (select sum(count) from movie_count mc1 where mc1.company = mc.company and ( mc.cday >= @fromcday AND mc.cday <= @tocday ) ) as totalcount into #tmptable2 from movie_count mc left join jogyo j on mc.pid=j.uid where ( mc.cday >= @fromcday AND mc.cday <= @tocday ) order by totalcount desc SET @strQuery = 'SELECT top 5 * FROM #tmptable2' EXEC SP_EXECUTESQL @strQuery SET NOCOUNT OFF

웹에서의 프로시저 불러오기

<% sqlstr = "EXEC TopCompany '"&prc_sdate&"', '"&prc_tdate&"'" set list = DBCon.execute(sqlstr)

if list.EOF then Response.Write("데이타없슴") else WHILE NOT list.EOF value1 = list(0) value2 = list(1) list.MOVENEXT WEND end if %>

저장 프로시져 옵션

http://sqler.pe.kr/sql2k/714.asp

  1. 저장 프로시져 옵션

OUTPUT 역시 매개 변수 입니다.

--OUTPUT을 사용한 저장 프로시져 CREATE PROC shopwiz_proc14 @v_title_id varchar(10) , @v_output int OUTPUT AS UPDATE titles SET price = price * 2 WHERE title_id = @v_title_id SET @v_output = (SELECT @@ROWCOUNT)

--프로시져 수행 DECLARE @v_effected_rows int EXEC shopwiz_proc14 'BU1032', @v_effected_rows OUTPUT SELECT @v_effected_rows

--영향을 받은 로우의 수가 없을 경우. DECLARE @v_effected_rows int EXEC shopwiz_proc14 'BU103X', @v_effected_rows OUTPUT SELECT @v_effected_rows

자 이런 식으로 수행이 됩니다. 수행 방식이 약간 특이 하지요. 아울러 프로시져 생성 부에서 매개변수 지정시 OUTPUT 키워드를 주는 부분이 역시나 조금 특이할 뿐입니다. 위의 예제는 간단히 @@ROWCOUNT 라는 시스템 함수로.. 테이블에서 영향을 받은(수정, 삭제, 삽입 등) 행의 수를 리턴 합니다. 이를 이용해 UPDATE가 적절히 잘 이루어 졌는지 확인이 가능하지요.

 

자 이제 많은 분들이 오해하고 계시고!!! 아울러 어려워하는!!!

SELECT가 포함된 프로시져의 OUTPUT 매개변수 사용 입니다.

--OUTPUT을 사용한 저장 프로시져 SELECT 포함 CREATE PROC shopwiz_proc15 @v_title_id varchar(10) , @v_output int OUTPUT AS UPDATE titles SET price = price * 2 WHERE title_id = @v_title_id SELECT * FROM titles SET @v_output = (SELECT @@ROWCOUNT)

--프로시져 수행 DECLARE @v_effected_rows int EXEC shopwiz_proc15 'BU1032', @v_effected_rows OUTPUT SELECT @v_effected_rows

--영향을 받은 로우의 수가 없을 경우. DECLARE @v_effected_rows int EXEC shopwiz_proc15 'BU103X', @v_effected_rows OUTPUT SELECT @v_effected_rows

 

자 결과를 봐 보세요..

어렵지 않게 먼저 수정된 결과로 1개 행 적용된 메세지..

아울러 SELECT 결과.. 아울러 OUTPUT 매개변수 결과를 보실 수 있습니다.

많은 분들이 OUTPUT값만 받거나 SELECT 결과만 받거나.. 둘중의 하나만 생각

하시지만. 실제로는 모든 결과를 받으실 수 있습니다. ^_^ OUTPUT 매개변수는

전혀 다른 중요한 떨거지 값이라는 것이지요. - 작문실력 꽝!. T.T

 

하지만.. 문제가 있습니다. ^_^

뭘까요? - ASP등으로 개발해 보신분은 조금 감이 오실 겁니다.

위의 결과 - OUTPUT 값을 ASP에서 받아서 사용하실 수 없습니다. - 코난이가 아는한...

이유인 즉슨.. 결과셋이 3개이기 때문입니다.

  1. UPDATE 결과셋

  2. SELECT 결과셋

  3. OUTPUT 결과셋

ASP의 레코드 셋이라고 생각하시면 좋습니다.

이를 편법을 이용해 2개의 결과셋으로 줄일 수 있습니다.

--OUTPUT을 사용한 저장 프로시져 SELECT 포함 CREATE PROC shopwiz_proc17 @v_title_id varchar(10) , @v_output int OUTPUT AS SET NOCOUNT ON UPDATE titles SET price = price * 2 WHERE title_id = @v_title_id SELECT * FROM titles SET @v_output = (SELECT @@ROWCOUNT)

--프로시져 수행 DECLARE @v_effected_rows int EXEC shopwiz_proc17 'BU1032', @v_effected_rows OUTPUT SELECT @v_effected_rows

--영향을 받은 로우의 수가 없을 경우. DECLARE @v_effected_rows int EXEC shopwiz_proc17 'BU103X', @v_effected_rows OUTPUT SELECT @v_effected_rows

 

바로 SET NOCOUNT ON 이라는 녀석 입니다.

결과셋중 UPDATE 결과셋은 리턴 값이 없는.. 오로지 영향받은 행의 수만 리턴 합니다.

이럴 경우 SET NOCOUNT ON을 이용해 결과 값이 없을 경우 결과 셋으로 처리 안하실

수 있습니다. - 이러면 UPDATE 결과셋이 안넘어 오니 두개의 결과셋이 오지요.

COMPUTE의 결과셋 - (여러개의 결과셋)을 이용할 수 없는 이유와 같다고 보시면 됩니다.

ASP에서는 이를 받아서 처리하실 수 없습니다.

하지만.. VB + DB 나.. ASP + 컴퍼넌트 + DB 를 이용할 경우 사용이 가능합니다.

ADO의 Recordset 메서드 중에서 NextRecoedset을 이용하면 사용이 가능합니다.

하지만. ASP + DB일 경우 사용이 불가 합니다. 이점 주의하세요.

사실 @@ROWCOUNT나 @@ERROR 와 같은 전역 함수는 매우 유용합니다.

제대로 수행을 했는지 안했는지 판단하는 기준이 되니까요.. 약간 안타까운 부분이지요.

 

다음은 RETURN을 사용하는 방식 입니다. 역시나 이용이유는 OUTPUT과 비슷 합니다. ^_^

--RETURN을 사용한 저장 프로시져 CREATE PROC shopwiz_proc16

@v_title_id varchar(10) AS UPDATE titles SET price = price * 2 WHERE title_id = @v_title_id RETURN @@ROWCOUNT

--프로시져 수행 DECLARE @v_effected_rows int EXEC @v_effected_rows = shopwiz_proc16 'BU1032' SELECT @v_effected_rows

--영향을 받은 로우의 수가 없을 경우. DECLARE @v_effected_rows int EXEC @v_effected_rows = shopwiz_proc16 'BU103X' SELECT @v_effected_rows

 

 

역시나 SELECT가 포함된 RETURN을 이용하는 방식 입니다. ^_^

--RETURN을 사용한 저장 프로시져 SELECT 포함 CREATE PROC shopwiz_proc18 @v_title_id varchar(10) AS UPDATE titles SET price = price * 2 WHERE title_id = @v_title_id SELECT * FROM titles RETURN @@ROWCOUNT

--프로시져 수행 DECLARE @v_effected_rows int EXEC @v_effected_rows = shopwiz_proc18 'BU1032' SELECT @v_effected_rows

--영향을 받은 로우의 수가 없을 경우. DECLARE @v_effected_rows int EXEC @v_effected_rows = shopwiz_proc18 'BU103X' SELECT @v_effected_rows

 

 

지연된 이름 확인

자 이제는 저장 프로시져의 옵션에 대해서 이야기를 드릴 시간이군요. ^_^

자 첫번째 이야기는 지연된 이름 확인이라는 약간 생소한 녀석 입니다.

프로시져 내부에서 다른 저장 프로시져를 호출할 수 있을까영? ^_^

  • 가능합니다. 32개 까지 중첩이 가능합니다. - 트리거 같지용 ^_^

문제는 프로시져 내부에서 수행하는 프로시져가 존재하는가 입니다.

--shopwiz_proc99라는 존재하지 않는 프로시져 수행 CREATE PROC shopwiz_proc20 AS SELECT TOP 1 * FROM titles EXEC shopwiz_proc99

--오류 메세지 존재하지 않는 개체 'shopwiz_proc99'에 의존하고 있으므로 현재 저장 프로시저의 sysdepends에 행을 추가할 수 없습니다. 저장 프로시저는 만들어집니다.

--수행결과는? EXEC shopwiz_proc20

--shopwiz_proc99 프로시져 생성 CREATE PROC shopwiz_proc99 AS SELECT TOP 10 * FROM titles

--수행결과는? EXEC shopwiz_proc20

EXEC shopwiz_proc99

 

지연된 이름확인에 대한 간단한 이야기였는데요.. 별 어려운 내용은 아니실 겁니다.

참고로.. 우리가 생성된 저장 프로시져를 역추적 해 보지용. ^_^

--sysobjects 테이블에서 타입은 프로시져이고 --이름이 shopwiz_proc20 인 프로시져의 name과 id 조회 SELECT name, id FROM sysobjects WHERE xtype = 'P' and name = 'shopwiz_proc20'

-- < ID 값 - 코난이의 경우 434100587 임.. 님들의 값과 다를 겁니당.

--해당 ID값으로 syscomments 테이블에서 데이터 조회 --코난이와 다른 값을 주셔야 겠지요? ^_^ SELECT id, text FROM syscomments where id = 434100587

--참고로 sysdepends 테이블에서 의존성을 확인해 보자. SELECT id, depid FROM sysdepends where id = 434100587

--sysdepends 테이블에서 조회된 id로 어떤 DB개체인지 알아보자. SELECT name, id FROM sysobjects WHERE id = '2121058592'

--코난이의 경우 titles 테이블 이었습니다. ^_^

매개변수를 사용한 저장 프로시져

참조 : http://sqler.pe.kr/sql2k/713.asp

  1. 매개변수를 사용한 저장 프로시져

USE pubs GO

--프로시져 생성 CREATE PROC shopwiz_proc6 AS SELECT * FROM titles

--프로시져 수행 EXEC shopwiz_proc6

 

자 저러한 프로시져에서 조건을 주어서... price가 얼마 이상인 녀석이 처리되게 해 봅시다.

 

--프로시져 생성(상수처리) CREATE PROC shopwiz_proc7 @v_price int AS SELECT * FROM titles WHERE price > @v_price

--프로시져 수행 EXEC shopwiz_proc7 10

EXEC shopwiz_proc7 20

--프로시져 생성(문자열 처리) CREATE PROC shopwiz_proc8 @v_title varchar(10) AS SELECT * FROM titles WHERE type = @v_title

--프로시져 수행 EXEC shopwiz_proc8 'business'

EXEC shopwiz_proc8 business

EXEC shopwiz_proc8 'mod_cook'

-- insert 구문

--테스트 테이블 생성 CREATE TABLE konan_test9( c1 int, c2 varchar(10) )

--프로시져 생성 CREATE PROC shopwiz_proc9 @v_c1 int, @v_c2 varchar(10) AS INSERT INTO konan_test9(c1, c2) VALUES(@v_c1, @v_c2)

--프로시져 수행 EXEC shopwiz_proc9 1, 'Hi~'

EXEC shopwiz_proc9 2, '테스트'

--데이터 조회 SELECT * FROM konan_test9

 

--문자열 생성 방식

--프로시져 생성 CREATE PROC shopwiz_proc10 @v_tblname varchar(20) , @v_title_id varchar(20) AS

--저장할 변수 선언 DECLARE @v_strSQL VARCHAR(200)

--변수 @v_strSQL에 생성된 문자열 저장 SET @v_strSQL = 'SELECT * FROM ' + @v_tblname + ' WHERE title_id = ''' + @v_title_id + '''' EXEC(@v_strSQL) --SELECT @v_strSQL

--프로시져 수행 EXEC shopwiz_proc10 'titles', 'BU1032'

EXEC shopwiz_proc10 'titles', 'BU1111'

EXEC shopwiz_proc10 'titleauthor', 'BU1111'

EXEC shopwiz_proc10 'titleauthor', 'BU1032'

[설명]

CREATE PROC shopwiz_proc10 @v_tblname varchar(20) , @v_title_id varchar(20)

자 저는 매개변수를 두개 받았습니다.

이름에서 대강 느끼시겠지만.. 테이블을 받을 변수 @v_tblname,

title_id를 받을 변수 @v_title_id 를 두었습니다. ^_^

--저장할 변수 선언 DECLARE @v_strSQL VARCHAR(200) --변수 @v_strSQL에 생성된 문자열 저장 SET @v_strSQL = 'SELECT * FROM ' + @v_tblname + ' WHERE title_id = ''' + @v_title_id + ''''

프로시져 내부에서 사용할.. 문자열 연결로 SQL구문을 생성할 변수인

@v_strSQL 변수를 생성 했습니다. 아울러 VARCHAR(200) 이라는 조금 긴 문자열도

저장이 가능하게 생성 했습니다.

이어서 SET 구문을 이용해 @v_strSQL 변수에 문자열을 구성합니다.

작은따옴표 의 갯수가 상당히 중요 합니다.

작은 따옴표 하나를 문자열 내에서(문자열은 작은 따옴표로 묶이지요) 표현 하려면?

작은 따옴표 두개를 사용해야 합니다.

아울러 쿼리의 띄어쓰기도 주의 하셔야 합니다. FROM 절의 앞과 뒤에서 공백을 하나씩

주어서 문제없이 SQL구문이 생성되도록 주의해 주셔야 합니다.

끝으로...

EXEC(@v_strSQL) --SELECT @v_strSQL

두줄 입니다.

해당하는 쿼리를 디버깅 하는 것은 상당히 귀찮은 작업 입니다.

--EXEC(@v_strSQL) SELECT @v_strSQL 처음 수행시는 이처럼..

수행을 하는 구문인 EXEC 구문대신에.. 아래처럼 SQL구문이 SELECT되게 하는

프로시져를 생성 합니다.

그러면 위에서 약간 복잡한 해당하는 SQL구문이 구성된 녀석이 프로시져 수행시

리턴 될겁니다. 그런후 결과창의 구성된 SQL구문을 질의 분석기(쿼리 어낼라이져)로

옮기신후 여기서 수행해 보신후 잘 생성이 되었나 안되었나를 알아 보신후

테스트 해 보시면 되겠지요. 그런후 ALTER PROCEDURE 구문으로

해당 프로시져를

EXEC(@v_strSQL) --SELECT @v_strSQL

이러한 식으로 EXEC - 수행되게 변경을 하신후.. 프로시져를 수행 하시면?

결과가 잘 나오는 것을 보실 겁니다. ^_^

 

그렇다면!!! 왜 저런 복잡한듯한... 문자열 생성 방식을 사용해야 하는 것인가!!! 간단합니다. 테이블명과 같은 객체형 값(Object Value)는 프로시져의 매개변수로 사용이 불가 합니다. 객체형 값(Object Value) : 테이블명, TOP xx,

--프로시져 생성 - 수행 안됨 CREATE PROC shopwiz_proc11 @v_tblname varchar(20) AS SELECT * FROM @v_tblname

--일반 비교값으로 생성하는 프로시져 CREATE PROC shopwiz_proc11 @v_title_id varchar(20) AS SELECT * FROM titles WHERE title_id = @v_title_id

--프로시져 수행 EXEC shopwiz_proc11 'BU1032'

 

천천히 프로시져의 수행 방식을 생각해 보신다면 이해가 되실 겁니다.

 

다음으로 TOP 구문을 이용할 경우 입니다.

SELECT TOP 10 * FROM titles 이런 식으로 사용을 하시지요?

이때 10 과 같은 TOP의 값을 수행하고 싶을 경우 입니다.

--프로시져 생성 - 수행 안됨 CREATE PROC shopwiz_proc12 @v_topN int AS SELECT top @v_topN * FROM titles

--프로시져 생성 - 프로시져 생성은 가능. 수행은 불가 CREATE PROC shopwiz_proc12 @v_topN int AS DECLARE @v_strSQL VARCHAR(200) SET @v_strSQL = 'SELECT top ' + @v_topN + ' * FROM titles' EXEC(@v_strSQL)

--프로시져 수행. 수행 불가 EXEC shopwiz_proc12 '10'

--프로시져 생성 CREATE PROC shopwiz_proc13 @v_topN varchar(5) --여기가 틀림 AS DECLARE @v_strSQL VARCHAR(200) SET @v_strSQL = 'SELECT top ' + @v_topN + ' * FROM titles' EXEC(@v_strSQL)

--프로시져 수행 EXEC shopwiz_proc13 '10'

저장프로시저 - 1

참조 : http://sqler.pe.kr/sql2k/712.asp

생성

-- pubs database를 사용한다. (일반적으로 사용하지 않음) USE pubs GO

--프로시져 생성구문 CREATE PROC 프로시저명 AS SELECT pub_id 저자, type 책종류, royalty 로열티, ytd_sales 팔린수, AVG(price) 평균값 FROM titles GROUP BY pub_id, type, royalty, ytd_sales WITH CUBE GO

--프로시져 수행 구문 EXEC up_konan2

--프로시져 수정구문 ALTER PROC 프로시저명 AS SELECT pub_id FROM titles GO

--프로시져 수행 구문 EXEC 프로시저명

  --프로시져 삭제 DROP Proc 프로시저명

--프로시져 생성구문 조회 sp_helptext 프로시저명

저장 프로시져 생성구문 암호화 ALTER PROC up_konan3 WITH ENCRYPTION AS SELECT pub_id, title FROM titles GO

저장 프로시져의 종류

  1. 사용자 정의 저장 프로시져 - 여지껏 저희가 생성하고 수행해본 것

  2. 시스템 저장 프로시져 - sp_help, sp_helptext 와 같이 sp_로 시작하는 프로시져

  3. 확장 시스템 저장 프로시져 - xp_ 로 시작하는 프로시져를 의미

ex) EXEC master..xp_cmdshell 'dir'

시간관련 사용자 정의함수

<% '+++++++++++++++++++++++++++++++++++++++ '함수명 : getWeekDayNum(chkDate) '인자 : chkDate - 문자열 '기능 : 날짜를 받아 날짜의 정수값 표현리턴
'+++++++++++++++++++++++++++++++++++++++ Function getWeekDayNum (chkDate) Dim chkVal chkVal = WeekDay(chkDate)

    getWeekDayNum = chkVal

End Function

'+++++++++++++++++++++++++++++++++++++++ '함수명 : getDayName(chkDate) '인자 : chkDate - 문자열 '기능 : 날짜를 받아 요일명 리턴
'+++++++++++++++++++++++++++++++++++++++ Function getDayName (chkDate) Dim chkVal, strDayName chkVal = WeekDay(chkDate) strDayName = WeekDayName(chkVal)

    getDayName = strDayName

End Function

'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ '함수명 : getMonthFirstSunday(chkDate) '인자 : chkDate - 문자열("YYYY-MM-DD") '기능 : 날짜를 받아 그 달의 첫번째 일요일 날짜 리턴
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Function getMonthFirstSunday(chkDate) Dim chkVal, thisMonthStart

    thisMonthStart = DateSerial(Year(chkDate), Month(chkDate),1)
    chkVal = WeekDay(thisMonthStart)'WeekDay 요일을 나타내는 정수 일요일: 1....
    If chkVal = 1 then
        getMonthFirstSunday = thisMonthStart
    Else
        getMonthFirstSunday = DateAdd("d",7-chkVal+1 , thisMonthStart)
    End If

End Function

'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ '함수명 : getMonthLastSunday(chkDate) '인자 : chkDate - 문자열 '기능 : 날짜를 받아 그 달의 마지막 일요일 날짜 리턴
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Function getMonthLastSunday(chkDate) Dim chkVal, nextMonthStart

    nextMonthStart = DateSerial(Year(chkDate), Month(chkDate)+1,1)
    chkVal = WeekDay(nextMonthStart)
    
    If chkVal = "1" then
        getMonthLastSunday = DateAdd("ww",-1, nextMonthStart)
    Else
        getMonthLastSunday = DateAdd("d",-(chkVal-1) , nextMonthStart)
    End If

End Function

'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ '함수명 : getFirstDayofTheMonth(chkDate) '인자 : chkDate - 문자열("YYYY-MM-DD") '기능 : 날짜를 받아 그 달의 첫번째 일을 리턴
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Function getFirstDayofTheMonth(chkDate) Dim chkVal getFirstDayofTheMonth = DateSerial(Year(chkDate), Month(chkDate),1) End Function

'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ '함수명 : getLastDayofTheMonth(chkDate) '인자 : chkDate - 문자열("YYYY-MM-DD") '기능 : 날짜를 받아 그 달의 마지막 일을 리턴
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Function getLastDayofTheMonth(chkDate) Dim chkVal getLastDayofTheMonth = DateSerial(Year(chkDate), Month(chkDate)+1,0) End Function

'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ '함수명 : getFirstDayofTheMonth(chkDate) '인자 : chkDate - 문자열("YYYY-MM-DD") '기능 : 날짜를 받아 그 달의 첫번째 일을 리턴
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Function getFirstDayofTheQuarter(chkDate) Dim chkVal, QuarterMonth QuarterMonth = 1 + (DatePart("q", chkDate)-1)*3 getFirstDayofTheQuarter = DateSerial(Year(chkDate), QuarterMonth,1) End Function

'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ '함수명 : getLastDayofTheMonth(chkDate) '인자 : chkDate - 문자열("YYYY-MM-DD") '기능 : 날짜를 받아 그 달의 마지막 일을 리턴
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Function getLastDayofTheQuarter(chkDate) Dim chkVal, QuarterMonth QuarterMonth = DatePart("q", chkDate)*3 getLastDayofTheQuarter = DateSerial(Year(chkDate), QuarterMonth+1,0) End Function '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ '함수명 : getSaturdayOfTheDay(chkDate) '인자 : chkDate - 문자열("YYYY-MM-DD") '기능 : 날짜를 받아 그주의 마지막 토요일 날짜 리턴
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Function getSaturdayOfTheDay(chkDate) Dim chkVal chkVal = WeekDay(chkDate)'WeekDay 요일을 나타내는 정수 일요일: 1.... If chkVal = 1 then getSaturdayOfTheDay = chkDate Else getSaturdayOfTheDay = DateAdd("d",7-chkVal , chkDate) End If End Function

'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ '함수명 : getSundayOfTheDay(chkDate) '인자 : chkDate - 문자열 '기능 : 날짜를 받아 날짜의 주차의 해당 일요일을 리턴 '++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Function getSundayOfTheDay(chkDate) Dim chkVal, firstSunDay firstSunday = getMonthFirstSunDay(chkDate) diff = DateDiff("ww",firstSunday, chkDate) If diff = 0 then getSundayOfTheDay = firstSunday Else getSundayOfTheDay = DateAdd("ww",diff,firstSunday) End If End Function

'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ '함수명 : getWeekSunDayCnt(chkDate) '인자 : chkDate - 문자열 '기능 : 날짜를 받아 날짜의 주차의 해당 일요일의 그 달의 카운터를 리턴 '++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Function getWeekSunDayCnt(chkDate) Dim chkVal, firstSunDay

    firstSunday = getMonthFirstSunDay(chkDate)
    
    diff = DateDiff("ww",firstSunday, chkDate)
    
    If diff = 0 then
        getWeekSunDayCnt = 1
    Else
        getWeekSunDayCnt = diff+1
    End If
        

End Function

'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ '함수명 : getFirstDayofTheYear(chkDate) '인자 : chkDate - 문자열("YYYY-MM-DD") '기능 : 날짜를 받아 그 달의 첫번째 일을 리턴
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Function getFirstDayofTheYear(chkDate) Dim chkVal getFirstDayofTheYear = DateSerial(Year(chkDate), 1,1) End Function

'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ '함수명 : getLastDayofTheyear(chkDate) '인자 : chkDate - 문자열("YYYY-MM-DD") '기능 : 날짜를 받아 그 달의 마지막 일을 리턴
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Function getLastDayofTheyear(chkDate) Dim chkVal getLastDayofTheyear = DateSerial(Year(chkDate), 12+1,0) End Function %>

컴포넌트 CDO(Collaboration Data Object)

CDO(Collaboration Data Object) 메일을 보낼때 사용하는 컴포넌트 서버컴포넌트 이므로 기본적으로 서버에 깔려 있습니다. 설치여부 확인 먼저 C:\Windows\system\inetsrv폴더에 Cdonts.DLL파일이 유무확인 없으면 Microsort 홈페이지에서 다운로드후 inetsrv폴더에 저장 도스모드에서 C:\Windows\system\inetsrv>Regsvr32 Cdonts.DLL 입력후 엔터

CDONTS 컴포넌트를 이용한 간단 메일 보내기 예제..

  1. 텍스트기반 메일 보내기

Set objMail = Server.CreateObject("CDONTS.NewMail") objMail.From = "[email protected]" objMail.To = "[email protected]" objMail.Subject = "제목: 텍스트 메일 예제 입니다." objMail.Body = "본문: 텍스트 메일 예제 입니다." objMail.Send Set objMail = Nothing

2.HTML기반 메일 보내기

Set objMail = Server.CreateObject("CDONTS.NewMail") objMail.From = "[email protected]" objMail.To = "[email protected]" objMail.Subject = "제목: HTML 메일 예제 입니다." objMail.BodyFormat = 0 objMail.MailFormat = 0 objMail.Body = "본문: <H2>HTML 메일 예제 입니다." objMail.Send Set objMail = Nothing

CommandType 속성

 

CommandType 속성

CommandType 속성은 Command 개체의 형식을 나타내며, 다음 표의 값을 지정할 수 있다.

상수 설명
adCmdUnspecified -1 CommandType 인수를 지정하지 않는다.
adCmdUnknown 8 디폴트 값, Command 개체의 타입을 알 수 없음으로 지정한다.
adCmdText 1 명령어 또는 저장 프로시저를 텍스트로 지정한다.
adCmdTable 2 테이블을 지정한다(내부적으로 생성된 SQL 문장에 의해서 필드가 생성된다).
adCmdStoredProc 4 저장 프로시저를 지정한다.
adCmdFile 256 Persisted Recordset 개체의 파일명을 지정한다.
adCmdTableDirect 512 테이블을 지정한다(모든 필드가 생성된다).

CommandType 속성의 값이 디폴트 값인 adCmdUnknown일 경우에는 CommandText 속성이 SQL 문장인지, 저장 프로시저인지, 테이블의 이름인지를 결정하기 위해서 ADO는 Provider를 호출하게 되고, CommandType 속성을 정확하게 지정한 경우 보다 Command 개체가 수행하기 위해 부하가 더 걸리게 된다. 그렇기 때문에 CommandType 속성을 정확하게 지정하고 사용하면 디폴트 값을 사용하는 것보다 빠른 속도로 명령을 실행하게 된다. CommandType 속성에 지정한 값과 실제 실행에 사용될 명령의 형식이 맞지 않을 경우에는 Execte 메서드를 사용할 때 오류가 발생하게 된다.

Execute 메서드를 사용할 때 함께 사용할 수 있는 옵션으로 adExecuteNoRecords가 있다. 이 옵션은 명령 또는 저장 프로시저가 반환 값을 가지지 않을 경우에 지정한다.

adExecuteNoRecords 상수는 최소한의 내부 프로세스만을 거치기 때문에 속도는 빠른 반면에 항상 adCmdText 또는 adCmdStoredProc 상수와 함께 사용해야 한다.

[예제]

다음 예제는 CommandType 속성을 adCmdText로 지정해서 Command 개체를 수행하는 예이다.

Private Sub cmdCommandType_Click()    Dim adoCn As New ADODB.Connection    Dim adoCmd As New ADODB.Command    Dim strConn As String

            &nbsp;&nbsp;&nbsp;strConn = "Provider=sqloledb;" &amp; _
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Data Source=(local);Initial 
            Catalog=Pubs;User ID=sa;Password=; "
            
            &nbsp;&nbsp;&nbsp;adoCn.Open strConn
            
            &nbsp;&nbsp;&nbsp;Set adoCmd.ActiveConnection = adoCn
            
            &nbsp;&nbsp;&nbsp;adoCmd.CommandText = "Update Authors Set au_lname 
            = 'Chris' " &amp; _
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" Where 
            au_id = '172-32-1176'"
            
            &nbsp;&nbsp;&nbsp;adoCmd.CommandType = adCmdText
            
            &nbsp;&nbsp;&nbsp;adoCmd.Execute
            
            &nbsp;&nbsp;&nbsp;Set adoCmd = Nothing
            
            &nbsp;&nbsp;&nbsp;adoCn.Close
            &nbsp;&nbsp;&nbsp;Set adoCn = Nothing
            End Sub </P></TD>
      </TR>
    </TBODY>
  </TABLE></td>

CreateParameter 메서드 (ADO)

CreateParameter 메서드 (ADO)

이 메서드는 지정된 속성을 가진 새 Parameter 개체를 작성합니다.

[구문] Set parameter = command.CreateParameter (Name, Type, Direction, Size, Value)

[반환값] Parameter 개체를 반환합니다.

[매개 변수] Name : Parameter 개체의 이름을 나타내는 문자열이며 데이터 형식은 String입니다. Type : Parameter 개체의 데이터 형식을 지정하는 매개 변수이며 데이터 형식은 Long입니다. 유효 설정값에 대한 내용은 Type 속성을 참조하십시오. Direction : Parameter 개체의 형식을 지정하는 매개 변수이며 데이터 형식은 Long 입니다. 유효 설정값에 대한 내용은 Direction 속성을 참조하십시오. Size : 문자 또는 바이트 단위로 매개 변수 값의 최대 길이를 지정하는 매개 변수이며 데이터 형식은 Long입니다. Value :Parameter 개체의 값을 지정하는 매개 변수이며 데이터 형식은 Variant 입니다.

[참고] 지정된 이름, 형식, 방향, 크기 및 개체의 값으로 새 Parameter 개체를 작성하려면 CreateParameter 메서드를 사용합니다. 인수에 전달한 각각의 값은 해당 Parameter 속성에 기록됩니다. 이 메서드는 Command 개체의 Parameters 컬렉션에 Parameter 개체를 자동으로 추가하지 않습니다. 따라서 사용자는 Parameters 컬렉션에 Parameter 개체를 추가할 때 ADO에서 그 값을 검증할 추가 속성을 설정할 수 있습니다. Type 인수에 가변 길이 데이터 형식을 지정하는 경우에는 Parameters 컬렉션에 Parameter 개체를 추가하기 전에 Size 인수를 전달하거나 이 개체의 Size 속성을 설정해야 합니다. 그렇지 않으면 오류가 발생합니다.

Type 속성 (ADO) 이 속성은 Parameter, Field 또는 Property 개체의 작업 형식이나 데이터 형식을 나타냅니다.

설정값과 반환값 이 속성은 아래와 같은 DataTypeEnum 값 중 하나를 설정하거나 반환합니다. 해당 OLE DB 형식 표시기는 아래 표의 설명 열에서 괄호 안에 표시됩니다.

상수 설명 adArray : 다른 형식과 논리적 OR로 연결되어 데이터가 해당 형식의 안전 배열이 될 수 있음을 나타냅니다(DBTYPE_ARRAY). adBigInt : 8바이트의 부호 있는 정수(DBTYPE_I8) adBinary : 이진값(DBTYPE_BYTES) adBoolean : 부울값(DBTYPE_BOOL) adByRef :다른 형식과 논리적 OR로 연결되어 데이터가 다른 형식의 데이터에 대한 포인터임을 나타냅니다(DBTYPE_BYREF). adBSTR : Null 종료 문자열(유니코드)(DBTYPE_BSTR) adChar : String 값(DBTYPE_STR) adCurrency : Currency 값(DBTYPE_CY). Currency는 소수점 이하의 자리수가 4개인 고정 자리수입니다. 이 값은 10,000으로 환산된 8바이트의 부호 있는 정수로 저장됩니다. adDate : Date 값(DBTYPE_DATE). 날짜는 Double로 저장되며 정수 부분은 1899년 12월 30일 이후의 날짜수이며 소수 부분은 하루 중 시간을 나타냅니다.
adDBDate : 날짜 값(yyyymmdd)(DBTYPE_DBDATE) AdDBTime : 시간 값(hhmmss)(DBTYPE_DBTIME) adDBTimeStamp : 날짜-시간 스탬프(yyyymmddhhmmss에 10억분의 1초 단위가 추가된)(DBTYPE_DBTIMESTAMP) adDecimal : 고정 정밀도와 크기로 나타낸 정확한 숫자값(DBTYPE_DECIMAL) adDouble : 배정밀도의 부동 소수점 값(DBTYPE_R8) adEmpty : 지정된 값 없음(DBTYPE_EMPTY) adError : 32비트 오류 코드(DBTYPE_ERROR) adGUID : 전역 고유 식별자(GUID)(DBTYPE_GUID) adIDispatch : OLE 개체에서 IDispatch 인터페이스에 대한 포인터(DBTYPE_IDISPATCH) adInteger : 4바이트의 부호 있는 정수(DBTYPE_I4) adIUnknown : OLE 개체에서 IUnknown 인터페이스에 대한 포인터(DBTYPE_IUNKNOWN) adLongVarBinary : Long 이진 값(Parameter 개체만 해당) adLongVarChar : Long String 값(Parameter 개체만 해당) adLongVarWChar : Long Null 종료 문자열 값(Parameter 개체만 해당) AdNumeric : 고정 정밀도와 크기로 나타낸 정확한 숫자값(DBTYPE_NUMERIC) adSingle : 단정밀도의 부동 소수점 값(DBTYPE_R4) adSmallInt : 2바이트의 부호 있는 정수(DBTYPE_I2) adTinyInt : 1바이트의 부호 있는 정수(DBTYPE_I1) adUnsignedBigInt : 8바이트의 부호 없는 정수(DBTYPE_UI8) adUnsignedInt : 4바이트의 부호 없는 정수(DBTYPE_UI4) adUnsignedSmallInt : 2바이트의 부호 없는 정수(DBTYPE_UI2) adUnsignedTinyInt : 1바이트의 부호 없는 정수(DBTYPE_UI1) adUserDefined : 사용자 정의 변수(DBTYPE_UDT) adVarBinary : 이진값(Parameter 개체만 해당) adVarChar : String 값(Parameter 개체만 해당) adVariant : 자동화 Variant(DBTYPE_VARIANT) adVector : 다른 형식과 논리적 OR로 연결되어 데이터가 OLE DB에서 정의된 것과 같은 DBVECTOR 구조임을 나타냅니다. 이 구조는 요소의 개수와 다른 형식의 데이터에 대한 포인터를 포함합니다(DBTYPE_VECTOR). adVarWChar : Null 종료 유니코드 문자열(Parameter 개체만 해당) adWChar : Null 종료 유니코드 문자열(DBTYPE_WSTR)

[참고]

Parameter 개체의 경우 Type 속성은 읽기/쓰기가 가능합니다. 다른 모든 개체의 경우 Type 속성은 읽기 전용입니다.

Stored Procedure란

Stored Procedure란

저장 프로시저 라고 부르는 Stored Procedure는 우리가 여러 작업을 간편하게 작업하거나 모아서 하고자 할 때 함수를 만들거나 배치파일을 만들어서 해당 함수나 배치파일만 실행시킴으로써 편리하게 사용하게 된다. 이렇듯이 SP(Stored Procedur)는 여러 SQL 작업을 서버 측에 미리 저장해 두고 그 프로시저의 이름만을 호출함으로써 미리 저장되어 있는 모든 작업들을 실행하게 할 수 있다

가령 어떤 결과를 얻기 위해서 실행하고자 하면 10개 이상의 구문을 작성하고자 할 때 매 번 이런 구문들을 작성하여 실행한다는 것은 상당히 귀찮고 비효율적일 수 밖에 없다. 따라서 이러한 구문들을 서버 측에 모조리 미리 저장해 두고 그 프로시저의 이름만을 호출하여 간편하게 사용할 수 있도록 하는 것이다.

System Stored Procedure는 이렇듯이 DB 서버를 사용하면서 중요한 여러 기능들이 있을텐데 이러한 기능들을 편리하게 사용할 수 있도록 미리 정의해 놓은 것이다. 즉, 사용자가 직접 그런 프로시저를 작성하지 않더라도 어떠한 설정값을 변경한다던가 정보를 알아내기 위해서 곧장 사용이 가능해지게 되는 것이다.

Sp_help 등이 여기에 속합니다. 보통 시스템 스토어드 프로시저는 SP_ 로 시작한다.

쿼리 분석기 또는 창에서 SP_HELP를 실행하면 현재 작업 중인 데이터베이스의 정보를 보여준다. 어디에 생성되어 있고 용량은 얼마며 언제 생성되어 있고 테이블은 어떠한 것들이 있다...등등등. SP_Help 테이블명 해주게 되면 해당 테이블의 상세한 정보를 보여준다.

SP_HelpText는 뷰나 프로시저의 생성구문을 볼 수 있도록 해줍니다.

SP_HelpText SP_Help

ADODB.Connection.ConnectionString 사용 방법

ADODB.Connection.ConnectionString 사용 방법

(1) DSN 있는 ODBC 연결 방법 (MS OLE DB for ODBC)

[Provider=MSDASQL;] {DSN=namelFileDSN=filename}; [DATABASE=database;] UID=user; PWD=password


(2) SQL서버 : DSN 없는 ODBC 연결 방법 (MS SQL Server ODBC Driver)

[Provider=MSDASQL;] Driver={SQL Server}; Server=디비서버이름; Database=디비이름; UID=아이디; PWD=비밀번호 ex) Driver={SQL Server}; Server=taeyo; Database=taeyoDB; UID=taeyo; PWD=11


(3) Ms-Access : DSN 없는 ODBC 연결방법 (MS Access ODBC Driver)

ex) Driver={Microsoft Access Driver (*.mdb)}; DBQ=E:\NorthWind.mdb;DefaultDir=E:; DriverId=25; FIL=MSAccess;ImplicitCommitSync=Yes; MaxBufferSize=512;MaxScanRows=8; PageTimeout=5; SafeTransactions=0; Threads=3;UID=admin; PWD=; UserCommitSync=Yes


(4) ORACLE : DSN 없는 ODBC 연결방법 (MS ODBC Driver for ORACLE)

ex) Driver={Microsoft ODBC Driver for Oracle};ConnectString=OracleServer.world; UID=demo; PWD=demo


(5) SQL서버 : OLE DB 직접 접근 방법 (MS OLE DB for SQL Server)

Provider=SQLOLEDB; Data Source=디비서버이름;Initial Catalog=디비이름;User id= 아이디;password= 비밀번호[; Trusted Connection=사용자 인증 모드 (true:NT인증 모드 FALSE:복합모드사용); Current Language=사용언어식별;Network Address=Location 으로 지정한 SQL Server의 네트워크 주소;Network Library=Net-Library(DLL)이름(경로 나 .dll 파일 확장명 불가);Use Procedure for Prepare=저장프로시저사용;Auto Translate=OEM/ANSI문자 변환(TRUE);Packet Size=바이트단위의네트워크패킷크기(512- 32767,기본:4096);Application Name=클라이언트응용프로그램이름;Workstation ID=워크 스테이션식별문자열] ex) Provider= SQLOLEDB;Data Source= taeyo;Initial Catalog=taeyo;User id= taeyo; password= 11


(6) Ms-Access : OLE DB 직접 접근 방법 (MS OLE DB for Access)

Provider=Microsoft.Jet.OLEDB.4.0; Data Source= MDB파일의 물리적인전체경로[; Jet OLEDB:System Database=작업그룹정보파일의경로와파일이름;Jet OLEDB:Registry Path=Jet엔진레지스트리키;Jet OLEDB:Database Password=암호] ex) Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\work\MyDb.mdb


(7) Oracle : OLE DB 직접 접근 방법 (MS OLE DB for ORACLE)

Provider=MSDAORA


(8) MS Index Server (MS OLE DB Provider for Microsoft Index Server)

Provider=MSIDXS


(9) MS Active Directory Service (MS OLE DB Provider for Microsoft Active Directory Service)

Provider=ADSDSOObject; Root=검색 시작할 ADsPath 개체(검색기준);Filter=RFC 960 형식의 검색 필터;Attributes=쉼표로 구분되는 반환될 특성의 목록[; Scope=Base (기준개체(검색기준)만검색)lOneLevel(한수준만검색)lSubtree(모든하위트리검색)]

발췌 : http://www.howtobank.net

서브쿼리의 간단한 예

sqlstr = "select (select pname from wizmall where p.ccode = uid) as pname, b.*, p.ccode from wizbuyer b, wizbuyproduct p "&wherestr&" order by b.uid desc"

가상테이블( View)생성

뷰에 가상테이블을 생성후 가져오는 방법입니다. php의 temp table 과 동일 역활 수행

-------- view 생성 쿼리문------------------- SET QUOTED_IDENTIFIER ON GO SET ANSI_NULLS ON GO

CREATE VIEW dbo.view_news <--- view테이블명은 편하시대로 만드세요. AS SELECT Top 5 subject, regdate, 'wizboard_board01_root' AS tb FROM wizboard_board01_root

UNION SELECT Top 5 subject, regdate, 'wizboard_board02_root' AS tb FROM wizboard_board02_root

UNION SELECT Top 5 subject, regdate, 'wizboard_board03_root' AS tb FROM wizboard_board03_root

GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO

이렇게 쿼리에널라이져에서 생성하시고, 메인에 아래와 같이 불러오셔서 출력하시면 됩니다.

Sql = "Select Top 5 * From view_news order by regdate desc "

'실 응용 ' 특이한 점은 'board01' as bid 처럼 기존에 필드가 없을 경우 필드를 생성하고 특정 변수를 넣어준다

SET QUOTED_IDENTIFIER ON GO SET ANSI_NULLS ON GO

CREATE VIEW dbo.main_view_news AS SELECT Top 10 uid, 'board01' as bid, 'root' as gid, subject, regdate, 'wizboard_board01_root' AS tb FROM wizboard_board01_root

UNION SELECT Top 10 uid, 'board02' as bid, 'root' as gid, subject, regdate, 'wizboard_board02_root' AS tb FROM wizboard_board02_root

UNION SELECT Top 10 uid, 'board03' as bid, 'root' as gid, subject, regdate, 'wizboard_board03_root' AS tb FROM wizboard_board03_root

UNION SELECT Top 10 uid, 'board05' as bid, 'root' as gid, subject, regdate, 'wizboard_board05_root' AS tb FROM wizboard_board05_root

UNION SELECT Top 10 uid, 'board07' as bid, 'root' as gid, subject, regdate, 'wizboard_board07_root' AS tb FROM wizboard_board07_root

UNION SELECT Top 10 uid, 'board08' as bid, 'root' as gid, subject, regdate, 'wizboard_board08_root' AS tb FROM wizboard_board08_root

GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO

Sql = "Select Top 5 * From view_news order by regdate desc "

이미지 사이즈 구하기

<% 'ASP에서 구하기 file_path = server.mappath(".") &"\image\board\1.gif" image_size = Split(ImgGetSize(file_path),"|") Response.Write("넓이 : "& image_size(0)) Response.Write("높이 : "& image_size(1))

Function ImgGetSize(file_path) Dim ImageSize(2) Set ObjImg = LoadPicture(file_path) ImageSize(0) = cint(ObjImg.Width *24 /635) ImageSize(1) = cint(ObjImg.Height *24 /635) file_width = cint(ObjImg.Width *24 /635) file_height = cint(ObjImg.Height *24 /635)

ImgGetSize = file_width & "|" & file_height End Function %>

<% 'UPLOAD Componant에서 구하기 file_width = UPLOAD("attached").ImageWidth file_height = UPLOAD("attached").ImageHeight %>

확장자 구하기

<% str = "test.mpg.avi.mpeg" Response.Write Ucase(mid(str, instrrev(str, ".") + 1)) %>

엑셀파일 db에 넣기

set objxls = Server.CreateObject("ADODB.connection") xlsConnection = "Provider=MSDASQL; Driver={Microsoft Excel Driver (*.xls)}; DBQ=" & fullpath &";" objxls.Open xlsConnection '연결합니다 'Response.End()

set objRs = Server.CreateObject("ADODB.RecordSet") sql = "select c_code,Name,ID,currency,price,picture,dim,spec,drawing,manual,setting,ts,dim_text,spec_text,setting_text,ts_text,content from [sheet1$]"

objRs.Open sql, objxls if Err then %> <% response.end end if

do while not objRs.eof

쿼리 한번으로 여러테이블에서 각각 불러오기

select * from popup where isuse=0 and enddate>='2005-09-15' order by seq asc;select top 4 * from education order by seq desc;select top 4 * from news order by seq desc;select * from main_product; set rs=db.execute(sql)

상기와 같이 구분자 ";"으로 가지고 올 것을 다 사용해 준다.

<% set rs=rs.nextrecordset if rs.eof then %> 자료없슴 <% else i = 0 Do until RS.eof %> 내용출력 <% i = i + 1 RS.movenext loop

Do while i<4 i = i + 1 loop end if

%> 상기처럼 진행시키면 됩니다. 물론 set rs=rs.nextrecordset은 다음 레코드셑이 있을때입니다.

문자처리함수 정리

문자처리관련 함수 <% 'db insert 시 문자 처리 'html 미사용시

Function ConvertChar(InputStr) Dim Str Str = InputStr InputStr = Str InputStr = Replace(InputStr, "&", "&") InputStr = Replace(InputStr, chr(34), """) InputStr = Replace(InputStr, "'", "''") ConvertChar = InputStr End Function

'html 사용시 Function ConvertCharWithHtml(InputStr) Dim Str Str = InputStr InputStr = Str InputStr = Replace(InputStr, "&", "&") InputStr = Replace(InputStr, "<", "<") InputStr = Replace(InputStr, ">", ">") InputStr = Replace(InputStr, chr(34), """) InputStr = Replace(InputStr, "'", "''") ConvertChar2 = InputStr End Function

'db 실렉트시 문자 처리

Function ReConvertChar(InputStr) Dim Str Str = InputStr InputStr = Str InputStr = Replace(InputStr, "\r", "
") InputStr = Replace(InputStr, "\n", " ") InputStr = Replace(InputStr, "&", "&") InputStr = Replace(InputStr, """, chr(34)) InputStr = Replace(InputStr, Chr(13)&Chr(10), "
") ReConvertChar = InputStr End Function

'url자동링크처리

Function LinkURLs(str) Dim reg Set reg = New RegExp

reg.pattern = "(\w+):\/\/([a-z0-9\_\-\./~@?=%&:\-]+)"
reg.Global = True
reg.IgnoreCase = True
reg.multiline=true
str = reg.Replace(str, "<a href='$1://$2' target='_blank'>$1://$2</a>")
reg.pattern = "(\w+)@([\w.\-]+)"
str = reg.Replace(str, "<a href='mailto:$1@$2'>$1@$2</a>")
LinkURLs = str

End Function %>

테이블 생성하기

<% 'Option Explicit

Response.Expires = -1 Response.AddHeader "Pragma", "no-cache" Response.AddHeader "cache-control", "no-store" Const strConnect = "Provider=SQLOLEDB;Data Source=xxx.xxx.xxx.xxx;Initial Catalog=xxxxxx;user ID=xxx;password=xxxxxxxx" %> <OBJECT PROGID=ADODB.Connection ID=dbCon RUNAT=server></OBJECT> <% dbCon.ConnectionString = strConnect %>

<% dbCon.Open sqlstr = "CREATE TABLE [dbo].[tbl_community1] ( " & vbcrlf sqlstr = sqlstr & " [idx_num] [int] IDENTITY (1, 1) NOT NULL , " & vbcrlf sqlstr = sqlstr & " [user_name] [varchar] (30) COLLATE Korean_Wansung_CI_AS NULL , " & vbcrlf sqlstr = sqlstr & " [subject] [varchar] (200) COLLATE Korean_Wansung_CI_AS NULL , " & vbcrlf sqlstr = sqlstr & " [link_url] [varchar] (255) COLLATE Korean_Wansung_CI_AS NULL , " & vbcrlf sqlstr = sqlstr & " [contents] [text] COLLATE Korean_Wansung_CI_AS NULL , " & vbcrlf sqlstr = sqlstr & " [add_file1] [varchar] (80) COLLATE Korean_Wansung_CI_AS NULL , " & vbcrlf sqlstr = sqlstr & " [reg_date] [datetime] NULL , " & vbcrlf sqlstr = sqlstr & " [view_flag] [char] (1) COLLATE Korean_Wansung_CI_AS NULL " & vbcrlf sqlstr = sqlstr & " ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] " & vbcrlf

set list = dbcon.execute(sqlstr)

sqlstr = "ALTER TABLE [dbo].[tbl_community1] WITH NOCHECK ADD " & vbcrlf sqlstr = sqlstr & " CONSTRAINT [PK_tbl_community1] PRIMARY KEY CLUSTERED " & vbcrlf sqlstr = sqlstr & " ( " & vbcrlf sqlstr = sqlstr & " [idx_num] " & vbcrlf sqlstr = sqlstr & " ) ON [PRIMARY] " & vbcrlf

set list = dbcon.execute(sqlstr)

dbCon.Close %>

중국어 사이트 개발시 참고

중국어 사이트 개발시 주의사항이 잘 정리되어 있어 옮겨 놓습니다.

출처 : http://www.devpia.com/Forum/BoardView.aspx?no=96336&page=1&Tpage=3&forumname=www_qa&stype=&ctType=&answer=&KeyR=title&KeyC=


작업환경 :

    OS = 한글windows2000 server 

    DB = MS-SQL2000

    개발에디터 = Ultra Editor, Notepad (노트패드는 소스화일을 저장시 utf-8로 저장하기 위해 필요함)

    mail = sendmail, 기본smtp
  1. 유니코드로 작성한다.

    -소스상단에 넣어야 할 것

     <% session.codepage = 65001 %>
    
     <% Response.CharSet = "utf-8" %>
    

    -html 부분과 중국어폰트적용

     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    

    -화일을 저장시 노트패드 등을 이용하여 utf-8로 저장함

  2. DB 작업

    -중국어가 들어가는 필드(문자열)를 nvarchar로 설정

    -소스 : 유니코드의 값부분에 N을 넣어준다. (insert, select, uodate, delete 동일)

     <%
    
         insert into tblName (title) value (N'&variable&')
    
     %>
    
  3. window2000 설정

    -제어판->국가별옵션에서

     --사용자로케일을 중국어(RPC)로 설정(본토인경우)
    
     --시스템언어설정을 중국(간체)로 설정하고 기본값으로 설정
    
     --시간부분의 오전,오후를 중국어표기로 변경(그래야 now()함수를 사용시 중국시간표기로 나옴 2002-02-12 오전 10:00에서 오전자가 중국어로 나온다는 말)
    
     --시스템언어설정이 중국어로 되더라도 윈도우환경이 메뉴등은 한글로 표기되나... 폴더명, 화일명 등의 한국어는 깨지며 소스화일의 한국어가 ㅁ ? 등으로 표기됨, 중국어는 제대로 보임 즉, 한국어와 중국어가 바뀌는 현상발생함.
    

4.asp페이지와 페이지사이의 quertstring에서 중국어가 안 넘어가는 경우 해결법

-server.urlencode을 이용하여 넘겨주면 해결

-소스예

        <a class='MIME' href="page1.asp?param1=<%=server.urlencode("변수명")%>">클릭하세요</a> 여기서 변수명의 실제값이 중국어이다.

5.asp페이지의 스크립트부분에서 변수에 중국어를 넣을 때 에러나는 경우 해결법

-소스상단에 <% session.codepage = 65001 %> 대신에 <%@ CODEPAGE = 65001 %>을 넣어줌.

6.abcupload, dextupload 등을 이용하여 폼을 넘길 경우 해결법

-소스예

<%

    set UploadForm = server.CreateObject("ABCUpload4.XForm") 'abs일 경우

    'Set uploadForm = Server.CreateObject("DEXT.FileUpload") 'dext일 경우

    UploadForm.CodePage = 65001

 %>

7.이메일발송시 중국어 깨지는 것 해결

-소스예

<%

    objMail.SetLocaleIDs(936) '로케일설정을 936(중국)으로 설정하며

    body =  "<meta http-equiv='Content-Type' content='text/html; charset=gb2312'>" '보내는 바디부분에 삽입

    '이페이지 상단은 session.codepage = 65001 로 타페이지와 같음

%>
  1. now()사용시 오전/오후 한글로 표기되는 경우(한글OS에서 중국으로 셋팅하여 사용하는 경우)

session.LCID=2052

  1. queryString으로 받았는데 중국어가 깨지는 경우가 있으면...

자바로 된 실시간 쪽지에서 유저애플릿으로 쪽지내용을 보내주고 이를 쿼리스트링으로 넘겨서 받는 사람에게 실시간으로 보여줄 때 중국어, 한국어 등등 모두 가능하게 해야 되기에 이런 방법을 써봤습니다.

위의 방법은 제가 중국커뮤니티사이트를 개발하면서 나름대로 터득한 것입니다. 처음엔 정말 난감하구 어렵더군요.

여기 데브피아에서 많은 분들의 도움을 받아서 이번엔 제가 겪었던 입장에 처한 분들에게 조금이나마 도움이 되기를

바라며 이렇게 글을 올려봅니다.

많은 도움되시길 바라며 내용 중에 불필요하거나 잘못된 것이 있을 경우 리플 달아주세요.

오류 : [DBNMPNTW]지정된 SQL Server가 없습니다

우선은 라인상태가 안좋은 경우 그런 문제가 자주 발생 그리고 그런경우 웹서버에서 연결부분에서 Network Library 를 아래와 같이 명시하지 않는경우 문제 발생 <P>Provider=sqloledb;Data Source=211.233.xxx;Initial Catalog=juxxx;Network Library=dbmssocn;User ID=web_xxx;Password=xxx; <P>--> 수정 : 뒷부분에 Network=dbmssocn 추가 Provider=SQLOLEDB.1;Data Source=211.200.22.xxx;Initial catalog=xxxxx;User id=xxxx;Password=xxxxx;Network=dbmssocn;<P> --설명 -- dbnmpntw - Win32 Named Pipes dbmssocn - Win32 Winsock TCP/IP <P>보통
Network Library 부분을 명시하지 않을경우 네임파이프를 통해 연결을 한다고 합니다. Network Library=dbmssocn 이라고 명시하면 네임파이프 말고 TCP/IP 로 잘 연결을 합니다. <P>굳이 Network Library 를 명시하지 않고 네임파이프로 연결하려 하신다면 <P>1.서비스 중 computer browser가 멈추어져 있을경우 잘 되지 않는경우가 있다 2.네트워크식별에서 작업그룹을 잡아줄것 3.인터넷프로토콜(TCP/IP)등록정보에서 고급TCP/IP설정중 WINS탭의 TCP/IP에서 NetBios사용을 선택할것 <P>참조 : http://blog.naver.com/falconer00/80005971853

inner join 문의 실 예

SELECT * FROM concern_tbl INNER JOIN prog_tbl ON prog_tbl.p_idx = concern_tbl.productid Where concern_tbl.userid = 'wangta69'<P> 아래는 실전에 사용된 예제입니다. 하기는 concern_tbl에서 일치하는 id값을 가져와 prog_tbl에서 모든 정보를 가져오는 예입니다. sqlstr = "select top " & pagesize & " * from concern_tbl c inner join prog_tbl p on p.p_idx = c.productid " sqlstr= sqlstr & " where c.uid not in" sqlstr= sqlstr & " (select top " & pagesize*(pageno-1) & " c.uid from concern_tbl c inner join prog_tbl p on p.p_idx = c.productid where c.userid = '" & SESSION("id") & "' order by c.uid desc) " sqlstr= sqlstr & " and c.userid = '" & SESSION("id") & "' order by c.uid desc "

업로드 컴포넌트 사용하기

' ABCUpload4.XForm

SET UPLOAD = Server.CreateObject("ABCUpload4.XForm") UPLOAD.AbsolutePath = True UPLOAD.MaxUploadSize = 524288000 UPLOAD.Overwrite = False

SET fileAttr = UPLOAD("file")(1) IF fileAttr.FileExists THEN upload_filename = fileAttr.SafeFileName fileAttr.Save "pds" & upload_filename END IF

' DEXT.FileUpload SET UPLOAD = Server.CreateObject("DEXT.FileUpload") UPLOAD.DefaultPath = "pds"

SET fileAttr = UPLOAD("file")(1) IF fileAttr.FileExists THEN upload_filename = fileAttr.FileName fileAttr.saveAS "pds" & upload_filename END IF

asp에서 xml 사용하기

일단 링크는 http://www.mskwork.com/korea/msdn/library/etc/issues/2004/odc_XLxmlhowto_/default.aspx

이부분을 요즘 보고 있는데 정리되는 대로 제 개시판에 새로올려 드리겠습니다.

배열에 관한 다양한 응용

주로 사용하는 법 for i = 1 to Request("multiselect").COUNT
response.Write Request("multiselect")(i) next

'다른 예 dim area, areaArr area = Request("area") areaArr = split(area, ",")

for i=0 to ubound(areaArr) j = i+1 next

mssql에서 데이타 뽑아오는 예

일반적으로 sqlstr = "select * from wizmembers" set list = DBCON.Execute(sqlstr)

로서 가져옮니다. 아래는 가져온 데이타를 처리하는 예입니다.


while 문을 사용하여 조건이 참일 경우에 가져오는예

WHILE NOT list.EOF field1 = list("field1") list.MOVENEXT WEND


if를 이용해서 한개의 데이타를 가져올경우

Sql = "Select Top 1 * From tbl_community1 Where view_flag = 'Y' Order By reg_date " Set Rs = dbCon.Execute(Sql) If Rs.Eof Then Else Response.Write("데이타가 없습니다.") end if


DO UNTIL 문 사용하기

Sql0 = "Select Top 5 idx_num, subject, reg_date From tbl_notice Where view_flag='Y' Order By reg_date DESC" Set Rs0 = dbCon.Execute(Sql0) If Rs0.EOF Then Response.Write("데이타가 없습니다.") Else Do Until Rs0.EOF Response.Write("내용 display") Rs0.MoveNext Loop End If

아래도 물론 while not 을 사용하지만 먼저 데이타가 있는지를 책크하는 루틴

if list.eof then Response.Write("가져올 데이타가 없습니다.") else WHILE NOT list.EOF field1 = list("field1") list.MOVENEXT WEND end if

게시판에서 특정 row수만을 가져오는 예

rownum = 10 일반적인예 sqlstr = "select TOP " & rownum & " * from tablename" 페이징이 적용되는예 sqlstr = "select TOP " & rownum & " * from tablename Where idx_num not in (SELECT TOP " & ((page - 1) * rownum) & " idx_num from tablename ORDER BY idx_num desc) ORDER idx_num desc "

파일생성 및 저장하기

Dim MakeFile MakeFile = SERVER.MAPPATH("../../") & "\config\dbconn.asp" SET FSO = SERVER.CREATEOBJECT("Scripting.FileSystemObject")

IF FSO.fileExists(MakeFile) THEN FSO.DeleteFile(MakeFile)

SET FILE = FSO.createTextFile(MakeFile, ForWriting) FILE.WRITELINE("<%") FILE.WRITELINE(" DB_NAME = " & CHR(34) & DB_NAME & CHR(34)) FILE.WRITELINE(" USER_ID = " & CHR(34) & USER_ID & CHR(34)) FILE.WRITELINE(" USER_PASSWD = " & CHR(34) & USER_PASSWD & CHR(34)) FILE.WRITELINE(" HOST_NAME = " & CHR(34) & HOST_NAME & CHR(34)) FILE.WRITELINE(" dbconn = " & CHR(34) & "Provider=SQLOLEDB;Data Source = " & CHR(34) & "&HOST_NAME&" & CHR(34) & ";Initial Catalog=" & CHR(34) & "&DB_NAME&" & CHR(34) & ";User ID=" & CHR(34) & "&USER_ID&" & CHR(34) & ";Password=" & CHR(34) & "&USER_PASSWD&" & CHR(34) & ";" & CHR(34)) FILE.WRITELINE("") FILE.WRITELINE(" SET DbCon = Server.CreateObject(" & CHR(34) & "ADODB.Connection" & CHR(34) & ")") FILE.WRITELINE(" DbCon.Open DbConnect") FILE.WRITELINE(CHR(37 ) & ">") FILE.CLOSE

case

Select Case val Case "case_value1" exp1

Case "case_value2"
	exp2

Case "case_value3"
	exp3

Case "case_value4"
	exp4

Case "case_value5"
	exp5

End Select

Select Case MyVar Case "빨강" document.bgColor = "빨강" Case "녹색" document.bgColor = "녹색" Case "파랑" document.bgColor = "파랑" Case Else MsgBox "다른 색을 고르십시오." End Select

select case sage

 case 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
 response.write "미성년자!! 서비스의 사용을 제한 합니다"
 

 case 19,20,21
 response.write sname & "님은 부분적으로 서비스를 제한 합니다"


 case else
 response.write sname& "님 모든 서비스 사용이 가능합니다"

end select

정의 함수 폼의 간단한 예

일반적인 함수 예

/*** [ 예 1 ] ******************************/ Function function_name (arg)

End Function

/*** [ 예 1 ] ******************************/ sub Page_Load() end sub

call Page_Load()

배열

변수가 진화한 것으로 보면 되고 변수는 그룹으로 다룰 수 없지만 하나 이상의 값을 집합처럼 다루고 싶은 경우앞의 변수의 경우는 개별 변수값을 다룬다면 배열에서는 집합내에서 인덱스번호로 값을 다루는 것이다0부터 시작하는 인덱스번호로 배열요소의 값에 접근할 수 있다* 배열관련용어 : 배열이름,배열크기,배열요소,배열요소개수,인덱스(첨자)배열이름은 값을 가지지 않는 집합의 이름이며 값은 배열요소가 가지면 이미 배운 변수처럼 취급하면 된다배열요소의 인덱스가 숫자이므로 반복문 for~next와 궁합이 잘 맞다선언방법

1. 배열명과 배열크기 동시 선언
Dim Arr(2) Arr(0)=10 Arr(1)=20 Arr(2)=30 Arr은 배열명, 2는 배열크기배열요소 : 값을 가짐

2. 배열을 선언하고 나서 배열크기 선언

Dim ArrRedim Arr(2)Arr(0)=10 Arr(1)=20 Arr(2)=30 Arr은 배열명Redim은 재선언2는 배열크기

3. 배열의 크기를 바꾸고자 할 경우

Dim ArrRedim Arr(2)Arr(0)=10 Arr(1)=20 Arr(2)=30 Redim Preserve Arr(3)Arr(3)=50 Arr은 배열명Redim은 재선언2는 배열크기배열크기 변경-앞의 데이타 그대로 유지Preserve가 없으면 앞의 데이타 잃어버림

4. 배열요소 개수 : 배열크기 + 15. 배열크기 구하는 함수 ;

Ubound(Arr)제일 큰,마지막 첨자 리턴

6. 배열이름은 값을 가질 수 없고 인덱스번호를 가진 배열요소가 값을 가진다 * 배열을 선언하고 값을 할당하고 사용하는 예제 - 배열요소 값으로 그래프를 그려보기

for

  1. For... Next

For 카운터 = 시작값 To 종료값 [Step 증가값]   실행구문   ... Next

  1. For Each... Next

For Each 요소 In 그룹   실행구문   ... Next

"그룹"은 배열이 되고 "요소"는 배열의 값이 된다. php에서의 list($key, $value) = each("배열")과 유사하게 사용된다.

  1. Do... Loop

Do While 조건문   실행구문   ... Loop

if 문

  1. If... Then

If 조건문 Then 실행구문

If 조건문 Then   실행구문 1   실행구문 2 End If

  1. If... Then... Else

If 조건문 1 Then   [실행구문 1] [ElseIf 조건문 2 Then   [실행구문 2]] ... [Else   [실행구문 n]] End If

  1. Select Case

Select Case 조건식   [Case 목록1     [실행구문-1]]   [Case 목록2     [실행구문-2]]

  ...

  [Case Else     [실행구문-n]] End Select

db_connect 하기

strCon="Provider=sqloledb;Data Source=디비주소;Initial Catalog=디비명;User ID=아이디;Password=패스워드;" Set dbcon= Server.CreateObject("ADODB.Connection") dbcon.open strcon sql="update order_list set card_ok = '1' where order_num='"& order_num &"'" DbCon.Execute Sql DbCon.Close<P>--------------------------------------------------------------------- 두번째 방법 <OBJECT RUNAT=server PROGID=ADODB.Connection id=db> </OBJECT><P>db.Open("Driver={SQL SERVER};server=디비주소;database=디비명;uid=아이디;pwd=패스워드;")<P>SQL="SELECT idx, subject from tb_gall where division='"& Request("division") &"'" set rs=Server.CreateObject("ADODB.Recordset") rs.open SQL,db,1

메일보내기

<% dim file,mail_body,fs,objsendmail,objMessage

file = Request.ServerVariables("APPL_PHYSICAL_PATH") &"admin\mailing\mail.asp"



Set fs = Server.CreateObject("Scripting.FileSystemObject")

if not(fs.FileExists(file)) then '파일이 존재하지 않으면
	Set fs=nothing
	mail_body=mail_comments
else

	dim readfs
	Set readfs = fs.OpenTextFile(file,1)

	Do while readfs.AtEndOfStream <> true
		mail_body = mail_body & readfs.readline
	Loop
						
	readfs.close
	Set fs=nothing
					
	mail_body=replace(mail_body, "$message", mail_comments)
end if	
	
	'response.write mail_body
	'response.end
	
	'메일 객체 생성 (CDO로 보낼경우)
	'Set objSendMail = CreateObject("CDONTS.NewMail")
	
	'objSendMail.From = "[email protected]"
	'objSendMail.To = email
	'objSendMail.bcc = "[email protected]"
	'objSendMail.Subject = title
	'objSendMail.BodyFormat=0
	'objSendMail.MailFormat=0
	'objSendMail.Body = mail_body
	'objSendMail.Send 

	'Set objSendMail = Nothing
	
	'서버에 올릴때는 이걸로
	Set objMessage = Server.CreateObject("CDO.Message")
	objMessage.To = email
	objMessage.From = "ISM고객센터<[email protected]>"
	objMessage.Subject = title

	objMessage.HTMLBody = mail_body

	objMessage.Send
	Set  objMessage = Nothing

%>

다국어 페이지를 만들때 글자가 깨지는 경우 혹은 에러발생시

ASP페이지에서 저장 프로시저 전달 구문에

adChar,adVarChar, adLongVarchar 등을 각각 adwChar,adVarwChar, adLongVarWChar 로 변경해 주어야 한다.

예) paramInfo(11) = db.MakeParam("@sub_subject1", adVarwChar, adParamInput,200, sub_subject1) paramInfo(13) = db.MakeParam("@content", adLongVarWChar, adParamInput,LenB(content), content)

물론 저장 프로시저에서는 INSERT INTO A VALUES (N'' + @전달값 + '') 처럼 N을 붙혀주어야한다. 이곳에서도 변수 설정시 nvarchar로 설정하는 것을 잊어서는 안된다.(각 table도 마찬가지임)

Table of contents 목차

평점을 남겨주세요
평점 : 2.5
총 투표수 : 1
Copyright © 온스토리