'Lotus Notes'에 해당되는 글 14건
- 2007/05/25 Notes Data To Excel I
- 2007/05/25 SameTime 설치시 JavaUserClasses 갱신 오류발생 문재 해결
- 2007/05/25 ODBC를 이용한 Select 쿼리 에이전트 원형 III
- 2007/05/25 ODBC를 이용한 Select 쿼리 에이전트 원형 II (1)
- 2007/05/25 ODBC를 이용한 Select 쿼리 에이전트 원형 I (4)
- 2007/05/25 다중 웹서버 구성시 리프레쉬 문제
- 2007/05/25 선택목록 필드를 읽기모드에서 깔끔하게 보이도록 하는 코드
- 2007/05/25 에이전트 개발 표준
- 2007/05/25 LotusScript의 Trim을 흉내낸 JavaScript 코드
- 2007/05/25 Back-End로 문서 삭제를...
#1. notes.ini에 등록된 아래의 파라메터를 삭제처리.
SametimeServerConfig=OnDomino
CleanupScriptPath=\Trace\stdiagzip.bat
#2. notes.ini에 아래의 파라메터 추가처리.
DominoBypassFlag=-vnver6
--> STsetup.exe 실행 (반드시 Domino 서버를 내리고 처리해야함)
댓글을 달아 주세요
이번에는 업데이트 코드가 추가가 되었습니다.
Update 쿼리를 호출할 수 있도록 기능이 추가되었습니다.
-> 다음과 같이 URL을 구성하면...
http://server_url/db.nsf/agent?openagent&order=update&set-i=2&setn-1=aaa&set-1=1111&setn-2=bbb&set-2=2222&where-i=2&wheren-1=ccc&where-1=123&wheren-2=ddd&where-2=456
결과는 update SQL_TABLE(Declarations의 설정값) set aaa = '1111', bbb = '2222' where ccc = '123' and ddd = '456' 이렇게 RDB 서버로 Query를 전송합니다.
파라메터가 추가가 된것인데요~
set-i : 설정컬럼 수
setn-1 ~ n : 설정컬럼명( set-i로 지정한 값 만큼 설정해야 합니다.(클케하지 않으면 어떤 오류가 뜰지 모릅니다... ㅡ_ㅡ;; )
set-1 ~ n : 설정컬럼값 ( set-i로 지정한 값 만큼 설정해야 합니다.(클케하지 않으면 어떤 오류가 뜰지 모릅니다... ㅡ_ㅡ;; )
where-i : 조건컬럼 수
wheren-1 ~ n : 조건컬럼명 ( where-i로 지정한 값 만큼 설정해야 합니다.(클케하지 않으면 어떤 오류가 뜰지 모릅니다... ㅡ_ㅡ;; )
where-1 ~ n : 조건컬럼 값 ( where-i로 지정한 값 만큼 설정해야 합니다.(클케하지 않으면 어떤 오류가 뜰지 모릅니다... ㅡ_ㅡ;; )
자 아래부터는 Full 코드입니다.
이전 버전에서 변경된 부분은 파란색으로 표현하겠습니다.
----------------------------------------------------------------------------------------
****************************
(Options)
****************************
Option Public
Uselsx "*LSXODBC"
****************************
(Declarations)
****************************
Dim ss As NotesSession
Dim curDb As NotesDatabase
Dim curDoc As NotesDocument
Dim curAgent As NotesAgent '// 현재 Agent
Dim con As ODBCConnection
Dim query As ODBCQuery
Dim result As ODBCResultSet
Dim order As String
Const SQL_DNS = "ODBC DNS"
Const SQL_ID = "USER ID"
Const SQL_PASSWORD = "USER PASSWORD"
Const SQL_TABLE_SCHEMA = "dbo"
Const SQL_TABLE = "TABLE NAME or PROCEDURE NAME"
'//★ 아래의 코드는 RDB Table과 같은 형식이어야 함. ( 코드마다 틀리게 구성해야 함. )
Const SQL_TABLE_FIELD = |a,b,c,d,e,f| '// 결과 필드 목록
Const SQL_TABLE_FIELDTYPE = |STRING,STRING,STRING,INTEGER,INTEGER,STRING| '// 결과 필드 목록 타입
Const SQL_TABLE_FIELD_AROUND = |^,^,^,^,^,| '// 결과 필드 둘러싸기 옵션
Dim TableDoc As NotesDocument
Dim fieldAround As Variant
****************************
Initialize
****************************
Sub Initialize
On Error Goto ErrorHandle
Dim qs As String
Dim resultField As String '// 결과
Set ss = New NotesSession
Set curDb = ss.CurrentDatabase
Set curAgent = ss.CurrentAgent
Set curDoc = ss.DocumentContext
qs = curDoc.Query_String_Decoded(0)
Print |Content-type: text/xml|
Print ||
Call SetTableDoc( qs )
'// SYBASE Server 연결
If( SQLConnection( SQL_DNS ) = False ) Then Exit Sub
If( GetTableInfo(TableDoc.result(0)) = False ) Then Goto ProcessEnd
ProcessEnd:
con.Disconnect
Exit Sub
ErrorHandle:
Print |
Msgbox curDb.Filepath + "/" + curAgent.Name + "::initialize ERROR[" + Cstr( Erl() ) + "] : " + Error()
Print "
Print curDb.Filepath + "/" + curAgent.Name + "::initialize ERROR[" + Cstr( Erl() ) + "] : " + Error()
Print "
If( con.IsConnected ) Then
con.Disconnect
End If
Exit Sub
End Sub
****************************
GetQueryType
****************************
Function GetQueryType( source As String ) As String
%REM
함수명 : GetQueryType
인자 : source - Query에 포함되는 필드명
반환 : String - STRING, INTEGER
목적 : Query를 구성할때 작은따옴표(')를 추가하여 Query를 구성할지에 대한 여부 체크를 위하여
작성정보 : v1.0 / 이동완 / 2006-06-07
%END REM
On Error Goto ErrorHandle
GetQueryType = ""
Dim FieldList As Variant
Dim FieldType As Variant
Dim index As Integer
FieldList = Evaluate(|@Trim( @Explode("| & SQL_TABLE_FIELD & |";",") )|)
FieldType = Evaluate(|@Trim( @Explode("| & SQL_TABLE_FIELDTYPE & |";",") )|)
index = 0
Forall ufl In FieldList
If( source = Cstr( ufl ) ) Then
If( Ubound( FieldType ) >= index ) Then
GetQueryType = Cstr( FieldType(index) )
Else
GetQueryType = ""
End If
End If
index = index + 1
End Forall
Exit Function
ErrorHandle:
Call WriteLog( Err(), curDb.Filepath + "/" + curAgent.Name + "::GetQueryType ERROR[" + Cstr( Erl() ) + "] : " + Error() )
GetQueryType = ""
Exit Function
End Function
****************************
GetTableInfo
****************************
Function GetTableInfo( res As String ) As Integer
%REM
함수명 : GetTableInfo
인자 : res - Query 결과
반환 : Boolean - Query 처리 결과
- True : 정상처리
- False : 비정상 종료
목적 : 테이블의 정보를 가져오기 위함
작성정보 : v1.0 / 이동완 / 2006-05-25/2006-05-26
%END REM
On Error Goto ErrorHandle
Dim index As Integer
Dim rowIndex As Integer
Dim whereFlag As Boolean
Dim writeData As String
whereFlag = False
query.SQL = MakeQuery( res )
' Print |
' Exit Function
If( query.SQL = "" ) Then
Msgbox "Query를 조합하지 못하였습니다."
GetTableInfo = False
Exit Function
End If
If Not result.Execute Then
If( order = "update" ) Then
Print |
Exit Function
Else
Messagebox result.GetExtendedErrorMessage + "/" + result.GetErrorMessage
End If
GetTableInfo = False
Exit Function
End If
'// 갱신 코드 처리완료
If( order = "update" ) Then
Print |
GetTableInfo = True
Exit Function
End If
result.MaxRows = 14000
If( result.NumRows = 0 ) Then
Print "
GetTableInfo = False
Exit Function
End If
Print |
index = 0
Do
result.NextRow
Print ""
If( result.CurrentRow <> 0 ) Then
If( res = "" Or Lcase( res ) = "all" ) Then
rowIndex = 1
Forall utdi In TableDoc.GetItemValue( "FieldList" )
If( Trim( result.GetValue( rowIndex ) ) >< "" ) Then
writeData = result.GetValue( rowIndex )
While( Asc( Right( writeData, 1 ) ) = 0 Or ( Asc( Right( writeData, 1 ) ) > 126 And Asc( Right( writeData, 1 ) ) < 256 ))
writeData = Left( writeData, Len( writeData )-1 )
Wend
Print |<| & Cstr( utdi ) & |>|
Print Strleft( fieldAround(rowIndex-1), "^" )
Print Trim( writeData )
Print Strright( fieldAround(rowIndex-1), "^" )
Print || Cstr( utdi ) & |>|
Else
Print "<" & Cstr( utdi ) & "/>"
End If
rowIndex = rowIndex + 1
End Forall
Else
If( Trim( Strrightback( res, " " ) ) <> "" ) Then
Print "<" + Strrightback( res, " " ) + ">" + result.GetValue(1) + "" ) Strrightback( res, + ?> Elseif( Strleft( res, "(" ) <> "" ) Then
Print "<" + Strleft( res, "(" ) + ">" + result.GetValue(1) + "" ) res, + ? Strleft( ?(?> Else
Print "<" + res + ">" + result.GetValue(1) + "" + ? res> End If
End If
Else
Print "
End If
Print ""
index = index + 1
Loop Until result.IsEndOfData
Print |
GetTableInfo = True
Exit Function
ErrorHandle:
Call WriteLog( Err(), curDb.Filepath + "/" + curAgent.Name + "::GetTableInfo ERROR[" + Cstr( Erl() ) + "] : " + Error() )
GetTableInfo = False
Exit Function
End Function
****************************
MakeQuery
****************************
Function MakeQuery( res As String )As String
%REM
함수명 : MakeQuery
인자 : res - Query 결과
반환 : String - Query 조합 결과
목적 : 테이블의 데이터를 가져오기위한 Query 조합
작성정보 : v1.0 / 이동완 / 2006-05-24 / 2006-05-26
%END REM
On Error Goto ErrorHandle
Dim returnQuery As String '// Query
Dim whereFlag As Boolean '// where절 추가상태 여부
Dim curItemName As String '// Query 구성 Item명
Dim separator As String '// 파라메터간 구분자
If( Lcase( TableDoc.Order(0) ) = "select" Or Lcase( TableDoc.Order(0) ) = "" ) Then
'// Select 구문인 경우
If( res = "" Or Lcase( res ) = "all" ) Then
returnQuery = "Select * from " + SQL_TABLE
Else
returnQuery = "Select " + res + " from " + SQL_TABLE
End If
Forall utdi In TableDoc.Items
curItemName = Lcase( utdi.Name )
'// result, fieldlist, order 필드는 Query에 포함되지 않음.
If( curItemName <> "result" And curItemName <> "fieldlist" And curItemName <> "fieldtype" And curItemName <> "order" And Left( curItemName, 6 ) <> "param-" ) Then
'// n_로 시작하는 필드는 n_ 다음 String으로 쿼리를 구성함.
If( Left( utdi.Name, 2 ) = "n_" ) Then
returnQuery = returnQuery + MakeQueryElement( Rightbp( utdi.Name, Len(utdi.Name)-2 ), utdi.Values(0), False, whereFlag )
Else
returnQuery = returnQuery + MakeQueryElement( utdi.Name, utdi.Values(0), True, whereFlag )
End If
End If
End Forall
Elseif( Lcase( TableDoc.Order(0) ) = "update" ) Then
'// Update 구문인 경우
returnQuery = TableDoc.Order(0)+ " " + SQL_TABLE
For i% = 1 To Cint( TableDoc.GetItemValue( "setItem-i" )(0) )
If( i% > 1 ) Then
separator = |, |
Else
separator = | set |
End If
returnQuery = returnQuery + separator + TableDoc.GetItemValue( "setItemName-" & Cstr(i%) )(0) + |='|
returnQuery = returnQuery + TableDoc.GetItemValue( "setitem-" & Cstr(i%) )(0) + |'|
Next
For i% = 1 To Cint( TableDoc.GetItemValue( "whereItem-i" )(0) )
If( i% > 1 ) Then
separator = | and |
Else
separator = | where |
End If
returnQuery = returnQuery + separator + TableDoc.GetItemValue( "whereItemName-" & Cstr(i%) )(0) + | = '|
returnQuery = returnQuery + TableDoc.GetItemValue( "whereItem-" & Cstr(i%) )(0) + |'|
Next
Else
'// 프로시저 호출일 경우
returnQuery = TableDoc.Order(0) + " " + SQL_TABLE
For i%=1 To Cint( TableDoc.GetItemValue( "param-i" )(0) )
If( i% > 1 ) Then
separator = |,'|
Else
separator = | '|
End If
returnQuery = returnQuery + separator + TableDoc.GetItemValue( "param-" & Cstr(i%) )(0) + |'|
Next
End If
MakeQuery = returnQuery
Exit Function
ErrorHandle:
Call WriteLog( Err(), curDb.Filepath + "/" + curAgent.Name + "::MakeQuery ERROR[" + Cstr( Erl() ) + "] : " + Error() )
MakeQuery = ""
Exit Function
End Function
****************************
MakeQueryElement
****************************
Function MakeQueryElement( itemName As String, source As String, equalOption As Boolean, whereFlag As Boolean )As String
%REM
함수명 : MakeQueryElement
인자 : itemName - Query 필드
source - Query 필드 값
equalOption - 포함되는 값을 찾으려면 True, 포함되지 않는 값을 찾으려면 False
whereFlag - where 구문 삽입 유무
반환 : String - Query 조합 결과
목적 : Query 부분 조합
- 2006-06-07 : Integer를 Query에 포함시키기 위하여 기능 추가
작성정보 : v1.0 / 이동완 / 2006-05-24 / 2006-06-07
%END REM
On Error Goto ErrorHandle
Dim pluralValue As Variant '// source 값 복수시 Explode
Dim returnQuery As String '// 결과 반환값
Const REF_CALCULATE_BLOCK = " AND " '//조건 블럭간 조건
Dim valueCompare As String '// 등호, 같음 또는 같지 않음 체크
Dim bitCalculator As String '// 같음 일때는 OR, 다름 일때는 AND 여야 함.
Dim itemType As String '// Query에 포함될 Item의 속성(STRING, INTEGER ... )
Dim quotationValue As String '// Query에 포함될 Item의 속성에 따른 인용부호
If( equalOption ) Then
valueCompare = " = "
bitCalculator = " OR "
Else
valueCompare = " <> "
bitCalculator = " AND "
End If
itemType = GetQueryType( itemName )
If( Ucase( itemType ) = "STRING" Or Ucase( itemType ) = "" ) Then
quotationValue = "'"
Else
quotationValue = ""
End If
If( Trim( source ) <> "" ) Then
If( Strleft( source, "," ) <> "" ) Then
'// 복수
If( whereFlag ) Then
returnQuery = returnQuery + REF_CALCULATE_BLOCK
End If
pluralValue = Evaluate(|@Unique( @Trim( @Explode("| & source & |";",") ) )|)
Forall upv In pluralValue
If( whereFlag ) Then
If( Cstr( upv ) = Cstr( pluralValue(0) ) ) Then
'// 첫번째 조건값
If( Left( Cstr( upv ), 1 ) = "[" And Strleft( Cstr( upv ), "]" ) <> "" ) Then
'// LIKE와 같은 구문이 있는 경우 (ex: [LIKE]AA%)
returnQuery = returnQuery + " ( " + itemName + " " + Strleft( Strright( Cstr( upv ) , "[" ), "]" ) + " " + quotationValue + Strright( Cstr( upv ), "]" ) + quotationValue
Else
returnQuery = returnQuery + " ( " + itemName + valueCompare + quotationValue + Cstr( upv ) + quotationValue
End If
Else
'// 두번째 이후 조건값
If( Left( Cstr( upv ), 1 ) = "[" And Strleft( Cstr( upv ), "]" ) <> "" ) Then
'// LIKE와 같은 구문이 있는 경우 (ex: [LIKE]AA%)
returnQuery = returnQuery + bitCalculator + itemName + " " + Strleft( Strright( Cstr( upv ) , "[" ), "]" ) + " " + quotationValue + Strright( Cstr( upv ), "]" ) + quotationValue
Else
returnQuery = returnQuery + bitCalculator + itemName + valueCompare + quotationValue + Cstr( upv ) + quotationValue
End If
End If
Else
'// where절이 없는 경우 추가
If( Left( Cstr( upv ), 1 ) = "[" And Strleft( Cstr( upv ), "]" ) <> "" ) Then
'// LIKE와 같은 구문이 있는 경우 (ex: [LIKE]AA%)
returnQuery = returnQuery + " where ( " + itemName + " " + Strleft( Strright( Cstr( upv ) , "[" ), "]" ) + " " + quotationValue + Strright( Cstr( upv ), "]" ) + quotationValue
Else
returnQuery = returnQuery + " where ( " + itemName + valueCompare + quotationValue + Cstr( upv ) + quotationValue
End If
whereFlag = True
End If
End Forall
returnQuery = returnQuery + ")"
Else
'// 단수
If( whereFlag ) Then
'// where 절을 이미 삽입한 경우
If( Left( source, 1 ) = "[" And Strleft( source, "]" ) <> "") Then
'// LIKE와 같은 구문이 있는 경우 (ex: [LIKE]AA%)
returnQuery = returnQuery + REF_CALCULATE_BLOCK + itemName + " " + Strleft( Strright( source , "[" ), "]" ) + " " + quotationValue + Strright( source, "]" ) + quotationValue
Else
returnQuery = returnQuery + REF_CALCULATE_BLOCK + itemName + valueCompare + quotationValue + source + quotationValue
End If
Else
'// where 절이 없는 경우 추가
If( Left( source, 1 ) = "[" And Strleft( source, "]" ) <> "" ) Then
'// LIKE와 같은 구문이 있는 경우 (ex: [LIKE]AA%)
returnQuery = returnQuery + " where " + itemName + " " + Strleft( Strright( source , "[" ), "]" ) + " " + quotationValue + Strright( source, "]" ) + quotationValue
Else
returnQuery = returnQuery + " where " + itemName + valueCompare + quotationValue + source + quotationValue
End If
End If
End If
whereFlag = True
End If
MakeQueryElement = returnQuery
Exit Function
ErrorHandle:
Call WriteLog( Err(), curDb.Filepath + "/" + curAgent.Name + "::MakeQueryElement ERROR[" + Cstr( Erl() ) + "] : " + Error() )
Print source
MakeQueryElement = ""
Exit Function
End Function
****************************
SetTableDoc
****************************
Sub SetTableDoc( source As String )
%REM
함수명 : SetTableDoc
인자 : source - Query_String_Decoded
반환 : -
목적 : Query_String_Decoded로 넘어온 값 중에서 원하는 Query를 잘라내어 TableDoc의 Item으로 생성함.
이를 MakeQuery, GetTableInfo 함수에서 사용함으로 각 코드에 Table 형식에 맞게끔 코딩하는 것을 방지할 수 있음.
작성정보 : v1.0 / 이동완 / 2006-05-26
%END REM
On Error Goto ErrorHandle
Dim FieldList As Variant
Dim FieldType As Variant
Set TableDoc = New NotesDocument( curDb )
FieldList = Evaluate(|@Trim( @Explode("| & SQL_TABLE_FIELD & |";",") )|)
FieldType = Evaluate(|@Trim( @Explode("| & SQL_TABLE_FIELDTYPE & |";",") )|)
fieldAround = Evaluate(|@Explode("| & SQL_TABLE_FIELD_AROUND & |";",")|)
Forall ufl In FieldList
Call TableDoc.ReplaceItemValue( Cstr( ufl ), GetArgumentValue( Cstr( ufl ) & "=", source ) )
Call TableDoc.ReplaceItemValue( "n_" & Cstr( ufl ), GetArgumentValue( Cstr( ufl ) & "!=", source ) )
End Forall
Call TableDoc.ReplaceItemValue( "FieldList", FieldList ) '// 결과 Field 목록
Call TableDoc.ReplaceItemValue( "FieldType", FieldType ) '// 결과 Field 종류
Call TableDoc.ReplaceItemValue( "result", GetArgumentValue( "result=", source ) ) '// 결과
Call TableDoc.ReplaceItemValue( "order", GetArgumentValue( "order=", source ) ) '// 명령( select, exec ...
댓글을 달아 주세요
몇일만에 바로 업글이 되었네요~ 그만큼 초기 버전이 제약사항 및 오류가 있었다는 얘기겠죠~
기존껀 오로지 SELECT, LIKE 조건 등을 날리지 못했으며,
각 RDB Table에 맞춰주려면 여러 함수들을 돌아다니면서 수정해줘야하는 번거로움이 있었습니다.
이제 달라졌습니다~
1. Table의 형식이 달라져도 (Declarations)의 ODBC Connection 설정 사항과 2줄의 코드만 수정해주면 다른곳은 수정할 필요가 없습니다.
-> SQL_TABLE_FIELD, SQL_TABLE_AROUND 상수가 추가가 되었습니다.
* SQL_TABLE_FIELD 상수에는 받고자하는 필드를 순서대로 컴머(,)로 분류하여 입력하시면 됩니다. ( 공백은 날려버리니 상관 없구요...)
* SQL_TABLE_FIELD_AROUND 상수는 SQL_TABLE_FIELD상수와 같은 수만큼 컴머로 분리하서 꺽쇠(^)를 넣어주시면 됩니다. 이것을 넣은 이유는 XML을 반환시 특수문자 또는 공백이 들어가면 오류가 발생되므로 공백이 포함된 필드값을 받고자하는 경우엔 <![CDATA[~~~~~]]>로 감싸줘야 하기때문에 상수가 추가가 되었습니다.
2. SELECT 쿼리와 프로시져를 호출할 수 있도록 기능이 추가되었습니다.
-> 다음과 같이 URL을 구성하면...
http://server_url/db.nsf/agent?openagent&order=exec¶m-i=2¶m-1=1111¶m-2=2222
결과는 exec SQL_TABLE(Declarations의 설정값) '1111','2222' 이렇게 RDB 서버로 Query를 전송합니다.
파라메터가 추가가 된것인데요~
order : 명령줄( select 생략가능 / 없으면 select로 인식 )
param-i : order를 exec와 같이 프로시저를 호출할 경우 파라메터를 넘겨주는데~ 그 파라메터의 수를 미리 지정해주는 옵션입니다.
param-1 ~ n : param-i로 지정한 값 만큼 설정해야 합니다. (글케하지 않으면 어떤 오류가 뜰지 모릅니다... ㅡ_ㅡ;; )
3. 오로지 A='b' 또는 A<>'b' 조건문 밖에 안되던것이... LIKE문을 넣을 수 있도록 추가가 되었습니다.
SQL을 마니 알지는 못하지만... LIKE문을 포함하여 쿼리를 구성할 수 있도록 수정하였습니다.
-> 기존엔 http://server_url/db.nsf/agent?openagent&aa=1111,2222&bb!=3333,4444 와 같이 호출하면...
SELECT * from table where ( aa = '1111' or aa = '2222' ) and ( bb <> '3333' and bb <> '4444' )라는 Query가 RDB 서버로 전송이됩니다. 이에 불만이 한가지 있었습니다.... LIKE 문이죠...
자 그럼~
http://server_url/db.nsf/agent?openagent&aaa=[LIKE]111%,[LIKE]222%&bb!=3333,4444 와 같이 호출하면~
SELECT * from table where ( aa LIKE '111%' or aa LIKE '222%' ) and ( bb <> '3333' and bb <> '4444' )라는 Query를 RDB 서버로 전송합니다.
조금더 확장된 기능을 제공한다라고 감히 말할수 있겠죠(?)
자 아래부터는 Full 코드입니다.
---------------------------------------------------------------------------------------------------
****************************
(Options)
****************************
Option Public
Uselsx "*LSXODBC"
****************************
(Declarations)
****************************
Dim ss As NotesSession
Dim curDb As NotesDatabase
Dim curDoc As NotesDocument
Dim curAgent As NotesAgent '// 현재 Agent
Dim con As ODBCConnection
Dim query As ODBCQuery
Dim result As ODBCResultSet
Const SQL_DNS = "ODBC_DNS"
Const SQL_ID = "UserID"
Const SQL_PASSWORD = "UserPassword"
Const SQL_TABLE_SCHEMA = "dbo"
Const SQL_TABLE = "table"
'//★ 아래의 코드는 RDB Table과 같은 형식이어야 함. ( 코드마다 틀리게 구성해야 함. )
Const SQL_TABLE_FIELD = |a,b,c,d,e| '// 결과 필드 목록
Const SQL_TABLE_FIELD_AROUND = |^,^,^,^,<![CDATA[^]]>| '// 결과 필드 둘러싸기 옵션
Dim TableDoc As NotesDocument
Dim fieldAround As Variant
****************************
Initialize
****************************
Sub Initialize
On Error Goto ErrorHandle
Dim qs As String
Dim resultField As String '// 결과
Set ss = New NotesSession
Set curDb = ss.CurrentDatabase
Set curAgent = ss.CurrentAgent
Set curDoc = ss.DocumentContext
qs = curDoc.Query_String_Decoded(0)
Print |Content-type: text/xml|
Print |<?xml version='1.0' encoding='KSC5601'?>|
Call SetTableDoc( qs )
'// SYBASE Server 연결
If( SQLConnection( SQL_DNS ) = False ) Then Exit Sub
If( GetTableInfo(TableDoc.result(0)) = False ) Then Goto ProcessEnd
ProcessEnd:
con.Disconnect
Exit Sub
ErrorHandle:
Print |<Result>
<msg>error</msg>
<ermsg>| + Error() + |</ermsg>
<erl>| + Cstr( Erl() ) + |</erl>
</Result>|
Msgbox curDb.Filepath + "/" + curAgent.Name + "::initialize ERROR[" + Cstr( Erl() ) + "] : " + Error()
Print "<error>"
Print curDb.Filepath + "/" + curAgent.Name + "::initialize ERROR[" + Cstr( Erl() ) + "] : " + Error()
Print "</error>"
If( con.IsConnected ) Then
con.Disconnect
End If
Exit Sub
End Sub
****************************
GetTableInfo
****************************
Function GetTableInfo( res As String ) As Integer
%REM
함수명 : GetTableInfo
인자 : res - Query 결과
반환 : Boolean - Query 처리 결과
- True : 정상처리
- False : 비정상 종료
목적 : 테이블의 정보를 가져오기 위함
작성정보 : v1.0 / 이동완 / 2006-05-25/2006-05-26
%END REM
On Error Goto ErrorHandle
Dim index As Integer
Dim rowIndex As Integer
Dim whereFlag As Boolean
whereFlag = False
query.SQL = MakeQuery( res )
If( query.SQL = "" ) Then
Msgbox "Query를 조합하지 못하였습니다."
GetTableInfo = False
Exit Function
End If
If Not result.Execute Then
Messagebox result.GetExtendedErrorMessage + "/" + result.GetErrorMessage
GetTableInfo = False
Exit Function
End If
result.MaxRows = 14000
If( result.NumRows = 0 ) Then
Print "<Result>검색한 결과가 없습니다.</Result>"
GetTableInfo = False
Exit Function
End If
Print |<Result>|
index = 0
Do
result.NextRow
Print "<data index='" & index & "'>"
If( res = "" Or Lcase( res ) = "all" ) Then
rowIndex = 1
Forall utdi In TableDoc.GetItemValue( "FieldList" )
Print "<" & Cstr( utdi ) & ">" & Strleft( fieldAround(rowIndex-1), "^" ) & result.GetValue( rowIndex ) & Strright( fieldAround(rowIndex-1), "^" ) & "</" & Cstr( utdi ) & ">"
rowIndex = rowIndex + 1
End Forall
Else
Print "<" + Strrightback( res, " " ) + ">" + result.GetValue(1) + "</" + Strrightback( res, " " ) + ">"
End If
Print "</data>"
index = index + 1
Loop Until result.IsEndOfData
Print |</Result>|
GetTableInfo = True
Exit Function
ErrorHandle:
Call WriteLog( Err(), curDb.Filepath + "/" + curAgent.Name + "::GetTableInfo ERROR[" + Cstr( Erl() ) + "] : " + Error() )
GetTableInfo = False
Exit Function
End Function
****************************
MakeQuery
****************************
Function MakeQuery( res As String )As String
%REM
함수명 : MakeQuery
인자 : res - Query 결과
반환 : String - Query 조합 결과
목적 : 테이블의 데이터를 가져오기위한 Query 조합
작성정보 : v1.0 / 이동완 / 2006-05-24 / 2006-05-26
%END REM
On Error Goto ErrorHandle
Dim returnQuery As String '// Query
Dim whereFlag As Boolean '// where절 추가상태 여부
Dim curItemName As String '// Query 구성 Item명
Dim separator As String '// 파라메터간 구분자
If( Lcase( TableDoc.Order(0) ) = "select" Or Lcase( TableDoc.Order(0) ) = "" ) Then
'// Select 구문인 경우
If( res = "" Or Lcase( res ) = "all" ) Then
returnQuery = "Select * from " + SQL_TABLE
Else
returnQuery = "Select " + res + " from " + SQL_TABLE
End If
Forall utdi In TableDoc.Items
curItemName = Lcase( utdi.Name )
'// result, fieldlist, order 필드는 Query에 포함되지 않음.
If( curItemName <> "result" And curItemName <> "fieldlist" And curItemName <> "order" And Left( curItemName, 6 ) <> "param-" ) Then
'// n_로 시작하는 필드는 n_ 다음 String으로 쿼리를 구성함.
If( Left( utdi.Name, 2 ) = "n_" ) Then
returnQuery = returnQuery + MakeQueryElement( Rightbp( utdi.Name, Len(utdi.Name)-2 ), utdi.Values(0), False, whereFlag )
Else
returnQuery = returnQuery + MakeQueryElement( utdi.Name, utdi.Values(0), True, whereFlag )
End If
End If
End Forall
Else
'// 프로시저 호출일 경우
returnQuery = TableDoc.Order(0) + " " + SQL_TABLE
For i%=1 To Cint( TableDoc.GetItemValue( "param-i" )(0) )
If( i% > 1 ) Then
separator = |,'|
Else
separator = | '|
End If
returnQuery = returnQuery + separator + TableDoc.GetItemValue( "param-" & Cstr(i%) )(0) + |'|
Next
End If
MakeQuery = returnQuery
Exit Function
ErrorHandle:
Call WriteLog( Err(), curDb.Filepath + "/" + curAgent.Name + "::MakeQuery ERROR[" + Cstr( Erl() ) + "] : " + Error() )
MakeQuery = ""
Exit Function
End Function
****************************
MakeQueryElement
****************************
Function MakeQueryElement( itemName As String, source As String, equalOption As Boolean, whereFlag As Boolean )As String
%REM
함수명 : MakeQueryElement
인자 : itemName - Query 필드
source - Query 필드 값
equalOption - 포함되는 값을 찾으려면 True, 포함되지 않는 값을 찾으려면 False
whereFlag - where 구문 삽입 유무
반환 : String - Query 조합 결과
목적 : Query 부분 조합
작성정보 : v1.1 / 이동완 / 2006-05-24
%END REM
On Error Goto ErrorHandle
Dim pluralValue As Variant '// source 값 복수시 Explode
Dim returnQuery As String '// 결과 반환값
Const REF_CALCULATE_BLOCK = " AND " '//조건 블럭간 조건
Dim valueCompare As String '// 등호, 같음 또는 같지 않음 체크
Dim bitCalculator As String '// 같음 일때는 OR, 다름 일때는 AND 여야 함.
If( equalOption ) Then
valueCompare = " = "
bitCalculator = " OR "
Else
valueCompare = " <> "
bitCalculator = " AND "
End If
If( Trim( source ) <> "" ) Then
If( Strleft( source, "," ) <> "" ) Then
'// 복수
If( whereFlag ) Then
returnQuery = returnQuery + REF_CALCULATE_BLOCK
End If
pluralValue = Evaluate(|@Unique( @Trim( @Explode("| & source & |";",") ) )|)
Forall upv In pluralValue
If( whereFlag ) Then
If( Cstr( upv ) = Cstr( pluralValue(0) ) ) Then
'// 첫번째 조건값
If( Left( Cstr( upv ), 1 ) = "[" And Strleft( Cstr( upv ), "]" ) <> "" ) Then
'// LIKE와 같은 구문이 있는 경우 (ex: [LIKE]AA%)
returnQuery = returnQuery + " ( " + itemName + " " + Strleft( Strright( Cstr( upv ) , "[" ), "]" ) + " '" + Strright( Cstr( upv ), "]" ) + "'"
Else
returnQuery = returnQuery + " ( " + itemName + valueCompare + "'" + Cstr( upv ) + "'"
End If
Else
'// 두번째 이후 조건값
If( Left( Cstr( upv ), 1 ) = "[" And Strleft( Cstr( upv ), "]" ) <> "" ) Then
'// LIKE와 같은 구문이 있는 경우 (ex: [LIKE]AA%)
returnQuery = returnQuery + bitCalculator + itemName + " " + Strleft( Strright( Cstr( upv ) , "[" ), "]" ) + " '" + Strright( Cstr( upv ), "]" ) + "'"
Else
returnQuery = returnQuery + bitCalculator + itemName + valueCompare + "'" + Cstr( upv ) + "'"
End If
End If
Else
'// where절이 없는 경우 추가
If( Left( Cstr( upv ), 1 ) = "[" And Strleft( Cstr( upv ), "]" ) <> "" ) Then
'// LIKE와 같은 구문이 있는 경우 (ex: [LIKE]AA%)
returnQuery = returnQuery + " where ( " + itemName + " " + Strleft( Strright( Cstr( upv ) , "[" ), "]" ) + " '" + Strright( Cstr( upv ), "]" ) + "'"
Else
returnQuery = returnQuery + " where ( " + itemName + valueCompare + "'" + Cstr( upv ) + "'"
End If
whereFlag = True
End If
End Forall
returnQuery = returnQuery + ")"
Else
'// 단수
If( whereFlag ) Then
'// where 절을 이미 삽입한 경우
If( Left( source, 1 ) = "[" And Strleft( source, "]" ) <> "") Then
'// LIKE와 같은 구문이 있는 경우 (ex: [LIKE]AA%)
returnQuery = returnQuery + REF_CALCULATE_BLOCK + itemName + " " + Strleft( Strright( source , "[" ), "]" ) + " '" + Strright( source, "]" ) + "'"
Else
returnQuery = returnQuery + REF_CALCULATE_BLOCK + itemName + valueCompare + "'" + source + "'"
End If
Else
'// where 절이 없는 경우 추가
If( Left( source, 1 ) = "[" And Strleft( source, "]" ) <> "" ) Then
'// LIKE와 같은 구문이 있는 경우 (ex: [LIKE]AA%)
returnQuery = returnQuery + " where " + itemName + " " + Strleft( Strright( source , "[" ), "]" ) + " '" + Strright( source, "]" ) + "'"
Else
returnQuery = returnQuery + " where " + itemName + valueCompare + "'" + source + "'"
End If
End If
End If
whereFlag = True
End If
MakeQueryElement = returnQuery
Exit Function
ErrorHandle:
Call WriteLog( Err(), curDb.Filepath + "/" + curAgent.Name + "::MakeQueryElement ERROR[" + Cstr( Erl() ) + "] : " + Error() )
Print source
MakeQueryElement = ""
Exit Function
End Function
****************************
SetTableDoc
****************************
Sub SetTableDoc( source As String )
%REM
함수명 : SetTableDoc
인자 : source - Query_String_Decoded
반환 : -
목적 : Query_String_Decoded로 넘어온 값 중에서 원하는 Query를 잘라내어 TableDoc의 Item으로 생성함.
이를 MakeQuery, GetTableInfo 함수에서 사용함으로 각 코드에 Table 형식에 맞게끔 코딩하는 것을 방지할 수 있음.
작성정보 : v1.0 / 이동완 / 2006-05-26
%END REM
On Error Goto ErrorHandle
Dim FieldList As Variant
Set TableDoc = New NotesDocument( curDb )
FieldList = Evaluate(|@Trim( @Explode("| & SQL_TABLE_FIELD & |";",") )|)
fieldAround = Evaluate(|@Explode("| & SQL_TABLE_FIELD_AROUND & |";",")|)
Forall ufl In FieldList
Call TableDoc.ReplaceItemValue( Cstr( ufl ), GetArgumentValue( Cstr( ufl ) & "=", source ) )
Call TableDoc.ReplaceItemValue( "n_" & Cstr( ufl ), GetArgumentValue( Cstr( ufl ) & "!=", source ) )
End Forall
Call TableDoc.ReplaceItemValue( "FieldList", FieldList ) '// 결과 Field 목록
Call TableDoc.ReplaceItemValue( "result", GetArgumentValue( "result=", source ) ) '// 결과
Call TableDoc.ReplaceItemValue( "order", GetArgumentValue( "order=", source ) ) '// 명령( select, exec ... )
Call TableDoc.ReplaceItemValue( "param-i", GetArgumentValue( "param-i=", source ) ) '// 파라메터 수
If( TableDoc.GetItemValue("param-i")(0) <> "" ) Then
For i%=1 To Cint( TableDoc.GetItemValue( "param-i" )(0) )
Call TableDoc.ReplaceItemValue( "param-" & Cstr(i%), GetArgumentValue( "param-" & Cstr(i%) & "=", source ) )
Next
End If
Exit Sub
ErrorHandle:
Call WriteLog( Err(), curDb.Filepath + "/" + curAgent.Name + "::SetTableDoc ERROR[" + Cstr( Erl() ) + "] : " + Error() )
Exit Sub
End Sub
****************************
SQLConnection
****************************
Function SQLConnection( dns As String )As Integer
'===========================================================================================
' 함 수 명 : SQLConnection
' 목 적 : SQL Server Connection
' 버 젼 : 1.0
' 매개 변수 : dns : DNS (ex: "hits")
'===========================================================================================
On Error Goto ErrorHandle
Dim status As String
Set con = New ODBCConnection
Set query = New ODBCQuery
Set result = New ODBCResultSet
Set query.Connection = con
Set result.Query = query
status = con.ConnectTo( dns, SQL_ID, SQL_PASSWORD )
If( Ucase( status ) <> "TRUE" ) Then
Print |<Result>
<msg>error</msg>
<ermsg>조회정보 서버에 연결할 수 없습니다.( DNS : | + SQL_DNS + | ) 관리자에게 서버의 ODBC 설정을 확인 요청을 하시기 바랍니다.</ermsg>
<erl>| & Erl & |</erl>
</Result>|
SQLConnection = False
Exit Function
End If
SQLConnection = True
Exit Function
ErrorHandle:
Call WriteLog( Err(), curDb.Filepath + "/" + curAgent.Name + "::SQLConnection ERROR[" + Cstr( Erl() ) + "] : " + Error() )
SQLConnection = False
Exit Function
End Function
****************************
WriteLog
****************************
Function WriteLog( ErrorOption As Integer, LogMessage As String )
%REM
함수명 : WriteLog
인자 : ErrorOption - 오류코드 ( 0 : 정상로그, 이외 오류코드 )
반환 : -
목적 : 로그 DB에 결과 기록
작성정보 : v1.0 / 이동완 / 2006-04-07
%END REM
On Error Goto ErrorHandle
Msgbox LogMessage
Print LogMessage
%REM
If( ErrorOption = 0 ) Then
Call curLog.LogAction( |[| & curDb.FilePath & |] | & LogMessage )
Else
Call curLog.LogError( ErrorOption, |[| & curDb.FilePath & |] | & LogMessage )
End If
%END REM
Exit Function
ErrorHandle:
Msgbox |[| & curDb.FilePath & |] | & curAgent.Name & |::WriteLog ERROR[| & Cstr( Erl() ) & |] : | & Error()
Exit Function
End Function
****************************
GetArgumentValue
****************************
Function GetArgumentValue(div As String, source As String )
'===========================================================================================
' 함 수 명 : GetArgumentValue
' 목 적 : 웹 파라미터 값을 반환하는 함수
' 버 젼 : 1.0
' 매개 변수 : div : 파라미터 (ex: "sv=")
' source : 전체문자열
'===========================================================================================
GetArgumentValue = ""
Dim pos As Integer
Dim valueItem As String
pos = Instr( source, div )
If pos > 0 Then
valueItem = Mid( source, pos )
If Instr( valueItem , "&" ) > 0Then
GetArgumentValue = Mid( valueItem, Instr( valueItem , "=") + 1, Instr( valueItem , "&") - Instr( valueItem , "=")-1)
Else
GetArgumentValue = Mid( valueItem, Instr( valueItem , "=") + 1)
End If
End If
End Function
아래의 코드는 반복적으로 Select 구문을 소모적으로 만들다 보니 시간도 비교적 많이 걸리게 되더군요.
앞으로 지속적으로 업데이트 해 나가야 겠지만...
1단계로 정리된 코드가 있어 기록해 둡니다.
---------------------------------------------------------------------------------------------
*********
(Options)
*********
Option Public
Uselsx "*LSXODBC"
*************
(Declarations)
*************
Dim ss As NotesSession
Dim curDb As NotesDatabase
Dim curDoc As NotesDocument
Dim curAgent As NotesAgent '// 현재 Agent
Dim con As ODBCConnection
Dim query As ODBCQuery
Dim result As ODBCResultSet
Const SQL_DNS = "Domino" '// ODBC DNS 이름
Const SQL_ID = "UserID" '// ODBC USER ID
Const SQL_PASSWORD = "Password" '// ODBC USER PASSWORD
Const SQL_TABLE_SCHEMA = "dbo" '// Table 스키마명
Const SQL_TABLE = "table" '// TABLE 이름
'//★ 아래의 코드는 RDB Table과 같은 형식이어야 함. ( 코드마다 틀리게 구성해야 함. )
Public Type table
r1 As String '// 필드 1
r2 As String '// 필드 2
r3 As String '// 필드 3
r4 As String '// 필드 4
r5 As String '// 필드 5
'// Query중 포함되지 않는 열을 지정하기 위한 멤버
n_r1 As String '// NOT 필드 1
n_r2 As String '// NOT 필드 2
n_r3 As String '// NOT 필드 3
n_r4 As String '// NOT 필드 4
n_r5 As String '// NOT 필드 5
End Type
'// 에이전트 Query_String으로 들어온 데이터를 정리하기 위한 객체
Dim sqlInfo As table
************
Initialize
************
Sub Initialize
On Error Goto ErrorHandle
Dim qs As String
Dim resultField As String '// 결과
Set ss = New NotesSession
Set curDb = ss.CurrentDatabase
Set curAgent = ss.CurrentAgent
Set curDoc = ss.DocumentContext
qs = curDoc.Query_String_Decoded(0)
'// 결과 코드 기본 *(값이 없으면), 특정 열만 가져오고자하면 해당 필드명, DISTINCT fieldname 하면 Domino 수식의 @Unique와 같은 동작을 하더군요... ^^
resultField = GetAgrumentValue( "result=", qs )
'//★ 아래의 코드는 RDB Table과 동일해야 합니다. (Declarations)에 정의된 구조체 참조
sqlInfo.r1 = GetArgumentValue( "r1=", qs )
sqlInfo.r2 = GetArgumentValue( "r2=", qs )
sqlInfo.r3 = GetArgumentValue( "r3=", qs )
sqlInfo.r4 = GetArgumentValue( "r4=", qs )
sqlInfo.r5 = GetArgumentValue( "r5=", qs )
sqlInfo.n_r1 = GetArgumentValue( "r1!=", qs )
sqlInfo.n_r2 = GetArgumentValue( "r2!=", qs )
sqlInfo.n_r3 = GetArgumentValue( "r3!=", qs )
sqlInfo.n_r4 = GetArgumentValue( "r4!=", qs )
sqlInfo.n_r5 = GetArgumentValue( "r5!=", qs )
Print |Content-type: text/xml|
Print |<?xml version='1.0' encoding='KSC5601'?>|
'// Server 연결
If( SQLConnection( SQL_DNS ) = False ) Then Exit Sub
If( GetTableInfo(resultField) = False ) Then Goto ProcessEnd
ProcessEnd:
con.Disconnect
Exit Sub
ErrorHandle:
Print |<Result>
<msg>error</msg>
<ermsg>| + curDb.Filepath + "/" + curAgent.Name + "::initialize ERROR[" + Cstr( Erl() ) + "] : " + Error() + |</ermsg>
<erl>| + Cstr( Erl() ) + |</erl>
</Result>|
Msgbox curDb.Filepath + "/" + curAgent.Name + "::initialize ERROR[" + Cstr( Erl() ) + "] : " + Error()
If( con.IsConnected ) Then
con.Disconnect
End If
Exit Sub
End Sub
**************
GetTableInfo
**************
Function GetTableInfo( res As String ) As Integer
%REM
함수명 : GetTableInfo
인자 : res - Query 결과
반환 : Boolean - Query 처리 결과
- True : 정상처리
- False : 비정상 종료
목적 : 테이블의 정보를 가져오기 위함
작성정보 : v1.0 / 이동완 / 2006-05-23
%END REM
On Error Goto ErrorHandle
Dim index As Integer
Dim whereFlag As Boolean
whereFlag = False
query.SQL = MakeQuery( res )
If( query.SQL = "" ) Then
Msgbox "Query를 조합하지 못하였습니다."
GetEquipmentInfo = False
Exit Function
End If
If Not result.Execute Then
Messagebox result.GetExtendedErrorMessage + "/" + result.GetErrorMessage
GetEquipmentInfo = False
Exit Function
End If
'// 14000 라인 이상의 데이터를 쿼리해오면 오류가 뜨더군요... Out of memory 그래서...
result.MaxRows = 14000
If( result.NumRows = 0 ) Then
Print "<Result>검색한 결과가 없습니다.</Result>"
GetEquipmentInfo = False
Exit Function
End If
Print |<Result>|
index = 0
Do
result.NextRow
Print "<data index='" & index & "'>"
'//★ 아래의 If문 사이에 있는 코드는 RDB Table 구조와 동일해야 합니다. ( 코드마나 다르게 구성해야함. )
If( res = "" Or Lcase( res ) = "all" ) Then
Print "<r1>" & result.GetValue(1) & "</r1>"
Print "<r2>" & result.GetValue(2) & "</r2>"
Print "<r3>" & result.GetValue(3) & "</r3>"
Print "<r4>" & result.GetValue(4) & "</r4>"
Print "<r5>" & result.GetValue(5) & "</r5>"
Else
'// DISTINCT 와 같은 문자가 들어가는 것을 위해... ^^
Print "<" + Strrightback( res, " " ) + ">" + result.GetValue(1) + "</" + Strrightback( res, " " ) + ">"
End If
Print "</data>"
index = index + 1
Loop Until result.IsEndOfData
Print |</Result>|
GetTableInfo = True
Exit Function
ErrorHandle:
Call WriteLog( Err(), curDb.Filepath + "/" + curAgent.Name + "::GetTableInfo ERROR[" + Cstr( Erl() ) + "] : " + Error() )
GetTableInfo = False
Exit Function
End Function
***************
MakeQuery
***************
Function MakeQuery( res As String )As String
%REM
함수명 : MakeQuery
인자 : res - Query 결과
반환 : String - Query 조합 결과
목적 : 테이블의 데이터를 가져오기위한 Query 조합
작성정보 : v1.0 / 이동완 / 2006-05-24
%END REM
On Error Goto ErrorHandle
Dim pluralValue As Variant
Dim returnQuery As String
Dim whereFlag As Boolean
If( res = "" Or Lcase( res ) = "all" ) Then
returnQuery = "Select * from " + SQL_TABLE
Else
returnQuery = "Select " + res + " from " + SQL_TABLE
End If
'//★ Query를 조합하는 구문으로 RDB Table 형식과 동일하게 처리해야 함. ( 코드마다 다르게 구성해야함.)
returnQuery = returnQuery + MakeQueryElement( "r1", sqlInfo.r1, whereFlag )
returnQuery = returnQuery + MakeQueryElement( "r2", sqlInfo.r2, whereFlag )
returnQuery = returnQuery + MakeQueryElement( "r3", sqlInfo.r3, whereFlag )
returnQuery = returnQuery + MakeQueryElement( "r4", sqlInfo.r4, whereFlag )
returnQuery = returnQuery + MakeQueryElement( "r5", sqlInfo.r5, whereFlag )
'// 특정 데이터가 들어가있지 않은 문서를 Query 해오기 위해서 사용
returnQuery = returnQuery + MakeQueryNotElement( "r1", sqlInfo.n_r1, whereFlag )
returnQuery = returnQuery + MakeQueryNotElement( "r2", sqlInfo.n_r2, whereFlag )
returnQuery = returnQuery + MakeQueryNotElement( "r3", sqlInfo.n_r3, whereFlag )
returnQuery = returnQuery + MakeQueryNotElement( "r4", sqlInfo.n_r4, whereFlag )
returnQuery = returnQuery + MakeQueryNotElement( "r5", sqlInfo.n_r5, whereFlag )
MakeQuery = returnQuery
Exit Function
ErrorHandle:
Call WriteLog( Err(), curDb.Filepath + "/" + curAgent.Name + "::MakeQuery ERROR[" + Cstr( Erl() ) + "] : " + Error() )
MakeQuery = ""
Exit Function
End Function
**********************
MakeQueryElement
**********************
Function MakeQueryElement( itemName As String, source As String, whereFlag As Boolean )As String
%REM
함수명 : MakeQueryElement
인자 : itemName - Query 필드
source - Query 필드 값
whereFlag - where 구문 삽입 유무
반환 : String - Query 조합 결과
목적 : Query 부분 조합
작성정보 : v1.0 / 이동완 / 2006-05-24
%END REM
On Error Goto ErrorHandle
Dim pluralValue As Variant
Dim returnQuery As String
If( Trim( source ) <> "" ) Then
If( Strleft( source, "," ) <> "" ) Then
'// 복수
If( whereFlag ) Then
returnQuery = returnQuery + " AND "
End If
pluralValue = Evaluate(|@Unique( @Trim( @Explode("| & source & |";",") ) )|)
Forall upv In pluralValue
If( whereFlag ) Then
If( Cstr( upv ) = Cstr( pluralValue(0) ) ) Then
returnQuery = returnQuery + " ( " + itemName + "='" + Cstr( upv ) + "'"
Else
returnQuery = returnQuery + " OR " + itemName + "='" + Cstr( upv ) + "'"
End If
Else
returnQuery = returnQuery + " where ( " + itemName + "='" + Cstr( upv ) + "'"
whereFlag = True
End If
End Forall
returnQuery = returnQuery + ")"
Else
'// 단수
If( whereFlag ) Then
returnQuery = returnQuery + " AND " + itemName + "='" + source + "'"
Else
returnQuery = returnQuery + " where " + itemName + "='" + source + "'"
End If
End If
whereFlag = True
End If
MakeQueryElement = returnQuery
Exit Function
ErrorHandle:
Call WriteLog( Err(), curDb.Filepath + "/" + curAgent.Name + "::MakeQueryElement ERROR[" + Cstr( Erl() ) + "] : " + Error() )
MakeQueryElement = ""
Exit Function
End Function
*************************
MakeQueryNotElement
*************************
Function MakeQueryNotElement( itemName As String, source As String, whereFlag As Boolean )As String
%REM
함수명 : MakeQueryNotElement
인자 : itemName - Query 필드
source - Query 필드 값
whereFlag - where 구문 삽입 유무
반환 : String - Query 조합 결과
목적 : Query 부분 (NOT) 조합
작성정보 : v1.0 / 이동완 / 2006-05-25
%END REM
On Error Goto ErrorHandle
Dim pluralValue As Variant
Dim returnQuery As String
If( Trim( source ) <> "" ) Then
If( Strleft( source, "," ) <> "" ) Then
'// 복수
If( whereFlag ) Then
returnQuery = returnQuery + " AND "
End If
pluralValue = Evaluate(|@Unique( @Trim( @Explode("| & source & |";",") ) )|)
Forall upv In pluralValue
If( whereFlag ) Then
If( Cstr( upv ) = Cstr( pluralValue(0) ) ) Then
returnQuery = returnQuery + " ( " + itemName + " <> '" + Cstr( upv ) + "'"
Else
returnQuery = returnQuery + " AND " + itemName + " <> '" + Cstr( upv ) + "'"
End If
Else
returnQuery = returnQuery + " where ( " + itemName + " <> '" + Cstr( upv ) + "'"
whereFlag = True
End If
End Forall
returnQuery = returnQuery + ")"
Else
'// 단수
If( whereFlag ) Then
returnQuery = returnQuery + " AND " + itemName + " <> '" + source + "'"
Else
returnQuery = returnQuery + " where " + itemName + " <> '" + source + "'"
End If
End If
whereFlag = True
End If
MakeQueryNotElement = returnQuery
Exit Function
ErrorHandle:
Call WriteLog( Err(), curDb.Filepath + "/" + curAgent.Name + "::MakeQueryNotElement ERROR[" + Cstr( Erl() ) + "] : " + Error() )
MakeQueryNotElement = ""
Exit Function
End Function
*********************
SQLConnection
*********************
Function SQLConnection( dns As String )As Integer
'===========================================================================================
' 함 수 명 : SQLConnection
' 목 적 : SQL Server Connection
' 버 젼 : 1.0
' 매개 변수 : dns : DNS (ex: "hits")
'===========================================================================================
On Error Goto ErrorHandle
Dim status As String
Set con = New ODBCConnection
Set query = New ODBCQuery
Set result = New ODBCResultSet
Set query.Connection = con
Set result.Query = query
status = con.ConnectTo( dns, SQL_ID, SQL_PASSWORD )
If( Ucase( status ) <> "TRUE" ) Then
Print |<Result>
<msg>error</msg>
<ermsg>조회정보 서버에 연결할 수 없습니다.( DNS : | + SQL_DNS + | ) 관리자에게 서버의 ODBC 설정을 확인 요청을 하시기 바랍니다.</ermsg>
<erl>| & Erl & |</erl>
</Result>|
SQLConnection = False
Exit Function
End If
SQLConnection = True
Exit Function
ErrorHandle:
Call WriteLog( Err(), curDb.Filepath + "/" + curAgent.Name + "::SQLConnection ERROR[" + Cstr( Erl() ) + "] : " + Error() )
SQLConnection = False
Exit Function
End Function
******************
WriteLog
******************
Function WriteLog( ErrorOption As Integer, LogMessage As String )
%REM
함수명 : WriteLog
인자 : ErrorOption - 오류코드 ( 0 : 정상로그, 이외 오류코드 )
반환 : -
목적 : 로그 DB에 결과 기록
작성정보 : v1.0 / 이동완 / 2006-04-07
%END REM
On Error Goto ErrorHandle
Msgbox LogMessage
%REM
If( ErrorOption = 0 ) Then
Call curLog.LogAction( |[| & curDb.FilePath & |] | & LogMessage )
Else
Call curLog.LogError( ErrorOption, |[| & curDb.FilePath & |] | & LogMessage )
End If
%END REM
Exit Function
ErrorHandle:
Msgbox |[| & curDb.FilePath & |] | & curAgent.Name & |::WriteLog ERROR[| & Cstr( Erl() ) & |] : | & Error()
Exit Function
End Function
**********************
GetArgumentValue
**********************
Function GetArgumentValue(div As String, source As String )
'===========================================================================================
' 함 수 명 : GetArgumentValue
' 목 적 : 웹 파라미터 값을 반환하는 함수
' 버 젼 : 1.0
' 매개 변수 : div : 파라미터 (ex: "sv=")
' source : 전체문자열
'===========================================================================================
GetArgumentValue = ""
Dim pos As Integer
Dim valueItem As String
pos = Instr( source, div )
If pos > 0 Then
valueItem = Mid( source, pos )
If Instr( valueItem , "&" ) > 0Then
GetArgumentValue = Mid( valueItem, Instr( valueItem , "=") + 1, Instr( valueItem , "&") - Instr( valueItem , "=")-1)
Else
GetArgumentValue = Mid( valueItem, Instr( valueItem , "=") + 1)
End If
End If
End Function
댓글을 달아 주세요
-
바라기
2007/05/25 20:32
댓글주소
수정/삭제
댓글쓰기
참... 에이전트 호출하는 방식...
1.
http://serverURL/db.nsf/agent?openagent&result=DISTINCT r1&r2=TEST&r3=1111,2222,3333,4444&r4!=AAAA,BBBB
--->
결과는...
r2 필드값이 TEST 이며, r3 필드값이 1111 또는 2222 또는 3333 또는 4444 이며, r4 필드값이 AAAA 가 아니며, r4 필드값이 BBBB가 아닌 레코드의 r1값 중... 중복값을 제외한 목록이 반환 됩니다.
2.
http://serverURL/db.nsf/agent?openagent&r2=TEST&r2=1111,2222,3333
---->
결과는...
r2 필드값이 TEST인 레코드의 모든 필드값을 반환합니다.
( r2라는 파라메터를 중복해서 넣어주면 두번째껀 무시해 버립니다... !! )
result 파라메타가 없는 경우 모든 필드값을 반환하져...
3.
http://serverURL/db.nsf/agent?openagent&r2=TEST&r2!=1111,2222,3333
----->
결과는...
r2 필드값이 TEST인 레코드의 모든 필드값을 반환합니다.
r2! 파라메터가 무의미해 집니다. ( Select 쿼리에는 들어 갑니다... )
결과는 XML 형식으로 화면에 뿌려집니다~~~!!
다른 형태를 원하시면~ 잘~~ 수정해야 합니다~ -
황성진
2008/09/12 10:34
댓글주소
수정/삭제
댓글쓰기
ODBC를 이용한 데이터 쿼리를 참고하고 있습니다.
이에 대해서 몇 가지 질문을 하고자 합니다.
1. 기존의 RDBMS 데이터 뿐만 아니라, 특히 xls 파일에 대해서 각 필드 별로 노츠 데이터베이스파일 NSF의 각 필드에 대응시켜 매칭됨으로써, 이를 이용한 문서를 생성할 수 있는지 알고 싶습니다.
2. 노츠 데이터베이스(test.nsf)라고 만든 것에 대해서 외부 애플리케이션에서 접근해서 test.nsf의 각 필드에 해당하는 값을 획득하는 방법을 알고 싶습니다.
가능하면 샘플을 통해 설명을 부탁드립니다. Notes를 이용해서 애플리케이션을 작성하는 것이 너무도 힘이 듭니다.-

바라기
2008/09/17 12:12
댓글주소
수정/삭제
답변이 늦었네요...
지금... 프로젝트가 진행중이라... 자세한 답변은 힘들듯 합니다.
1. 엑셀파일을 이용해서 데이터를 업로드할 수 있습니다.
샘플은 찾아봐야 할텐데요... 제가 요즘 도미노를 하지 않고 있어서 바로 찾기는 힘들듯 하고 찾으면 게시를 해 놓겠습니다. NotesToExcel.txt라는 파일이 아마 게시되어 있을겁니다. 반대의 내용이지만 참조를...
2. 노츠 DB의 내용을 외부 어플에서 접근하려면 C/C++ API를 이용하여 직접 접근하는 방법이 있겠구요. 간단한 방법으로는 데이터에 접근할 수 있는 에이전트를 해당 DB에 생성해 놓고 XML 반환을 할 수 있는 구조로 말이죠. 그리고 외부 어플에서 해당 Agent를 호출하여 반환하는 Response XML 데이터를 파싱하여 사용하는 방법이 있을것 같습니다.
-
시스템 구성이 아래와 같이 되어있다고 가정을 할때.
----------------------------------------------------
어플리케이션(결재) 서버 : app.company.com
메일서버 : mail.company.com
----------------------------------------------------
시스템에서의 처리는 당연 결재서버 또는 메일서버를 Primary Server로 구성하고 나머지 서버는 Secondary Server로 구성하여 프로그램상으로 개발하는데는 문제점이 없도록 하고 있습니다.
하지만 웹브라우저상에서 처리되어야 하는 코드중에 이런것이 있습니다.
1) 결재 처리요청 메일 발송
2) 결재자 결재요청 메일 수신
3) 결재할 문서 목록에서 문서를 클릭 (app.company.com)
4) 승인버튼 클릭하여 결재처리 (app.company.com)
5) 결재자에게 발송된 결재요청메일 삭제 (mail.company.com)
6) 결재할 문서 목록 갱신 (app.company.com)
위와같은 순서로 처리되는 경우,
5) -> 6) 항목으로 넘어가는 과정에서 웹브라우저상 권한없음 오류가 발생할 수 있습니다.
이는 DB ACL 문제가 아니며 브라우저상 도메인이 다른 페이지에 대한 자바스크립트 접근권한이 없다는 경고입니다.
물론 5)번 항목 처리시 새창을 오픈해서 처리하고 닫아버리면 될수도 있는 문제겠지만, 창이 열리고 닫히고 그러면 싫어할 사람들이 많죠.
아니면 document.domain = "company.com"; 코드를 화면에 보여지는 모든 페이지에 추가하면 되는 문제일 수도 있습니다. 하지만 연동되는 타시스템이 있다면 이걸 맞춰주는것도 쉬운 문제는 아닐듯 합니다.
다른 방법에 대해서 설명을 하겠습니다.
5) 번 항목에서 결재 요청메일을 삭제하고 나서는 화면이 어떻게 되어야할지 보통적으로 에이전트에서 자바스크립트 형식으로 프린트를 합니다.
print |<script>
try
{
opener.window.location.reload();
window.close();
}
catch( e )
{
var actionURL = "http://app.company.com/refresh.nsf/Refresh?CreateDocument";
var _form = document.createElement("form");
_form.action = actionURL;
_form.method = "post";
// saveoptions 필드를 0으로 두어야 필요없는 문서가 DB에 저장되지 않습니다.
var _saveoption = document.createElement( "<input type=hidden name='saveoptions'>" );
_form.appendChild(_saveoption);
document.body.appendChild(_form);
_form.saveoptions.value = "0";
_form.submit();
}
</script>|
마지막에 처리될 코드이죠...
그럼 이것으로 끝나냐? 아니죠?
위의 코드에 보면 var actionURL = "http://app.company.com/refresh.nsf/Refresh?CreateDocument";
이라는 코드가 있습니다. 이는 refresh.nsf 라는 DB가 있어야 하며 그 DB에는 Refresh라는 양식이 있어야 합니다.
또한 var _saveoption = document.createElement( "<input type=hidden name='saveoptions'>" ); 이라는 부분이 있는데 이는 Refresh 양식에 saveoptions 필드가 있어야 존재해야 한다는 얘기가 됩니다.
그리고 또 중요한건...
Refresh 양식에 $$Return 필드를 두어 필요한 코드가 들어갈 수 있도록 합니다.
예를들어 "<script>opener.window.location.reload();window.close();</script>"라고 두면 상위 opener를 reload하고 창이 닫힙니다.
-------------------------------------
위와 같이 처리하는 이유는...
CreateDocument는 URL 호출이기 때문에 도메인과 상관없이 호출할 수 있으며, createdocument로 호출된 이후에는 opener와 같은 도메인인 app.company.com으로 변경되므로 opener를 자바스크립트로 접근하여 처리할 수 있게 됩니다.
다른 방법도 있겠지만, 여러가지로 응용하여 사용할 수 있는 코드입니다.
댓글을 달아 주세요
라디오버튼, 확인란 등...
CS에서 저장을해서 읽기 모드로 볼 경우, 선택되어진 값만 보이도록 처리하기 위해서 어떻게 표현을 하시는지요.( 물론 있는 그대로를 보여줄 경우는 해당 필드만 놔두면 되겠지만요... ^^ )
가정1. 라디오버튼을 사용.
전제1. 읽기 모드시엔 사용자가 선택한 값만 보이도록 함.
전제2. 내부코드에서 필드값을 코드화하여 사용함.
전제3. 해당 값이 추가 변경될 수 있으므로 한곳에서 관리를 해야함.
--------------------------------------------------------------------------
물론 방법은 여러가지 입니다.... 그중 한가지에 대해서 기록을 합니다.
목록 선택 필드(Options 필드)에 사용자는 기아, 현대, 삼성, 대우, 쌍용, 기타 중 하나를 선택할 수 있다고 생각을 해보죠.
그럼 Options 필드의 종류를 "라디오 단추"로 선택하고, 선택목록값에 "기아", "현대", "삼성", "대우", "쌍용", "기타"를 입력해 놓으실 겁니다.[가정1]
그러나 만약 내부 프로그램에서 해당 값을 사용하여 먼가를 처리하는 코드가 있다라고 하면??[전제2]
한글을 사용하는 것보다는 특정 코드값으로 처리를 해야할 경우가 발생됩니다.
이런경우 Options 필드의 선택목록값을 파이프(|)를 이용하여 Alias를 지정하죠~ "기아|0", "현대|1", "삼성|2", "대우|3", "쌍용|4", "기타|etc" 처럼요.
물론 Options 필드를 읽기모드에서 보이도록 처리하면 될 수도 있으나, [전제1]의 목적과 [전제3]의 목적을 달성하기 위해 닥질이 필요합니다.
1. Options 필드는 읽기모드시 숨김처리를 합니다.
2. 그 바로 위나 아래에 <계산된 문자열>을 삽입합니다. 코드는 이후에.
3. OptionsList 필드를 양식 맨 상단에 추가합니다.(맨 아래도 상관없구요... ^^)
4. OptionsList 필드는 종류 : 문자열, 표시할때 계산, 다중값 허용, 읽기/편집모드 모두 숨김으로 설정하고 값으로 "기아|0" : "현대|1" : "삼성|2" : "대우|3" : "쌍용|4" : "기타|etc"로 설정합니다.
5. Options 필드의 선택목록값을 수식으로 변경하여 OptionsList를 입력합니다.
자 그럼 마지막으로 2번 항목에서 삽입한 <계산된 문자열>의 수식을 지정해야 합니다.
어떻게 하시겠습니까?
그냥 Options라고 하시면 어떻게 표현되는지 아시죠?
만약 기아를 선택하셨다면?? 0이라 표현이 될겁니다.
[전제1]에 위배되죠...
자~ 그럼...
이 부분의 코드를 기록하기 위해 장황하게... ㅠㅠ
첫번째 단순 무식(?)한 방법
=========================================================================================
result := "";
@For( i := 1 ; i <= @Elements(OptionsList) ; i := i + 1 ;
@If( @Right( @Subset( @Subset( OptionsList ; i ) ; -1 ) ; "|" ) = Options ;
@Set( "result" ; @Left( @Subset( @Subset( OptionsList ; i ) ; -1 ) ; "|" ) ) ;
"" )
);
result
=========================================================================================
R6 부터 수식에도 반복문이 생긴건 아시죠?? ^^
위와 같은 방법으로 할 수 있습니다.
코드는 간단하죠? OptionsList 값을 하나씩 반복하면서 파이프(|)뒤에 값과 Options 값과 일치하는 부분을 찾아서 보여주는 거죰...
확실한 방법일 수 있으나 항목 수 만큼 반복해야 하니깐 왠지 모르게 다른 방법이 없을까 찾아보게 됩니다....
두번째 조금은 무모할지 모르나 간단하고 빠르게 목적을 달성할 수 있는 방법입니다.
=========================================================================================
res := @Implode( OptionsList ; "^^^" );
result := @Explode( @Word( res ; "|" + Options + "^^^" ; 1 ) ; "^^^" );
@Subset( result ; -1 )
=========================================================================================
코드 줄이 짧아졌죠...
간단하게 설명하자면. OptionsList 값을 "^^^"로 합칩니다.
그리고 "|" + Options + "^^^"값으로 @Word 함수를 호출하면... 맨끝에 원하는 값이 위치하게 됩니다.
다시 "^^^"로 Explode 처리하면~~~ 배열로 잡히면서 맨 끝에 값이 원하는 값...
루프 돌리는 것보다 속도가 훨씬 빠를것이라 예상이 되네요...
이 한 코드로 속도 향상을 기대하는건 쩜 힘들지만... 이런 코드덜이 쌓이면?? ^^
댓글을 달아 주세요
(Options)
Option Declare
--------------------------------
(Declarations)
Dim ss As NotesSession
Dim curDb As NotesDatabase '// 현재 Database
Dim curAgent As NotesAgent '// 현재 Agent
Dim curLog As NotesLog '// Log 기록
Const LOG_PROGRAM = "에이전트 프로그램(프로세스) 이름-로그 기록명" '★
Const DBPATH_LOG = "Application\log.nsf" '★
---------------------------------
Sub Initialize
'★ 에이전트명은 언제나 -> (에이전트명)|agAgentName
%REM
함수명 : Initialize
인자 : -
반환 : -
목적 : -
작성정보 : v1.0 / 이동완 / 2006-04-07 '★
%END REM
On Error Goto ErrorHandle
Set ss = New NotesSession
Set curDb = ss.CurrentDatabase
Set curAgent = ss.CurrentAgent
'// Log Object 생성 및 Open
Set curLog = New NotesLog( curAgent.Name & | Log(| & curDb.FilePath & |)| )
Call curLog.OpenNotesLog( curDb.Server, DBPATH_LOG )
'// Start Log
Call WriteLog( Err(), LOG_PROGRAM & " 시작" )
'// ------------------------------------------------------------------------------------------------------------------
'// 실제 코드 (여기에 작성하세요~)
'// ------------------------------------------------------------------------------------------------------------------
'★
'// ------------------------------------------------------------------------------------------------------------------
'// End Log
Call WriteLog( Err(), LOG_PROGRAM & " 종료" )
Call curLog.Close()
Exit Sub
ErrorHandle:
Call WriteLog( Err(), curAgent.Name & |::Initialize ERROR[| & Cstr( Erl() ) & |] : | & Error() )
Call curLog.Close()
Exit Sub
End Sub
----------------------------------
Function WriteLog( ErrorOption As Integer, LogMessage As String )
%REM
함수명 : WriteLog
인자 : ErrorOption - 오류코드 ( 0 : 정상로그, 이외 오류코드 )
반환 : -
목적 : 로그 DB에 결과 기록
작성정보 : v1.0 / 이동완 / 2006-04-07
%END REM
On Error Goto ErrorHandle
If( ErrorOption = 0 ) Then
Call curLog.LogAction( |[| & curDb.FilePath & |] | & LogMessage )
Else
Call curLog.LogError( ErrorOption, |[| & curDb.FilePath & |] | & LogMessage )
End If
Exit Function
ErrorHandle:
Print |[| & curDb.FilePath & |] | & curAgent.Name & |::WriteLog ERROR[| & Cstr( Erl() ) & |] : | & Error()
Msgbox |[| & curDb.FilePath & |] | & curAgent.Name & |::WriteLog ERROR[| & Cstr( Erl() ) & |] : | & Error()
Exit Function
End Function
--------------------------------
Function UserFunctionTemplate( x As Integer ) As Boolean
%REM
함수명 : 함수명(UserFunctionTemplate) '★
인자 : 인자명(x) - 인자설명 '★
반환 : 반환값형식(Boolean) - 반환값에 대한 설명 '★
- True : 존재함. '★
- False : 없음. '★
목적 : 함수 목적 기록 '★
작성정보 : v1.0 / 이동완 / (작성일/최근 수정일)2006-04-07 '★
%END REM
On Error Goto ErrorHandle
'// ------------------------------------------------------------------------------------------------------------------
'// 실제 코드 (여기에 작성하세요~)
'// ------------------------------------------------------------------------------------------------------------------
'★
'// ------------------------------------------------------------------------------------------------------------------
Exit Function
ErrorHandle:
Call WriteLog( Err(), curAgent.Name & |::함수이름 ERROR[| & Cstr( Erl() ) & |] : | & Error() ) '// 아래코드 형식으로 '★
'Call WriteLog( Err(), curAgent.Name & |::UserFunctionTemplate ERROR[| & Cstr( Erl() ) & |] : | & Error() )
Exit Function
End Function
댓글을 달아 주세요
| LotusScript의 Trim 함수 많이 쓰시죠? JavaScript에서도 가끔(?) 사용되는 함수입니다. Trim~~ 앞뒤 공백을 제거하고 중간에 겹쳐진 스페이스를 하나의 스페이스로... --------------------------------------------------------------------------------------------------- function Trim(sValue) { sValue = String(sValue); // 다중 공백 제거 for( ; sValue.indexOf(" ") != -1 ; ) sValue = sValue.replace( " ", " " ); // 앞 공백 제거 if( sValue.indexOf(" ") == 0 ) sValue = sValue.substring( 1, sValue.length ); // 뒤 공백 제거 if( sValue.lastIndexOf(" ") == sValue.length -1 ) sValue = sValue.substring( 0, sValue.length-1 ); return sValue; } |
댓글을 달아 주세요
JS의 xmldoc와 VBScript의 tar 인수값이 문서 ID였는지 모르겠네요... ㅋㅋㅋ
---------------------------------------------------------------------------------------------------
HTTP개체를 VB나 JScript로 선언하고 노츠에서 Back-End로 처리하듯이 웹 스크립트로 처리한다면..??
물론, 어떤 분들은 숨겨진 프레임을 사용할 수도 있다고들 합니다.
하지만 숨겨진 프레임은 서브밋후 스크립트는 완료를 기다려 주지 않죠.. 바로 다음 로직이 수행되니 서브밋후 후속 조치에 어려운점들이 많습니다.
자 그럼.. 이 방법은 긴말이 필요 없습니다.
문서삭제를 예를 들어 간단한 셈풀 쏘스를 드립니다.
<script language="JScript">
function PostOrder (xmldoc)
{
var http = new ActiveXObject ("Microsoft.XMLHTTP");
http.Open("POST", "http://server/notes.nsf/view/Unid?DeleteDocument", false);
http.Send(xmldoc);
.
.
.
}
</script>
<script language=VBScript>
sub deleteDoc(tar)
dim Http
Set Http = CreateObject("Microsoft.XMLHTTP")
Targetpage = tar
Http.open "POST", Targetpage, False
Http.send RequestXML
.
.
.
End Sub
</SCRIPT>
Notes2Excel.txt







댓글을 달아 주세요