Informix OLE DB Provider 2.0
1. 설치 및 환경설정
1.1 제품설치
Informix OLE DB Provider는 Connect 2.30 TC1과 ClientSDK 2.30 TC1에 포함되어 있습니다. ESQL/C등을 사용하여 프로그램을 하지 않을 경우는 Connect 2.30을 설치합니다. 설치 시에는 꼭 표준 설치가 아닌 사용자 설치를 선택해야 Informix OLE DB Provider를 설치할 수 있습니다.
사용자 설치를 선택 후 Informix OLE/DB를 선택하면 MDAC 2.0이 자동으로 선택됩니다. 만약 MDAC 2.1을 사용하길 원한다면 제품설치 이후 MDAC 2.1을 다시 설치하여야 합니다.
그리고 $INFORMIXDIR/bin이 시스템 환경 PATH에 포함되어 있는지 확인합니다. 만약 포함이 되어있지 않다면 추가하세요.
1.2 환경설정
setnet32를 사용하여 환경변수를 설정한 후 이를 적용하기 위하여서는 regcopy.exe ($INFORMIXDIR/bin/regcopy)를 실행합니다. 그리고 제어판 서비스의 IIS서비스(admin & web)를 재기동(stop&start)합니다.
1.3 OLE DB 카달로그 생성
${INFORMIXDIR}/etc/coledbp.sql을 sysmaster데이터베이스에 informix사용자로 접속 후 실행합니다. 제거는 doledbp.sql을 사용하여 제거할 수 있습니다. OLE DB 시스템 카달로그를 생성하지 않을 경우 테이블이 없다는 오류를 발생시킵니다.
1.4 사용자 설정
NT 서버의 데이터베이스에 접속할 경우 도메인 사용자 계정으로 접속을 하고자 할 경우 사용자가 없다는 오류가 발생할 수 있습니다. 이는 사용자 계정이 로컬 로그인을 할 수 있는 권한이 없기 때문에 발생하는 문제입니다. 그러므로 사용자 관리자에서 데이터베이스에 접속하고자 하는 사용자 계정을 로컬 로그인이 가능하도록 보안 정책을 바꾸어 주어야 합니다. 사용자 계정은 8자이상을 사용하여도 무방하나 데이터베이스에서 인증되는 것은 8자까지 입니다.
2. 접속 방법
2.1 접속 문자열(Connection String)
접속 문자열을 다음의 여러 개의 부분으로 나뉘어집니다.
Provider : OLE DB Provider
Data Source : 접속할 데이터베이스
User ID : 사용자 ID
Password : 암호
o Provider
Provider는 접속시 사용할 OLE DB Provider를 설정하는 속성입니다. 만약 설정하지 않을 경우 마이크로소프트에서 제공하는 OLE DB Provider for ODBC가 기본적으로 사용되게 됩니다. 여기에 informix OLE DB Provider를 가리키게 할 수 있는 문자열을 다음의 3가지 입니다.
Informix OLE DB Provider
Ifxoledbc
Ifxoledbc.2
Ex) Provider=ifxoledbc
o Data Source
Data Source는 접속할 데이터베이스를 가리키는 속성입니다. 값의 설정은 데이터베이스명@서버명을 주면 됩니다.
Ex) Data Source=stores7@jupiter
o User ID
User ID는 데이터베이스에 접속할 ID를 설정하는 속성입니다. ODBC를 사용할 경우 처럼 UID로 줄여서 사용할 수 없습니다. Trust되어 있거나 netrc(Setnet32에서 Host의 암호를 설정)를 사용하여 접속할 경우에는 설정하지 않아도 됩니다.
Ex) User ID=informix
o Password
Password는 데이터베이스에 접속할 암호를 설정하는 속성입니다. ODBC를 사용할 경우처럼 PWD로 줄여서 사용할 수 없습니다. Trust되어 있거나 netrc를 사용하여 접속할 경우에는 설정하지 않아도 됩니다.
Ex) Password=in4mix
o 전체 접속 문자열
ConnString =
“Provider=ifxoledbc;Data Source=stores7@jupiter;User ID=informix;Password=in4mix“
3. 문제점 및 Workaround.
3.1 레코드 셋 사용상의 오류
Recordset(서버나 클라이언트 커서)을 사용 시 rowid와 관련하여 오류가 발생하는 경우가 있을 수 있습니다. 이는 adOpenKeyset이나 adOpenStatic을 사용할 경우 발생합니다. 꼭 이들 커서 유형이 필요한 경우가 아닌 경우 adOpenDynamic을 사용하면 오류가 발생하지 않습니다.
위의 커서 유형(adOpenKeyset, adOpenStatic)을 사용하고 rowid와 관련된 오류가 발생할 경우(JOIN을 사용할 경우 발생함) rowid를 함께 질의문에 추가하면 발생하지 않습니다.
*** 서버 커서의 경우 adOpenDynamic과 adOpenForwardOnly를 사용할 경우 RecordCount가 –1을 반환합니다. 이는 서버내의 커서가 생성중일 경우 그 크기를 알 수 없기 때문에 발생합니다. 이는 INFORMIX의 서버 스펙에 관련된 문제입니다. INFORMIX는 서버 커서를 생성시 여러 개의 쓰레드가 병렬로 처리를 하기 때문에 커서 내의 모든 결과가 만들어질 때까지 그 개수를 알 수 없게 됩니다.
3.2 레코드 셋을 이용 갱신 및 추가시 오류
갱신(Update)나 추가(Insert)가 가능한 Recordset을 생성할 경우 DBMS 버전 9.14이하 에서는 서버측 커서를 adCmdTableDirect(RecordCount 반환)를 사용하여 Open할 경우를 제외하고는 CursorLocation을 adUseServer를 사용할 수 없습니다(9.2에서 지원).
이 경우 CursorLocation을 adUseClient를 사용합니다(클라이언트 커서 사용). 이때 환경변수 중 DELIMIDENT가 y로 설정되어 있을 경우 SQL내 Identifier가 대소문자를 가리게 되므로 테이블이나 컬럼이 없다는 오류를 발생시킬 수 있습니다. 그러므로 Recordset을 Open시 SQL문내의 테이블명과 필드(컬럼)명은 모두 소문자로 작성합니다.
Dim rs AS New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open QueryStr, ConnStr, adOpenDynamic, adLockOptimistic, adCmdText
또는
rs.CursorLocation = adUseServer
rs.Open Tablename, ConnStr, adOpenDynamic, adLockOptimistic, adCmdTableDirect
3.3 레코드 셋을 이용한 갱신(VARCHAR)시 NULL 관련 오류
레코드 셋을 이용하여 행을 갱신하고자 할 경우 VARCHAR형의 컬럼에 길이가 0인 문자열을 대입하고 갱신(Rs.Update)할 경우 마이크로소프트의 커서 엔진과 관련된 오류가 발생할 수 있습니다.
인포믹스의 경우 ESQL/C를 사용할 경우에도 길
이가 0인 문자열 변수를 사용하여 갱신할 경우 컬럼의 값이 NULL이 되는 데, 이와 같은 이유에서 서버는 NULL의 값은 마이크로소프트 커서 엔진에는 길이가 0인 문자열을 가지게 되는 데에서 발생하는 오류로 추정됩니다.
해결방법은 서버의 컬럼을 NOT NULL또는 DEFAULT “”를 주어서 생성하여 직접적으로 오류가 발생하게 하거나 NULL일 경우 길이가 0인 문자열로 입력되게 하는 것입니다. 다른 방법으로는 프로그램 작성시 길이가 0인 문자열의 경우를 검사하여 “_”(스페이스)로 치환하여 대입하는 것입니다. 또는 직접 NULL을 대입하여도 무방할 것 같습니다.
3.4 여러 COM을 사용하여 동일 테이블을 접근할 경우
COM을 작성시 대부분의 작성자들은 각각의 COM에서 데이터베이스를 접속하고 이를 통하여 데이터베이스 작업을 진행합니다. 그리고 이들 COM들을 모아서 하나의 ASP페이지 또는 어플리케이션 작업에 사용하게 됩니다. 이 경우 Informix에서는 하나의 COM에서 삭제한 데이터가 다른 COM에서 적용되지 않아 Unique Constraint 오류 같은 것이 발생할 수 있습니다. 이는 마이크로소프트의 MTS에 의하여 데이터베이스 자원이 제대로 관리되지 않아서 발생되는 문제로 추정됩니다.
이 문제를 해결하는 방법으로는 COM을 작성시 데이터베이스 접속 객체를 인수로 받아 세션을 공유하여 사용하도록 COM을 수정하는 것입니다.
Ex)
Public Function aaa(Ac As ADODB.Connection, …) As …
…
End Function
Public Function bbb(Ac As ADODB.Connection, …) As …
…
End Function