Tibero Driver 연결가이드 Copyright 2013 TmaxData Co., Ltd. All Rights Reserved.
Copyright Notice Copyright 2013 TmaxData Co., Ltd. All Rights Reserved. 대한민국경기도성남시분당구황새울로 329 번길 5 티맥스빌딩우 ) 463-824 Restricted Rights Legend All TmaxData Software (Tibero ) and documents are protected by copyright laws and international convention. TmaxData software and documents are made available under the terms of the TmaxData License Agreement and may only be used or copied in accordance with the terms of this agreement. No part of this document may be transmitted, copied, deployed, or reproduced in any form or by any means, electronic, mechanical, or optical, without the prior written consent of TmaxData Co., Ltd. 이소프트웨어 (Tibero ) 사용설명서의내용과프로그램은저작권법과국제조약에의해서보호받고있습니다. 사용설명서의내용과여기에설명된프로그램은 TmaxData Co., Ltd. 와의사용권계약하에서만사용이가능하며, 사용권계약을준수하는경우에만사용또는복제할수있습니다. 이사용설명서의전부또는일부분을 TmaxData 의사전서면동의없이전자, 기계, 녹음등의수단을사용하여전송, 복제, 배포, 2차적저작물작성등의행위를하여서는안됩니다. Trademarks Tibero is a registered trademark of TmaxData Co., Ltd. Other products, titles or services may be registered trademarks of their respective companies. Tibero 는 TmaxData Co., Ltd. 의등록상표입니다. 기타모든제품들과회사이름은각각해당소유주의상표로서참조용으로만사용됩니다. 안내서정보안내서제목 : Tibero Driver 연결가이드발행일 : 2013-09-10 소프트웨어버전 : Tibero 5 안내서버전 : 2.1.2
내용목차 안내서에대하여... vii 제1장 ODBC 연결... 1 1.1. ODBC 개념... 1 1.2. Tibero ODBC 설치및구성... 2 1.2.1. ODBC 설치파일... 2 1.2.2. ODBC 드라이버등록... 4 1.2.3. ODBC 연결... 5 1.2.4. Windows 64bit에 32bit ODBC 설치... 8 1.3. ODBC Manager 설치... 10 1.4. 문제해결... 16 1.4.1. 로그발생... 16 1.5. 예제... 17 1.5.1. 연결예제... 17 1.5.2. 타입관련예제... 22 제2장 OLE DB 연결... 25 2.1. OLE DB 개념... 25 2.1.1. OLE DB의역할... 25 2.1.2. OLE DB 내부구조... 26 2.1.3. OLE DB 기능... 27 2.2. Tibero OLE DB Provider 설치및구성... 29 2.2.1. OLE DB 설치파일... 29 2.2.2. OLE DB Provider 등록... 30 2.2.3. OLE DB 연결... 33 2.2.4. Windows 64bit에 32bit OLE DB 설치... 36 2.3. Tibero OLE DB 연동... 38 2.3.1. ADO(ActiveX Data Objects)... 38 2.3.2. ADO.NET... 42 2.3.3. Enterprise Library 연동... 44 2.4. OLE DB 전환... 45 2.4.1. Oracle OLE DB... 45 2.5. 문제해결... 47 2.5.1. 로그발생... 47 2.5.2. 에러메시지처리... 48 2.5.3. 연동할때문제점... 48 2.6. 예제... 49 2.6.1. ASP... 49 2.6.2. ASP.NET... 53 2.6.3. C#... 55 제3장 JDBC 연결... 61 Tibero iii
3.1. JDBC 개념... 61 3.2. Tibero JDBC... 62 3.2.1. JDBC 드라이버... 62 3.2.2. 드라이버연동... 63 3.3. JDBC 전환... 65 3.3.1. Oracle JDBC... 65 3.4. 문제해결... 65 3.4.1. 로그발생... 65 3.5. 예제... 66 3.5.1. 기본예제... 66 3.5.2. 타입관련예제... 67 제4장 tbesql 연결... 71 4.1. tbesql 개념... 71 4.1.1. tbesql 기본동작... 71 4.2. tbesql 사용... 72 4.2.1. 관련파일... 72 4.2.2. 프리컴파일... 74 4.2.3. 컴파일및링크... 75 4.3. 문제해결... 76 4.3.1. 로그발생... 76 4.3.2. 단계별대처방안... 76 4.3.3. 에러코드... 76 4.4. 예제... 77 4.4.1. makefile 예제... 77 iv Tibero Driver 연결가이드
그림목차 [ 그림 1.1] ODBC... 1 [ 그림 1.2] ODBC 버전확인... 3 [ 그림 1.3] ODBC 등록확인... 5 [ 그림 1.4] ODBC 데이스소스추가... 6 [ 그림 1.5] IP, PORT 방식... 6 [ 그림 1.6] SID 방식... 7 [ 그림 1.7] tbdsn.tbr... 7 [ 그림 1.8] ODBC 접속테스트... 8 [ 그림 1.9] 32bit용 ODBC 데이터원본관리자실행및확인... 9 [ 그림 1.10] ODBC(=tbCLI) 환경변수적용... 16 [ 그림 2.1] UDA Architecture... 26 [ 그림 2.2] OLE DB 내부구조... 27 [ 그림 2.3] OLE DB 등록팝업... 31 [ 그림 2.4] udl 파일생성... 32 [ 그림 2.5] OLE DB 등록확인... 32 [ 그림 2.6] OLE DB 직접연결방식... 34 [ 그림 2.7] OLE DB DSN 이용방식... 35 [ 그림 2.8] OLE DB 연결테스트... 35 [ 그림 2.9] 32bit용 OLE DB 등록확인... 38 [ 그림 2.10] Visual Studio 에 Tibero DLL 참조추가... 44 [ 그림 3.1] TYPE1... 61 [ 그림 3.2] TYPE2... 61 [ 그림 3.3] TYPE3... 62 [ 그림 3.4] TYPE4... 62 [ 그림 4.1] tbesql 기본동작... 71 [ 그림 4.2] 프리컴파일소스생성... 74 Tibero v
안내서에대하여 안내서의대상 ODBC, OLE DB, JDBC, ESQL 와같은다양한인터페이스를통해 Tibero 로연결하기위한각 Driver 연동 방법을소개한다. 안내서의전제조건 본안내서는 Driver 연결과정을설명한안내서이다. 따라서본안내서를원활히이해하기위해서는다음과같은사항을미리알고있어야한다. 데이터베이스의이해 RDBMS의이해 운영체제및시스템환경의이해 UNIX 계열 (Linux 포함 ) 의기본지식 안내서의제한조건 본안내서는 Tibero 를실무에적용하거나운용하는데필요한모든사항을포함하지않는다. 안내서에대하여 vii
안내서규약 표기 <AaBbCc123> <Ctrl>+C [Button] 진하게 " "( 따옴표 ) ' 입력항목 ' 하이퍼링크 > +---- ---- 참고 의미프로그램소스코드의파일명, 디렉터리 Ctrl과 C를동시에누름 GUI의버튼또는메뉴이름강조다른관련안내서또는안내서내의다른장및절언급화면 UI에서입력항목에대한설명메일계정, 웹사이트메뉴의진행순서하위디렉터리또는파일있음하위디렉터리또는파일없음참고또는주의사항 [ 그림 1.1] [ 표 1.1] AaBbCc123 그림이름 표이름 명령어, 명령어수행후화면에출력된결과물, 예제코드 { } [ ] 필수인수값 옵션인수값 viii Tibero Driver 연결가이드
제 1 장 ODBC 연결 본장에서는 ODBC 에대한개념과 Tibero ODBC 의설치및구성에대해서설명한다. 1.1. ODBC 개념 ODBC(Open DataBase Connectivity) 는모든 DBMS에독립적인데이터베이스애플리케이션을작성하기위한 API의집합으로특정 DBMS 사용자가 ODBC 드라이버를통해다른 DBMS를사용할수있게한다. 따라서 DBMS에연결하기위해 ODBC 드라이버관리자를호출하여사용하려는드라이버를호출하고그드라이버는 SQL을사용하여 DBMS와교신한다. 즉, ODBC는사용자와각데이터베이스엔진사이를연결해사용자가공통된인터페이스로각각의다른데이터베이스엔진에접근하게하여원하는데이터를참조할수있도록한다. [ 그림 1.1] ODBC Tibero ODBC Tibero ODBC 는 2.x, 3.x 버전을모두지원한다. 단, ODBC 표준 61 개함수중아래 2 개함수를지원하지 않으며사용을할경우 not implemented 에러가발생한다. 함수 SQLBrowseConnect SQLSetScrollOptions 설명 연결문자열을찾아내기위해 iterative 한방법을제공하는 API 이다. 3.x 에서 SQLSetStmtAttr 로대체한다. 제 1 장 ODBC 연결 1
ODBC 표준관련링크 API 에대한관련정보는 http://msdn.microsoft.com/en-us/library/ms712628(vs.85).aspx 를참고한다. tbcli Tibero가제공하는 Call Level Interface(CLI) 로사용자의애플리케이션프로그램과 Tibero간의 SQL 인터페이스역할을수행한다. tbcli는 ODBC 및 X/Open Call Level Interface Standard를기초로개발되었으며 Tibero ODBC=tbCLI로인식해도무방하다. 1.2. Tibero ODBC 설치및구성 본절에서는 ODBC의설치파일과드라이버등록및연결하는방법에대해서설명한다. 기본적으로 32bit 클라이언트 OS 환경에서는 32bit ODBC 설치, 64bit 클라이언트 OS 환경에서는 64bit ODBC 설치방법을설명하며 64bit 클라이언트 OS 환경에서 32bit ODBC를설치하는방법은 1.2.4. Windows 64bit에 32bit ODBC 설치 를참고한다. 1.2.1. ODBC 설치파일 클라이언트인스톨러나 ODBC 인스톨러의경우 GUI 환경에서설치및등록을자동으로진행할수있다. 만약, 수동으로진행하려면 Tibero 서버가설치된환경에서설치하고자하는클라이언트컴퓨터환경에맞게설치파일을가져온다. 다음은서버의운영체제별바이너리위치에대한설명이다. UNIX 계열서버 구분 Windows 32bit Windows 64bit 바이너리위치 $TB_HOME/client/win32 $TB_HOME/client/win64 Windows 계열서버 32bit 바이너리 Tibero 버전 Tibero 4 SP1 및이전버전 Tibero 5 이상 구분 Windows 32bit Windows 64bit Windows 32bit Windows 64bit 위치 %TB_HOME%\client\lib %TB_HOME%\client\win64 %TB_HOME%\bin %TB_HOME%\client\win64 2 Tibero Driver 연결가이드
64bit 바이너리 Tibero 버전 Tibero 4 SP1 및이전버전 Tibero 5 이상 구분 Windows 32bit Windows 64bit Windows 32bit Windows 64bit 위치 %TB_HOME%\client\win32 %TB_HOME%\client\lib %TB_HOME%\client\win32 %TB_HOME%\bin 다음은배포되는바이러리파일명이다. 해당파일은 Tibero 5 기준이며다른버전의경우 exe 파일명이일 부다를수있다. 구분 Windows 32bit Windows 64bit 바이너리파일명 libtbcli.dll, libtbcli.lib, tbodbc_driver_installer_5_32.exe libtbcli.dll, libtbcli.lib, tbodbc_driver_installer_5_64.exe 서버와버전이일치하는지확인하기위해 libtbcli.dll 파일에서오른쪽마우스버튼을클릭한뒤 [ 속성 ] > [ 자세히 ] 의 Product version 을확인한다. [ 그림 1.2] ODBC 버전확인 제 1 장 ODBC 연결 3
1.2.2. ODBC 드라이버등록 ODBC 드라이버등록순서는다음과같다. 1. Tibero ODBC의 bit 선택 Tibero ODBC의 32bit 또는 64bit 선택은설치하는클라이언트 OS 환경에맞추기보다는 Tibero ODBC 를사용하는실제어플리케이션의 bit에맞춘다. 2. 바이너리복사 Tibero 버전에따라 ODBC 바이너리를복사하는위치가다르다. 버전에맞게 ODBC 바이너리를위치한다. Tibero 4 SP1 및이전버전 %WINDIR%\system32( 예 : c:\windows\system32) Tibero 5 이상임의의위치로가능하다. 단, 드라이버를등록할경우해당경로로지정이필요하다. ( 예 : c:\tibero\odbc) 3. 드라이버등록 command 창을열어 ODBC 바이너리가위치한곳으로이동한후명령어를실행한다. 만약 Windows 7 이상일경우 command 창을관리자권한으로실행한다. 등록방법 tbodbc_driver_installer_5_xx.exe -i <driver path> 항목 <driver path> 설명 ODBC 바이너리디렉터리이다. 등록예 C:\TmaxSoft\win64>tbodbc_driver_installer_5_64.exe -i c:\tmaxsoft\win64 4. 드라이버등록확인 [ 시작 ] > [ 제어판 ] > [ 관리도구 ] > [ 데이터원본 (ODBC)] > [ 드라이버 ] 에서 Tibero 드라이버가등록된것 을확인한다. 4 Tibero Driver 연결가이드
[ 그림 1.3] ODBC 등록확인 1.2.3. ODBC 연결 Tibero ODBC 를사용하는애플리케이션에서연결문자열 (Connection String) 을사용하는방식과 ODBC 관리자에 DSN(Data Source Name) 을등록하는방식에대해서설명한다. 연결문자열을사용하는방식 버전에따라서일부문자열이다르다. ODBC 함수중에서 SQLDriverConnect를사용할경우아래와같은정보가필요하다. 실제사용할때는한줄로입력하며 Tibero 5에서 DB 항목의경우는 DB NAME에해당하는정보를입력한다. Tibero 4 SP1 DRIVER={Tibero 4 ODBC Driver};SERVER=192.168.70.185;PORT=8629; Tibero 5 UID=dbtech;PWD=dbtech; DRIVER={Tibero 5 ODBC Driver};SERVER=192.168.70.185;PORT=8629;DB=t5; UID=dbtech;PWD=dbtech; 제 1 장 ODBC 연결 5
DSN 을등록하는방식 ODBC 함수중에서 SQLConnect를사용할때 DSN 정보가필요하므로 [ 제어판 ] > [ 관리도구 ] > [ 데이터원본 (ODBC)] > [ 시스템 DSN] 에데이터소스를추가한다. [ 그림 1.4] ODBC 데이스소스추가 접속방법은 IP, PORT 방식또는 SID 방식이있다. IP, PORT 방식을이용한접속 Tibero 클라이언트또는서버의설치없이 ODBC Driver를등록한이후에바로사용할수있다. [ 그림 1.5] IP, PORT 방식 6 Tibero Driver 연결가이드
SID 방식을이용한접속 Tibero 클라이언트또는서버가설치된경우사용할수있으며클라이언트설정파일인 tbdsn.tbr 파일 (Tibero 4 이전버전의경우 tbnet_alias.tbr 파일 ) 에 SID 이름이등록되어있어야한다. 참고 Tibero 클라이언트설치방법에대한자세한내용은 "Tibero 클라이언트설치가이드 " 를참고한다. [ 그림 1.6] SID 방식 [ 그림 1.7] tbdsn.tbr 제 1 장 ODBC 연결 7
DSN 등록후 [Test] 버튼을클릭하여정상적으로접속이되는지확인한다. 만약실패할경우 Tibero 서버 의기동, 방화벽차단, 접속정보등을확인한다. [ 그림 1.8] ODBC 접속테스트 1.2.4. Windows 64bit 에 32bit ODBC 설치 Windows 64bit 환경에 32bit Tibero ODBC 를설치할경우 "%WINDIR%\SysWOW64" 폴더의 32bit 용명령 어를이용한다. 다음은 Windows 64bit에 32bit ODBC 설치하는과정이다. 1. 바이너리복사 Tibero 버전에따라 ODBC 바이너리를복사하는위치가다르다. 버전에맞게 ODBC 바이너리를위치한다. Tibero 4 SP1 및이전버전 %WINDIR%\SysWOW64( 예 : c:\windows\syswow64) Tibero 5 이상임의의위치로가능하다. 단, 드라이버를등록할경우해당경로로지정이필요하다. ( 예 : c:\tibero\win32) 2. 드라이버등록 command 창을열어 ODBC 바이너리가위치한곳으로이동한후명령어를실행한다. 만약 Windows 7 이상일경우 command 창을관리자권한으로실행한다. 8 Tibero Driver 연결가이드
등록방법 tbodbc_driver_installer_5_32.exe -i <driver path> 항목 <driver path> 설명 32bit ODBC 바이너리디렉터리이다. 등록예 C:\TmaxSoft\win32>tbodbc_driver_installer_5_32.exe -i c:\tmaxsoft\win32 3. 드라이버등록확인 command 창을열어 "%WINDIR%\SysWOW64" 폴더로이동한후 32bit용 odbcad32.exe 명령어를실행한다. [ 그림 1.9] 32bit용 ODBC 데이터원본관리자실행및확인 참고 Windows 64bit 환경일경우 [ 시작 ] > [ 제어판 ] > [ 관리도구 ] > [ 데이터원본 (ODBC)] 의 64bit 용 odb cad32.exe 를이용한다. 제 1 장 ODBC 연결 9
4. ODBC 연결 ODBC 연결에대한자세한내용은 1.2.3. ODBC 연결 을참고한다. 주의 Windows 64bit 환경에 32bit Tibero ODBC 를설치할경우 ODBC 연결은 32bit 용 ODBC 데이터원본 관리자를이용해야한다. 1.3. ODBC Manager 설치 본절에서는 UNIX 계열 (Linux 포함 ) 에서 iodbc 설치및연동하는과정을설명한다. UNIX 계열의경우 ODBC Manager 가존재하지않으므로 iodbc 또는 UNIX ODBC 를별도로설치해야한다. 다음은 ODBC Manager 설치과정에대한설명이다. 1. Driver Manager 설치 2. profile 설정 3. ODBC 환경파일설정및확인 각과정에대한상세한설명은해당절의내용을참고한다. Driver Manager 설치 다음은 Driver Manager를설치하는과정에대한설명이다. 1. 다운로드 http://iodbc.org에서설치파일다운로드후설치를원하는서버에업로드한다. 다음은 libiodbc-3.52.7.tar.gz 파일을다운받아서버에설치한결과이다. 만약, tar 옵션의 xvzf가적용되지않을경우먼저 gunzip으로압축을해제한후 tar -xvf 옵션으로해제한다. $ tar -xvzf libiodbc-3.52.7.tar.gz libiodbc-3.52.7/ libiodbc-3.52.7/admin/ libiodbc-3.52.7/admin/gtk-2.0.m4 libiodbc-3.52.7/admin/gtk.m4 libiodbc-3.52.7/admin/libtool.m4 libiodbc-3.52.7/admin/ltoptions.m4 libiodbc-3.52.7/admin/ltsugar.m4 libiodbc-3.52.7/admin/ltversion.m4 libiodbc-3.52.7/admin/lt~obsolete.m4 10 Tibero Driver 연결가이드
libiodbc-3.52.7/admin/makefile.am libiodbc-3.52.7/admin/makefile.in libiodbc-3.52.7/admin/libiodbc.pc.in libiodbc-3.52.7/admin/libiodbc.spec.in libiodbc-3.52.7/admin/config.guess libiodbc-3.52.7/admin/config.sub libiodbc-3.52.7/admin/depcomp libiodbc-3.52.7/admin/install-sh libiodbc-3.52.7/admin/ltmain.sh libiodbc-3.52.7/admin/missing libiodbc-3.52.7/admin/mkinstalldirs libiodbc-3.52.7/debian/ libiodbc-3.52.7/debian/changelog 2. iodbc 설치 tar.gz 파일을가지고설치를진행할경우아래와같은순서를따른다. 설치전사전환경점검에서 prefix를설정하지않으면기본적으로 /usr/local 아래에설치되기때문에특정디렉터리를지정하여설치하고, 컴파일및설치작업을다시수행할경우 make clean 이후에진행한다. a. '$HOME/iodbc' 디렉터리에설치전사전환경점검을한다../configure --prefix=$home/iodbc --disable-gui b. 점검한결과문제가없으면컴파일한다../make c. 컴파일된파일을설치한다../make install 3. 설치확인설치된서버에원하는 bit로설치가되었는지확인한다. 특정 OS에따라 64bit 서버에 32bit로설치되는경우가있으므로 file 명령어를이용하여확인이필요하다. 만약, ODBC Manager가 64bit로설치됐다면내부적으로사용하는 Tibero ODBC 역시 64bit여야하며재설치가필요할경우 make clean 이후에진행한다. $ cd $HOME/iodbc/bin $ file iodbctest iodbctest: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), not stripped 제 1 장 ODBC 연결 11
[ 참고 ] 다음은 OS별로 iodbc 64bit 설치와설치확인방법에대한설명이다. AIX 1. 사전환경점검 export CFLAGS=-maix64 export LDFLAGS="-maix64 -brtl"./configure --prefix=$home/iodbc --disable-gui 2. 컴파일 export OBJECT_MODE=64./make 3. 설치./make install 4. 설치확인 $ file iodbctest iodbctest: 64-bit XCOFF executable or object module not stripped HP(IA64) 1. 사전환경점검 export CFLAGS=+DD64./configure --prefix=$home/iodbc --disable-gui 2. 컴파일./make 3. 설치./make install 4. 설치확인 $ file iodbctest iodbctest: ELF-64 executable object file - IA64 SunOS 1. 사전환경점검 export CFLAGS=-m64./configure --prefix=$home/iodbc --disable-gui 12 Tibero Driver 연결가이드
2. 컴파일./make 3. 설치./make install 4. 설치확인 $ file iodbctest iodbctest: ELF 64-bit MSB executable SPARCV9 Version 1, dynamically linked, not stripped, no debugging information available Linux 1. 사전환경점검 export CFLAGS=-m64./configure --prefix=$home/iodbc --disable-gui 2. 컴파일./make 3. 설치./make install 4. 설치확인 $ file iodbctest iodbctest: ELF 64-bit LSB executable, AMD x86-64, version 1(SYSV), for GNU/Linux 2.6.9, dynamically linked(uses shared libs), not stripped profile 설정 profile 내에아래와같은내용을추가한다. IODBC_HOME 의경우 iodbc 를설치한위치로설정한다. # iodbc setting export IODBC_HOME=$HOME/iodbc export LD_LIBRARY_PATH=$IODBC_HOME/lib:$LD_LIBRARY_PATH export PATH=$IODBC_HOME/bin:$PATHh" 주의 OS 에맞게환경변수 LD_LIBRARY_PATH(Linux), LIBPATH(AIX), SHLIB_PATH(HP) 를설정한다. 제 1 장 ODBC 연결 13
ODBC 환경파일설정및확인 ODBC Driver Manager의환경파일에 Tibero ODBC Driver를등록하는방법이다. 연결테스트전에 Tibero 클라이언트또는서버의설치및관련환경설정이되어야한다. 1. 환경파일위치및이름설정 $HOME/.odbc.ini( 개인설정 ) 또는 /etc/odbc.ini( 공통설정 ) 로설정가능하다. 우선순위는 $HOME/.odbc.ini 가높다. ODBC 환경파일설정방법 [ODBC Data Sources] <ODBC Data Sources> = Tibero5 ODBC driver [ODBC] Trace = 1 TraceFile = /home/tibero/iodbc/tmp/odbc.trace [<ODBC Data Sources 세부설정 >] Driver = <Tibero ODBC Driver 파일 > Description = Tibero5 ODBC Datasource SID = <tbdsn.tbr 파일에설정한 alias 정보 > User = dbtech Password = dbtech 항목 <ODBC Data Sources> <ODBC Data Sources 세부설정 > Driver SID User Password 설명 Datasource 이름으로 Oracle Gateway 설정파일에해당내용이들어간다. ODBC Data Sources에서설정한이름으로대소문자까지일치해야한다. ODBC Manager에서로드하는 Tibero ODBC Driver 파일이다. 해당파일존재여부및권한에대해서확인이필요하다. Tibero 클라이언트또는서버의 tbdsn.tbr 파일에설정한 Alias 정보이다. 사용자를의미한다. 테스트및링크생성의경우별도로사용자를가져가므로크게의미는없다. 사용자패스워드를의미한다. 테스트및링크생성의경우별도로사용자를가져가므로크게의미는없다. ODBC 환경파일설정예 [ODBC Data Sources] tibero5 = Tibero5 ODBC driver [ODBC] 14 Tibero Driver 연결가이드
Trace = 1 TraceFile = /home/tibero/iodbc/tmp/odbc.trace [tibero5] Driver Description SID User Password = /home/tibero/tibero5/client/lib/libtbodbc.so = Tibero5 ODBC Datasource = tibero = dbtech = dbtech 2. 연결테스트 '$IODBC_HOME/bin' 폴더에있는 iodbctest를이용하여연결테스트를수행한다. 테스트에문제가발생하는경우 ODBC 환경파일이름및위치와설정을확인한다. 다음은 iodbctest를이용한연결테스트설정방법이다. iodbctest "DSN=<dsn>;UID=<user>;PWD=<pwd>" 항목 DSN UID, PWD 설명 ODBC 환경파일에서설정한 ODBC Datasources 이름이다. 테스트할접속계정및패스워드이다. 다음은 iodbctest 를이용한연결테스트실행예이다. $ iodbctest "DSN=tibero5;UID=dbtech;PWD=dbtech" iodbc Demonstration program This program shows an interactive SQL processor Driver Manager: 03.52.0709.0909 Driver: 05.00.0204 (libtbodbc.so) SQL>select * from dept; DEPTNO DEPTNAME MGRNO LOCNO -------+------------------------------+---------+------- 100 Administration 2000 2700 200 Marketing 2010 2800 300 Purchasing 1140 2700 400 Human Resources 2030 3400 제 1 장 ODBC 연결 15
1.4. 문제해결 본절에서는특정문제가발생했을때해결하는방법을설명한다. 1.4.1. 로그발생 Tibero ODBC(=tbCLI) 에서는특정환경변수를적용하여로그를발생시키거나글자깨짐등의문제를해결할수있다. 로그를발생하는환경변수의경우일부성능이느려질수있으므로문제가있을때일시적으로만사용한다. 아래처럼환경변수를적용한후에애플리케이션을재기동한다. [ 그림 1.10] ODBC(=tbCLI) 환경변수적용 다음은자주사용하는환경변수에대한설명이다. 환경변수명 TBCLI_LOG_LVL TBCLI_LOG_DIR 설명로그를출력하게하는환경변수이다. trace 값을설정하면로그가출력된다. 로그를생성하는디렉터리를설정한다. 설정하지않을경우아래와같은경로에로그가생성된다. Windows 계열 : C:\tbcli_ 날짜시간.log UNIX 계열 : /tmp/tbcli_ 날짜시간.log 16 Tibero Driver 연결가이드
환경변수명 설명 Windows 7 은 C:\ 디렉터리에파일을생성할때관리자권한이필요하므로 해당경로에로그를생성하려면애플리케이션을관리자권한으로실행한다. TB_NLS_LANG 클라이언트의캐릭터셋을설정하는부분으로기본은 MSWIN949( 한글 ) 로 설정되어있다. 보통은 DB 캐릭터셋과일치시키거나부분집합으로설정하 며설정할수있는값은 DB 캐릭터셋과동일하다. 참고 다른환경변수에대해서는제품매뉴얼 "Tibero 관리자안내서 " 의 "Appendix D. 클라이언트환경 변수 " 를참고한다. 1.5. 예제 본절에서는 ODBC 를이용하여연결하는기본적인형태의예제와특수한타입의예제를설명한다. 1.5.1. 연결예제 다음은 ODBC 를이용한 Windows 환경의연결예제이다. define _DIRECT_ 를주석여부에따라 SQLDriverConnect 와 SQLConnect 중하나를사용해서접속한다. #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <sql.h> #include <sqlext.h> /* #include "stdafx.h" */ #define ROWSET_SIZE 20 #define _DIRECT_ int main(int argc, char* argv[]) { SQLRETURN rc = SQL_SUCCESS; SQLUINTEGER len; SQLHANDLE henv, hdbc, hstmt; SQLCHAR *sql = (SQLCHAR *)"SELECT TO_CHAR(SYSDATE,'YYYYMMDD') FROM DUAL"; char buf[128]; /* Env Handle */ SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); 제 1 장 ODBC 연결 17
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0); SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); /* Tibero Connect */ #ifdef _DIRECT_ // IP, PORT rc = SQLDriverConnect(hdbc, (SQLHWND)NULL, //(SQLCHAR *) "DRIVER={Tibero 4 ODBC Driver};\ SERVER=192.168.70.185;PORT=9629;UID=tibero;PWD=tmax;", (SQLCHAR *) "DRIVER={Tibero 5 ODBC Driver};\ SERVER=192.168.70.185;PORT=9629;DB=t5;UID=dbtech;PWD=dbtech;", SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT); #else // Data Source Name rc = SQLConnect(hdbc, (SQLCHAR *)"t5", SQL_NTS, /* Data Source Name or DB NAME */ (SQLCHAR *)"dbtech", SQL_NTS, /* User */ (SQLCHAR *)"dbtech", SQL_NTS); /* Password */ #endif if (rc!= SQL_SUCCESS) { fprintf(stderr, "Connection failed!!!"); exit(1); } /* Statements Handle */ SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); printf("query: %s\n", sql); /* Execute Query */ rc = SQLExecDirect(hstmt, sql, SQL_NTS); if (rc!= SQL_SUCCESS) { fprintf(stderr, "SQLExecDirect failed!!!"); exit(1); } 18 Tibero Driver 연결가이드
/* Bind Result */ SQLBindCol(hstmt, 1, SQL_C_CHAR, (SQLCHAR *)buf, 128, (long *)&len); printf("result: ", buf); /* Fetch Result */ while(sqlfetch(hstmt)!= SQL_NO_DATA) { printf("%s\n", buf); } /* Release Handle and Close Connection */ SQLFreeStmt(hstmt, SQL_DROP); SQLDisconnect(hdbc); SQLFreeConnect(hdbc); SQLFreeEnv(henv); return 0; } UNIX 계열에서테스트하고싶다면 Tibero 클라이언트또는서버가설치된환경에서위의샘플소스를아래와같이삭제, 추가, 컴파일및링크한다. 아래의경우는 Linux 64bit일때예제이다. 삭제 #include <windows.h> #include <sql.h> #include <sqlext.h> 추가 #include <sqlcli.h> 컴파일및링크 cc -m64 -O -I$TB_HOME/client/include -L$TB_HOME/client/lib -c test.c cc -m64 -O -I$TB_HOME/client/include -o test.bin -L$TB_HOME/client/lib -ltbcli \ -lclialloc test.o 참고 컴파일및링크옵션의경우 OS 에따라일부다를수있다. 강조된부분의경우는동일하고나머지 부분은원래사용하던컴파일및링크옵션을사용한다. 제 1 장 ODBC 연결 19
Autocommit 예제 ODBC 의 Autocommit 관련기본설정은 ON 이다. 애플리케이션에서 OFF 로처리하기위해서는아래와같 이처리한다. #include <windows.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sql.h> #include <sqlext.h> //#include <sqlcli.h> int main() { SQLRETURN rc; SQLHANDLE henv, hdbc, hstmt; SQLCHAR sregno[10], sregname[25]; SQLINTEGER sqlnts=sql_nts; /* Env Handle */ SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&henv); SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION,(void*)SQL_OV_ODBC3,0); SQLAllocHandle(SQL_HANDLE_DBC,henv,&hdbc); // Set Connection Attribute //SQLSetConnectAttr(hdbc,5,(void*)SQL_LOGIN_TIMEOUT,0); /* Tibero Connect */ rc = SQLConnect(hdbc, (SQLCHAR *)"t5", SQL_NTS, /* Data Source Name or DB NAME */ (SQLCHAR *)"dbtech", SQL_NTS, /* User */ (SQLCHAR *)"dbtech", SQL_NTS); /* Password */ if (rc!= SQL_SUCCESS) { printf("connection failed!!! : %d", rc); exit(1); } /* Set AutoCommit ON/OFF */ rc = SQLSetConnectAttr(hdbc,SQL_ATTR_AUTOCOMMIT,(SQLPOINTER)SQL_AUTOCOMMIT_OFF, 0); //rc = SQLSetConnectAttr(hdbc,SQL_ATTR_AUTOCOMMIT,(SQLPOINTER)SQL_AUTOCOMMIT_ON, 0); if (rc!= 0) return NULL; 20 Tibero Driver 연결가이드
/* Statements Handle */ SQLAllocHandle(SQL_HANDLE_STMT,hdbc,&hstmt); /* Execute Query - INSERT */ rc = SQLExecDirect(hstmt,(SQLCHAR *)"INSERT INTO reg VALUES(100,'Seoul')",SQL_NTS); if (rc!= SQL_SUCCESS) { printf("insert Failed!!!"); exit(1); } /* Commit */ // rc = SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT); /* Execute Query - SELECT */ rc = SQLExecDirect(hstmt,(SQLCHAR*)"SELECT * FROM reg",sql_nts); if (rc!= SQL_SUCCESS) { printf(stderr, "Select Failed!!!"); exit(1); } // Fetch printf("%10s%25s\n","regno","regname"); printf("%10s%25s\n","=====","========================"); while( SQLFetch(hstmt)!= SQL_NO_DATA ) { SQLGetData(hstmt,1,SQL_C_CHAR,sRegNo,10,&sqlnts); SQLGetData(hstmt,2,SQL_C_CHAR,sRegName,25,&sqlnts); printf("%10s%25s\n", sregno,sregname); } // while end printf("%10s%25s\n","=====","========================"); /* Release Handle and Close Connection */ SQLFreeStmt(hstmt, SQL_DROP); SQLDisconnect(hdbc); SQLFreeConnect(hdbc); SQLFreeEnv(henv); return 0; } 제 1 장 ODBC 연결 21
1.5.2. 타입관련예제 다음은 CLOB 을이용한특수한타입의예제이다. // $gcc test_clob.c -I$TB_HOME/client/include -L$TB_HOME/client/lib -ltbcli // a.out DSN USERNAME PASSWORD #include <stdio.h> #include <assert.h> #include "sqlcli.h" SQLRETURN _rc = SQL_SUCCESS; SQLHANDLE _henv = SQL_NULL_HANDLE; SQLHANDLE _hdbc = SQL_NULL_HANDLE; SQLHANDLE _hstmt = SQL_NULL_HANDLE; SQLCHAR *DSN = NULL; SQLCHAR *UID = NULL; SQLCHAR *PWD = NULL; int main(int argc, char **argv) { SQLINTEGER lob_loc = 0; SQLLEN ind = 0; SQLLEN lob_ind = 0; SQLINTEGER byte_len = 0; SQLBIGINT lob_len = 0; SQLCHAR lob_char[10+1]; // 버퍼크기 (10)+ 널텀 (1) // 읽어들일글자수, 버퍼크기가 10 이므로 5 로설정 SQLINTEGER read_char_len = 5; SQLINTEGER sqlnts=sql_nts; int offset = 1; // 여러번나누어가져올때의 offset int lob_length; _rc = SQLAllocEnv(&_henv); _rc = SQLAllocConnect(_henv, &_hdbc); DSN = (SQLCHAR *)argv[1]; UID = (SQLCHAR *)argv[2]; PWD = (SQLCHAR *)argv[3]; _rc = SQLConnect(_hdbc, DSN, SQL_NTS, UID, SQL_NTS, PWD, SQL_NTS); _rc = SQLAllocStmt(_hdbc, &_hstmt); 22 Tibero Driver 연결가이드
_rc = SQLExecDirect(_hstmt, (SQLCHAR *)"DROP TABLE T", SQL_NTS); _rc = SQLExecDirect(_hstmt, (SQLCHAR *)"CREATE TABLE T(C1 CLOB)", SQL_NTS); _rc = SQLExecDirect(_hstmt, (SQLCHAR *)"DELETE FROM T", SQL_NTS); _rc = SQLExecDirect(_hstmt, (SQLCHAR *)"INSERT INTO T VALUES (NULL)", SQL_NTS); _rc = SQLEndTran(SQL_HANDLE_DBC, _hdbc, SQL_COMMIT); _rc = SQLFreeStmt(_hstmt, SQL_RESET_PARAMS); /* Case 1 */ _rc = SQLExecDirect(_hstmt, (SQLCHAR *)"SELECT * FROM T", SQL_NTS); _rc = SQLFetch(_hstmt); /* must be return SQL_SUCCESS with SQL_NULL_DATA indicator value * at first invocation */ _rc = SQLGetData(_hstmt, 1, SQL_C_CHAR, NULL, 0, &ind); /* c1컬럼 (clob) 이 null인지확인. null이면 indicator가 SQL_NULL_DATA */ if (ind == SQL_NULL_DATA) { printf("case1: lob : null\n"); } /* must be return SQL_NO_DATA at second invocation*/ _rc = SQLGetData(_hstmt, 1, SQL_C_CHAR, NULL, 0, &ind); assert(_rc == SQL_NO_DATA); _rc = SQLCloseCursor(_hstmt); _rc = SQLFreeStmt(_hstmt, SQL_DROP); /* Case 2 : lob locator 사용 */ ind = 0; _rc = SQLAllocStmt(_hdbc, &_hstmt); _rc = SQLExecDirect(_hstmt, (SQLCHAR *)"DELETE FROM T", SQL_NTS); _rc = SQLExecDirect(_hstmt, (SQLCHAR *)"INSERT INTO T \ VALUES (' 티맥스소프트 abc 티베로입니다.')", SQL_NTS); _rc = SQLExecDirect(_hstmt, (SQLCHAR *)"SELECT * FROM T", SQL_NTS); _rc = SQLBindCol(_hstmt, 1, SQL_C_CLOB_LOCATOR, \ (SQLPOINTER)&lob_loc, 0, &ind); _rc = SQLFetch(_hstmt); // c1이 null이아니면 lob_loc이여기서채워짐 /* 해당 lob 데이터가 NULL인지확인 */ if (ind == SQL_NULL_DATA) { printf("case2 : lob : null\n"); } else { _rc = SQLLobGetLength(_hstmt, lob_loc, &lob_len, NULL); 제 1 장 ODBC 연결 23
printf("case2(lob_len) : lob len : %lld\n", lob_len); /* SQLRETURN SQL_API SQLLobGetData2(SQLHSTMT StatementHandle, SQLINTEGER Locator, // 1부터시작, 문자수의미의 offset, 여러번호출시값변경필요 SQLBIGINT Offset, SQLINTEGER *ReadLength, // 읽어들일문자수 SQLSMALLINT TargetCType, SQLPOINTER DataPtr, SQLINTEGER BufferLength, // 버퍼크기 SQLLEN *Indicator) */ while (1) { if( read_char_len > lob_len ) read_char_len = lob_len; _rc = SQLLobGetData2(_hstmt, lob_loc, offset, &read_char_len \, SQL_C_CHAR,lob_char, sizeof(lob_char),&lob_ind); if (!SQL_SUCCEEDED(_rc) lob_ind <= 0) break; offset += read_char_len; lob_len -= read_char_len; }// while end printf("length of writing buffer : %lld\n", lob_ind); printf("lob data : %s\n", lob_char); } //_rc = SQLExecDirect(_hstmt, (SQLCHAR *)"DROP TABLE T", SQL_NTS); _rc = SQLDisconnect(_hdbc); _rc = SQLFreeConnect(_hdbc); _rc = SQLFreeEnv(_henv); } return 0; 24 Tibero Driver 연결가이드
제 2 장 OLE DB 연결 본장에서는 OLE DB 에대한개념과기능, Tibero OLE DB Provider 설치및구성에대해서설명한다. 2.1. OLE DB 개념 ODBC는응용프로그램이데이터베이스를일정한방식으로액세스하는방법을제공하였다. 언어, 테이블구조, 내부정보등에관계없이데이터베이스를액세스하는공통의추상적인 API를제공했지만 IT기술이발전함에따라새로운방식으로 DB기반응용프로그램을설계하고구축하는상황에 ODBC는부적합하게되어 OLE DB라는새로운개방형 DB 연결방식이생겨났다. OLE DB는 Microsoft UDA(Universal Data Access) 의개념을구체화한프로그래밍인터페이스모델이다. UDA는단일 COM 기반프로그래밍인터페이스를사용하여관계형, 비관계형, 계층형등과같은모든유형의데이터를액세스할수있는기능을제공한다. Tibero OLE DB Provider는현재 Windows 운영체제만을지원한다. Tibero OLE DB Provider는 ADO 또는 OLE DB 기반애플리케이션이 Tibero 데이터베이스에접근하는환경의성능및안정성을보장한다. Tibero OLE DB Provider가최신 OLE DB 및 ADO 스펙과호환하므로 ADO, OLE DB 개발자는 Tibero 환경으로의애플리케이션마이그레이션작업을쉽고간단하게수행할수있다. 또 Tibero OLE DB Provider는 PSM 저장프로시저, LOB 등 Tibero 환경이제공하는기능을활용하는것을가능하게하며 Microsoft OLE DB.NET data provider를통해.net 환경을완벽하게지원한다. OLE DB.NET을사용하는경우모든종류의.NET 프로그래밍언어를사용하여 Tibero 데이터베이스에접근할수있다. 2.1.1. OLE DB 의역할 기본적으로분산되어있는데이터들에대한통합된 view를제공하는역할을한다. 아래그램처럼 UDA 기술은 ADO와 OLEDB를사용하여 SQL 데이터뿐만아니라비 SQL적인데이터 ( 메일, 텍스트, 디렉터리서비스등 ) 에도접근가능하고 OLE DB가기존의 ODBC를이용한데이터연결도사용할수있게되어있다. OLE DB를통한접근은기존의 ODBC가부족했던점을보완하여접근속도또한많은향상을가져왔다. 제 2 장 OLE DB 연결 25
[ 그림 2.1] UDA Architecture ( 출처 ) 마이크로소프트 2.1.2. OLE DB 내부구조 OLE DB 내부구조및각항목에해당하는설명은아래와같다. Data Source OLE DB provider 초기화및환경구축을하고접속정보를받아한개이상의연결 (Session) 을생성한다. Session 하나의연결단위로일반적으로한개이상의명령문 (Command) 을생성하고, 직접적으로한개이상의결과테이블 (Rowset) 을생성한다. Command SQL 문장실행의단위로 SELECT 문일경우한개이상의 Rowset을생성한다. Rowset 쿼리에의해서버로부터가져온데이터들의집합으로순방향, 역방향, 특정위치 row 접근을지원한다. 26 Tibero Driver 연결가이드
[ 그림 2.2] OLE DB 내부구조 2.1.3. OLE DB 기능 OLE DB 의몇가지특징적인기능들에대해서살펴본다. Updatable Cursor 쿼리의결과테이블의데이터를직접수정하여서버에반영시키는기능이다. 기본적으로 rowid를추가로쿼리에첨부하여보내고 rowid를붙일수없는쿼리는 Updatable Cursor가될수없다. 추가, 삭제, 수정모두내부적으로 rowid를이용한 DML로작성되어서버로보내진다. Updatable Cursor의기능들은다음과같다. 새로운 Row 추가 : 추가된 row는결과테이블에저장되지않는다. 기존 Row를삭제 : 삭제된 row는삭제되었다고표시만해놓는다. 기존 Row의데이터를수정 : 수정된데이터는바로조회가가능하다. 다음은 Updatable Cursor 의사용예제 (PHP) 이다. $conn = new COM("ADODB.Connection"); $conn->open("provider=tbprov.tbprov.5; Data Source=t5; User ID=dbtecj; Password=dbtech;Updatable Cursor=True; ); $rs = new COM("ADODB.Recordset"); $rs->cursorlocation = aduseserver; $rs->open("for_member", $conn, adopenkeyset, adlockpessimistic, adcmdtable); $rs->movenext(); $rs->fields("email")->value = "test@tibero.com"; $rs->fields("password")->value = "tmax123"; 제 2 장 OLE DB 연결 27
$rs->fields("name")->value = TESTUSER ; $rs->update(); $rs->close(); Schema Rowset DB의스키마정보 ( 테이블, 프로시저등 ) 를테이블형태로알려주는기능으로대부분내부적으로 DB의 static view를조회하여해당정보들을추출한다. DB접근이필요없는경우 OLE DB단에서해당스키마정보를저장하고있다가추출하고 Power Builder, Report Designer 등의툴로 Schema Rowset을통하여각종테이블, 뷰, 인덱스등의정보를가져와활용한다. Schema Rowset이지원하는항목들은다음과같다. TABLES VIEWS COLUMNS INDEXES PRIMARY_KEYS PROCEDURES PROCEDURE_PARAMETERS PROVIDER_TYPES CATALOGS( 빈결과물리턴 ) 지원되지않지만필요한 Schema 종류일경우요청에의해지속적으로추가한다. 다음은 Schema Rowset 의사용예제 (PHP) 이다. $conn = new COM("ADODB.Connection"); $conn->open( Provider=tbprov.Tbprov.5; ); $arr[0] = ""; $arr[1] = "dbtech"; $arr[2] = "EMP"; $rs = new COM("ADODB.Recordset"); $rs->cursorlocation = aduseclient; $rs = $conn->openschema(adschemaprimarykeys, $arr); Connection Pooling 동일한계정으로반복연결을할경우기존의연결을닫지않고저장해두었다가재사용하는기능이다. 연 결하는데드는시간을절약하는효과가있다. 28 Tibero Driver 연결가이드
Connection Pooling의설정방법은다음과같다. 연결문자열에 OLE DB Services 항목을추가한다. OLE DB Services=-1 : 풀링을사용한다. OLE DB Services=-2 : 풀링을사용하지않는다. PHP의경우무조건사용하도록설정된다. 2.2. Tibero OLE DB Provider 설치및구성 Tibero OLE DB의경우내부적으로 Tibero ODBC를사용하므로 OLE DB를설치한다면앞장의 ODBC 내용을참조하여미리설치를한다. 만약 32bit OLE DB를사용한다면 32bit ODBC를설치하고 64bit OLE DB를사용한다면 64bit ODBC를설치한다. 본절에서는 OLE DB의설치파일과 OLE DB Provider 등록및연결하는방법에대해서설명한다. 기본적으로 32bit 클라이언트 OS 환경에서는 32bit OLE DB 설치, 64bit 클라이언트 OS 환경에서는 64bit OLE DB 설치방법을설명하며 64bit 클라이언트 OS환경에서 32bit OLE DB를설치하는방법은 2.2.4. Windows 64bit에 32bit OLE DB 설치 를참고한다. 2.2.1. OLE DB 설치파일 클라이언트인스톨러나 OLEDB 인스톨러의경우 GUI 환경으로설치및등록을자동으로진행할수있다. 만약수동으로진행하려면 Tibero 서버가설치된환경에서설치하고자하는클라이언트에맞게설치파일을가져온다. 바이너리위치에관한자세한내용은 1.2.1. ODBC 설치파일 " 를참고한다. 다음은바이너리파일에대한설명이다. 파일명 tbprov5.dll msdtb5.dll Tibero.DbAccess.dll EntLibContrib.Da ta.tibero.dll 설명 OraOLEDB의데이터타입 spec을맞춘바이너리로 Provider를등록할때사용한다. MSDAORA의데이터타입 spec을맞춘바이너리로 Provider를등록할때사용한다..Net 환경에서의지원을위해추가된바이너리로.NET을연동할때사용한다. MS Enterprise Library 지원을위해추가된바이너리로 MS Enterprise Library 를연동할때사용한다. 참고 1. Tibero 5 r67771 이전버전의경우 tbprov.dll, msdtb.dll 파일을사용한다. 2. 확장자가 pdb(program Database) 인경우는디버깅작업을위해서사용하는파일이다. 릴리즈버전에따라포함되어있지않는경우도있다. 제 2 장 OLE DB 연결 29
2.2.2. OLE DB Provider 등록 OLE DB Provider 등록순서는다음과같다. 1. 바이너리복사 Tibero 버전에따라 OLE DB 바이너리를복사하는위치가다르다. 버전에맞게 OLE DB 바이너리를위치한다. Tibero 4 SP1 및이전버전 %WINDIR%\system32( 예 : c:\windows\system32) Tibero 5 이상임의의위치로가능하다. 단, 미리설치된 ODBC 바이너리가있는디렉터리에위치해야한다. 2. Provider 등록및해제 등록 command 창을열어 OLE DB 바이너리를위치한곳으로이동한후명령어를실행한다. 만약 Windows 7 이상일경우 command 창을관리자권한으로실행한다. 등록방법 regsvr32 <dllname> 항목 <dllname> 설명 등록할 dll 파일명을입력한다. Tibero 4 SP1 또는 Tibero 5 r67770 이전 tbprov.dll : OraOLEDB의데이터타입 spec msdtb.dll : MSDAORA의데이터타입 spec Tibero 5 r67770 이후 tbprov5.dll : OraOLEDB의데이터타입 spec msdtb5.dll : MSDAORA의데이터타입 spec 등록예 c:\tmaxsoft\win64>regsvr32 tbprov5.dll c:\tmaxsoft\win64>regsvr32 msdtb5.dll 30 Tibero Driver 연결가이드
등록을하면아래와같은팝업창이나타난다. [ 그림 2.3] OLE DB 등록팝업 해제 Provider 해제가필요한경우아래와같이수행한다. 만약 Windows 7 이상일경우 command 창을관리자권한으로실행한다. 해제방법 regsvr32 /u <dllname> 항목 <dllname> 설명 기존에이미등록이된 dll 파일중에서해제할 dll 파일명을입력한다. Tibero 4 SP1 또는 Tibero 5 r67770 이전 tbprov.dll : OraOLEDB의데이터타입 spec msdtb.dll : MSDAORA의데이터타입 spec Tibero 5 r67770 이후 tbprov5.dll : OraOLEDB의데이터타입 spec msdtb5.dll : MSDAORA의데이터타입 spec 해제예 c:\tmaxsoft\win64>regsvr32 /u tbprov5.dll c:\tmaxsoft\win64>regsvr32 /u msdtb5.dll 제 2 장 OLE DB 연결 31
3. Provider 등록확인 바탕화면에 tibero.udl 파일을새로생성한다. [ 그림 2.4] udl 파일생성 생성한 tibero.udl 파일을더블클릭한후 [Provider] 탭을선택하면 Tibero OLE DB Provider 를확인할 수있다. [ 그림 2.5] OLE DB 등록확인 32 Tibero Driver 연결가이드
2.2.3. OLE DB 연결 Tibero OLE DB 를사용하는애플리케이션에서연결문자열 (Connection String) 을사용하는방식과 Provider 테스트방식에대해서설명한다. 연결문자열을사용하는방식 사용방법 Provider=< 공급자이름 >;Data Source=< 데이터원본이름 >;User ID=< 접속사용자 ID>; Password=< 접속패스워드 >;Updatable Cursor=<Updateable Cursor 사용여부 >; OLE DB Services=<Connection Pooling 사용여부 > 항목 < 공급자이름 > 설명 Tibero 버전및리비전에따라공급자이름이조금씩다르다. Tibero 4 SP1 또는 Tibero 5 r67770 이전 tbprov.tbprov 또는 tbprov.tbprov.1 : OraOLEDB의데이터타입 spec tbprov.msdtb 또는 tbprov.msdtb.1 : MSDAORA의데이터타입 spec Tibero 5 r67770 이후 (Tibero 4, Tibero 5 용 OLE DB를같은클라이언트에서동시에사용하기위해서는해당리비전이후를사용한다 ) tbprov.tbprov 또는 tbprov.tbprov.5 : OraOLEDB의데이터타입 spec tbprov.msdtb 또는 tbprov.msdtb.5 : MSDAORA의데이터타입 spec < 데이터원본이름 > 데이터원본이름에는아래와같은항목이있다. 단, Tibero 버전에따라일부 다른정보가들어가기도한다. ODBC 데이터원본관리자에등록된이름 IP, PORT(Tibero 4 SP1) 또는 IP, PORT, DBNAME(Tibero 5) < 접속사용자 ID> < 접속패스워드 > Tibero 서버에접속할사용자이름이다. Tibero 서버에접속할패스워드이다. <Updateable Cursor 사용 Updatable Cursor 사용여부를설정한다. ( 기본값 : False) 여부 > True : 사용한다. False: 사용하지않는다. <Connection Pooling 사 용여부 > Connection Pooling 기능사용여부를설정한다. ( 기본값 : -1) -1 : 사용한다. -2 : 사용하지않는다. 제 2 장 OLE DB 연결 33
사용예 Provider=tbprov.Tbprov.5;Data Source=t5;User ID=dbtech;Password=dbtech; Updatable Cursor=True;OLE DB Services=-2 Provider 테스트 앞절에서만든 tibero.udl 파일로연결테스트를할수있으며아래와같이 2가지방식으로가능하다. IP, PORT 등의정보를이용한직접연결방식데이터원본에 IP, PORT, DB NAME 순으로설정하여접속한다. ( 예 : 192.168.70.185,8629,t5) 만약 Tibero 4 SP1 및이전버전의경우 DB NAME 정보없이 IP, PORT만으로접속이가능하다. ( 예 : 192.168.70.185,8629) [ 그림 2.6] OLE DB 직접연결방식 ODBC 원본관리자의 DSN 또는 tbdsn.tbr의 Alias를이용한방식데이터원본에 ODBC 원본관리자의 DSN 또는 "$TB_HOME/client/config/tbdsn.tbr" 의 Alias를이용하여 Tibero에접속이가능하다. 해당 Alias 정보를찾는방법은 [ODBC 원본관리자 ] > [tbdsn.tbr의 Alias] 순서대로찾는다. 34 Tibero Driver 연결가이드
[ 그림 2.7] OLE DB DSN 이용방식 참고 ODBC 원본관리자등록방법은 1.2.3. ODBC 연결 의 "DSN 을등록하는방식 " 을참고한다. 아래와같이테스트버튼을눌러서정상접속되는지확인한다. [ 그림 2.8] OLE DB 연결테스트 제 2 장 OLE DB 연결 35
2.2.4. Windows 64bit 에 32bit OLE DB 설치 32bit ODBC가미리설치된후진행해야한다. 1. 바이너리복사 Tibero 버전에따라 OLE DB 바이너리를복사하는위치가다르다. 버전에맞게 OLE DB 바이너리를위치한다. Tibero 4 SP1 및이전버전 %WINDIR%\SysWOW64( 예 : c:\windows\syswow64) Tibero 5 이상임의의위치로가능하다. 단, 미리설치된 32bit ODBC 바이너리가있는디렉터리에위치해야한다. 2. Provider 등록및해제 등록 command 창을열어 "%WINDIR%\SysWOW64" 폴더로이동한후명령어를실행한다. 만약 Windows 7 이상일경우 command 창을관리자권한으로실행한다. 등록방법 regsvr32.exe <dllname> 항목 <dllname> 설명 등록할 32bit dll 파일의위치를절대경로로입력한다. Tibero 4 SP1 또는 Tibero 5 r67770 이전 tbprov.dll : OraOLEDB의데이터타입 spec msdtb.dll : MSDAORA의데이터타입 spec Tibero 5 r67770 이후 tbprov5.dll : OraOLEDB의데이터타입 spec msdtb5.dll : MSDAORA의데이터타입 spec 등록예 c:\windows\system32>cd %WINDIR%\SysWOW64 c:\windows\syswow64>regsvr32.exe c:\tmaxsoft\win32\tbprov5.dll c:\windows\syswow64>regsvr32.exe c:\tmaxsoft\win32\msdtb5.dll 36 Tibero Driver 연결가이드
해제 command 창을열어 "%WINDIR%\SysWOW64" 폴더로이동한후명령어를실행한다. 만약 Windows 7 이상일경우 command 창을관리자권한으로실행한다. 해제방법 regsvr32.exe /u <dllname> 항목 <dllname> 설명 해제할 32bit dll 파일의위치를절대경로로입력한다. Tibero 4 SP1 또는 Tibero 5 r67770 이전 tbprov.dll : OraOLEDB의데이터타입 spec msdtb.dll : MSDAORA의데이터타입 spec Tibero 5 r67770 이후 tbprov5.dll : OraOLEDB의데이터타입 spec msdtb5.dll : MSDAORA의데이터타입 spec 해제예 c:\windows\system32>cd %WINDIR%\SysWOW64 c:\windows\syswow64>regsvr32.exe /u c:\tmaxsoft\win32\tbprov5.dll c:\windows\syswow64>regsvr32.exe /u c:\tmaxsoft\win32\msdtb5.dll 3. Provider 등록확인 Provider 등록확인은아래와같은순서로진행한다. a. C:\ 디렉터리에 tibero.udl 파일을생성한다. b. command 창을열고 rundll32.exe 명령어를실행한다. 명령어를실제사용할때는한줄로입력한다. 사용방법 C:\Windows\syswow64\rundll32.exe "C:\Program Files (x86)\common Files\System\Ole DB\oledb32.dll",OpenDSLFile <udl 파일 > 항목 <udl 파일 > 설명 C:\ 디렉터리에생성한 udl 파일의경로및파일명을입력한다. 사용예 제 2 장 OLE DB 연결 37
C:\Windows\syswow64\rundll32.exe "C:\Program Files (x86)\common Files\System\Ole DB\oledb32.dll",OpenDSLFile C:\tibero.udl c. Provider 가등록된것을확인한다. [ 그림 2.9] 32bit 용 OLE DB 등록확인 4. OLE DB 연결 OLE DB 연결에대한자세한내용은 2.2.3. OLE DB 연결 을참고한다. 2.3. Tibero OLE DB 연동 OLE DB 를사용하는인터페이스에대하여연동하는방법을설명한다. 해당인터페이스를사용하는서버에미리 Tibero OLE DB 가설치되어야한다. 2.3.1. ADO(ActiveX Data Objects) Microsoft사에서개발한데이터베이스연동용인터페이스로 ADO 컴포넌트를사용해데이터페이스에접근후여러작업을할수있다. 데이터베이스에접근하기위한 COM 객체들의모음이다. 사용자의프로그래밍언어와 OLE DB사이를연결하는계층이다. 38 Tibero Driver 연결가이드
Windows 운영체제를설치할때자동으로설치된다. ASP, PHP, VB 등의환경에서사용가능하다. 사용자가복잡한 OLE DB API 대신 ADO의단순화된 API로용이하게개발이가능하다. 각종 Script 언어와연동되어있으므로다양한환경에서의개발이가능하다. 다음은 ADO 에서사용하는주요객체이다. Connection 데이터베이스를연결할때사용하는객체이다. Set conn=server.createobject( ADODB.Connection ); Recordset 조회쿼리를보내그쿼리결과를받을때사용한다. Set rs = Server.CreateObject( ADODB.Recordset ) rs.open select * from emp,conn Command 이객체만데이터베이스연결, 명령, 쿼리실행등이가능하고주로프로시저실행이나매개변수가포함 된쿼리를실행할때사용한다. Set Cmd = Server.CreateObject("ADODB.Command") with Cmd.ActiveConnection = objconn.commandtype = adcmdstoredproc.commandtext = "ADD" End with Set Cmd = Nothing Transaction 트랜잭션을처리할때사용트랜잭션은 Connection 객체의.BeginTrans 와.CommitTrans 메소드호출 사이에존재한다. myconnection.begintrans While Not myrecordset.eof mcounter = mcounter + 1 myrecordset.update myrecordset.movenext Wend myconnection.committrans 제 2 장 OLE DB 연결 39
myrecordset.close myconnection.close Property ADO 객체의동적인속성을가지고있다. set prop=server.createobject("adodb.property") for each prop in rs.properties response.write("attr:" & prop.attributes & "<br>") response.write("name:" & prop.name & "<br>") response.write("value:" & prop.value & "<br>") next Field ADO Field 객체는 Recordset 객체의컬럼에대한정보를가지고있다. set f=server.createobject("adodb.field") for each f in rs.fields response.write("attr:" & f.attributes & "<br>") response.write("name:" & f.name & "<br>") response.write("value:" & f.value & "<br>") Next Parameter Stored Procedure 또는쿼리에서사용되는파라미터의정보를제공한다. ( 파라미터타입 : input,output, input/output, return) set comm=server.createobject("adodb.command") set para=server.createobject("adodb.parameter") para.type=advarchar para.size=20 para.direction=adparaminput para.value=username comm.parameters.append para Error 실행할때발생한에러를 Errors collection 에저장한다. for each objerr in objconn.errors response.write("<p>") response.write("description: ") 40 Tibero Driver 연결가이드
response.write(objerr.description & "<br>") response.write("help context: ") response.write(objerr.helpcontext & "<br>") response.write("help file: ") response.write(objerr.helpfile & "<br>") response.write("native error: ") response.write(objerr.nativeerror & "<br>") response.write("error number: ") response.write(objerr.number & "<br>") response.write("error source: ") response.write(objerr.source & "<br>") response.write("sql state: ") response.write(objerr.sqlstate & "<br>") response.write("</p>") next Record Recordset, directory, file 에서하나의행 (row) 을가리킨다. countfields=rec.fields.count Cursor Location 다음은 Cursor 서비스위치를가르키는속성값이며 Connection 또는 Recordset 단위로설정가능하다. 속성값 adusenode 설명 OBSOLETE( 하위호환을위해서만존재한다 ) Value 1 aduseserver 사용자가 row 를이동할때마다 OLE DB 로부터조금씩데이터를가져오는방식으 로 row 를일부만가져올경우 ( 전체메모리사용량이적음 ) 에유리하고접속을끊 은후에는데이터를가져올수없다. Updatable Cursor 가지원된다. Value 2( 기본값 ) aduseclient OLE DB 로부터전체데이터를가져와 ADO 단에서저장해두었다가 ADO 함수를 통하여 row 를이동할때바로꺼내어쓰는방식으로이미필요한데이터를가져온 상태이므로접속을끊어도데이터에접근이가능하다. Updatable Cursor 는지원되지않는다. Value 3 제 2 장 OLE DB 연결 41
사용예제 (ado_query.vbs) 다음은 ADO 를사용하는 VBScript 예제이다. Dim conn, rs, sql Set conn = CreateObject("ADODB.Connection") conn.open "Provider=tbprov.Tbprov.5;Data Source=t5;User ID=dbtech;Password=dbtech;" conn.cursorlocation = aduseclient 'aduseserver = 2, aduseclient = 3 Set rs = CreateObject("ADODB.RecordSet") sql = "select sysdate from dual" rs.open sql, conn While Not rs.eof WScript.Echo rs("sysdate") rs.movenext Wend rs.close() Set rs = Nothing Set conn = Nothing 2.3.2. ADO.NET ADO.NET은.NET 개발자에게데이터액세스서비스를노출하는클래스집합이며.NET 응용프로그램은 ADO.NET을통해데이터소스에연결하여데이터를검색, 조작및업데이트할수있다. 기존의 ADO와비교할때 ADO.Net은확장성과상호운영성이개선된 ADO이다. XML을보편적인데이터전송형식으로사용한다. C#, C++, VB.NET을지원한다. 다음은 ADO.NET 에서사용하는주요객체이다. 객체 Connection Command DataReader DataAdapter 설명가장먼저사용되는개체로데이터원본에대한기본적인연결을제공한다. 데이터베이스에수행하는명령 ("select * from emp") 을대표한다. OLE DB인경우 OleDbCommand이다. 데이터원본으로부터 forward only, read only 등의데이터를빠르고손쉽게얻을수있는개체이다. 단순히데이터를읽는경우라면이개체가가장좋은성능을낸다. OLE DB인경우 OleDbDataReader이다. 데이터원본에대한다양한작업 ( 갱신, DataSet 채우기 ) 을수행하는법용적인클래스이다. OLE DB인경우 OleDbDataAdapter이다. 42 Tibero Driver 연결가이드
객체 DataSet 설명응용프로그램안에서하나의단위로참조되는관련된테이블들의집합을대표한다. 예를들어 Customers, Orders, Products의모든고객들과그들이주문한제품들은하나의 DataSet에담기는것이가능하고이개체를이용하여원하는데이터를각테이블로부터빨리가져와서버와연결이끊어진상태에서데이터를변경하고한번의명령으로변경된것들을데이터베이스서버에저장할수있다. 네임스페이스의사용 C# 에서사용한다는가정하에공급자에따른네임스페이스사용법이다 ADO.NET 클래스들이있는 System.Data NameSpace 에참조를정의한다. using System.Data; OLE DB.NET 공급자를위한 using 문이다. using System.Data.OleDb; Tibero.Net 공급자를위한 using 문이다 using Tibero.DbAccess; SQL Server.Net 공급자를위한 using 문이다. using System.Data.SqlClient; Oracle 전용 Data Provider for.net 의경우 using 문이다. using System.Data.OracleClient; 사용예제 (test_oledb.cs) 다음은 ADO.NET 를사용하는 C# 예제이다. class Class1 { static void Main(string[] args) { Class1 c1 = new Class1(args); } public Class1(string[] args) { OleDbConnection conn = new OleDbConnection("Provider=tbprov.Tbprov; ); conn.open(); OleDbCommand cmd = new OleDbCommand(); cmd.connection = conn; cmd.commandtext = "select * from test order by a"; 제 2 장 OLE DB 연결 43
OleDbDataAdapter oda = new OleDbDataAdapter(cmd); DataSet dset = new DataSet(); oda.fill(dset); DataTable table = dset.tables[0]; DataRow[] rows = table.select(); Console.WriteLine(rows[0][ c1"].tostring()); } } conn.close(); 2.3.3. Enterprise Library 연동 Enterprise Library 는 MS 에서제공하는오픈소스프레임워크이다. Enterprise Library 에대한자세한내용 은 http://msdn.microsoft.com/en-us/library/ff632023.aspx 을참고한다. Tibero OLE DB 및 Enterprise Library가설치되었다면연동순서는아래와같다. 1. 프로젝트내에 Tibero DLL 파일추가 Visual Studio의프로젝트내에서 [Add Reference] > [Browse] 탭에서 Tibero.DbAccess.dll, EntLibCon trib.data.tibero.dll을선택한다. [ 그림 2.10] Visual Studio 에 Tibero DLL 참조추가 2. 소스내에네임스페이스추가 필요할경우소스내에아래와같이네임스페이스를추가한다. using Tibero.DbAccess; using EntLibContrib.Data.Tibero; 44 Tibero Driver 연결가이드
3. 관련설정추가 Enterprise Library 의설정파일에 Tibero OLE DB 에관련내용을설정한다. 아내내용중에설정정보 중에 <providermappings>, <connectionstrings> 부분을참조한다. <configuration> <configsections> <section name="dataconfiguration" type="microsoft.practices.enterpriselibrary.data... 생략 " /> </configsections> <dataconfiguration defaultdatabase="tibero"> <providermappings> <add databasetype= "EntLibContrib.Data.Tibero.TiberoDatabase,EntLibContrib.Data.Tibero, Version=1.0.0.0,Culture=neutral, PublicKeyToken=null" name="tibero.dbaccess" /> </providermappings> </dataconfiguration> <connectionstrings> <add name="tibero" connectionstring="provider=tbprov.tbprov.5;data Source=t5 ;User ID=dbtech;Password=dbtech;Pooling=True ;Max Pool Size=50;Min Pool Size=2;Connection Lifetime=0" providername="tibero.dbaccess" /> </connectionstrings> </configuration> 참고 1. <add databasetype="entlibcontrib.data~" 부분은한줄로작성한다. 2. <connectionstrings> 부분은고객사상황에맞게적용한다. 2.4. OLE DB 전환 본절에서는 Oracle OLE DB 를전환하는내용과예제를설명한다. 2.4.1. Oracle OLE DB 오브젝트를변경할때다음을참고한다. Oracle OracleConnection OracleCommand Tibero OleDbConnectionTbr OleDbCommandTbr 제 2 장 OLE DB 연결 45
Oracle OracleDataReader OracleDataAdapter OracleDbType OracleParameter OracleCommandBuilder OracleTransaction OracleLob Tibero OleDbDataReader OleDbDataAdapterTbr OleDbTypeTbr OleDbParameterTbr OleDbCommandBuilderTbr OleDbTransaction OleDbYpeTbr.LongVarChar(CLOB 대응 ) 또는 OleDbTypeTbr.LongVarBina ry(blob 대응 ) 사용방법은 reader 에서읽은후 GetString 으로읽어들인다. ( 예 : if (reader.read()) { string clob = reader.getstring(0);.. }) 소스변경예제 다음은 Cursor에관련된예제이다. 예제1 Oracle selectcmd.parameters.add("rs_lst", OracleDbType.RefCursor).Direction \ = ParameterDirection.Output; Tibero OleDbCommandTbr selectcmd = new OleDbCommandTbr(); selectcmd.connection = oconn; selectcmd.commandtype = CommandType.StoredProcedure; selectcmd.commandtext = "PKG.Get_List"; selectcmd.parameters.add("rs_lst", OleDbTypeTbr.Cursor).Direction \ = ParameterDirection.Output; 예제2 Oracle OracleParameter a = new OracleParameter("i_fromdate", fromdate); a.direction = ParameterDirection.Input; a.oracletype = OracleType.VarChar; 46 Tibero Driver 연결가이드
OracleParameter b = new OracleParameter ("o_rc", DBNull.Value); b.direction = ParameterDirection.Output; b.oracletype = OracleType.RefCursor; selectcmd.parameters.add(a); selectcmd.parameters.add(b); Tibero OleDbParameterTbr a = new OleDbParameterTbr("i_fromdate", fromdate); a.direction = ParameterDirection.Input; a.oledbtype = OleDbTypeTbr.VarChar; OleDbParameterTbr b = new OleDbParameterTbr("o_rc", DBNull.Value); b.direction = ParameterDirection.Output; b.oledbtype = OleDbTypeTbr.Cursor; selectcmd.parameters.add(a); selectcmd.parameters.add(b); Named Parameter 기능 (.NET Tibero OLE DB provider 에서지원 ) Tibero 에서 Named Parameter 기능을사용한예제이다. OleDbCommandTbr ocmd = new OleDbCommandTbr(); ocmd.connection = oconn; ocmd.commandtype = CommandType.Text; ocmd.commandtext = "insert into aaa(aa,bb) values (:aa,:bb)"; ocmd.parameters.add(new OleDbParameterTbr("bb", "bb")); ocmd.parameters.add(new OleDbParameterTbr("aa", "aa")); 2.5. 문제해결 특정문제가발생했을때해결하는방법을설명한다. 2.5.1. 로그발생 문제가발생할경우 Tibero OLE DB에서특정환경변수를적용하여로그를발생한다. 로그를발생시키는환경변수의경우일부성능이느려질수있다. 따라서문제가있을때일시적으로만사용한다. 참고로 Tibero OLE DB 경우는내부적으로 Tibero ODBC를사용하므로 ODBC 환경변수를적용하여발생한로그, OLE DB 로그를함께발생시킨다. 제 2 장 OLE DB 연결 47
환경변수명 TB_OLEDB_LOG 설명 로그를출력하게하는환경변수이다. 아래와같은값을설정가능하다. (3 또는 4를주로설정한다 ) 1 : API 주요함수 2 : 1 + API 비주요함수 3 : 2 + 내부함수 4 : 동적메모리할당및해제 TB_OLEDB_LOG_DIR 로그를생성하는디렉터리를설정한다. 설정하지않을경우 "C:\tboledb_ 날 짜시간.log" 경로에로그가생성된다. Windows 7 의경우 C:\ 디렉터리에파일을생성하려면관리자권한이필요 하다. 따라서해당경로에로그를생성하려면애플리케이션을관리자권한 으로실행한다. FORCED_USE_WCHAR 1 로설정할경우 Tibero OLE DB 에서 varchar,char 를 wchar 로강제바인드 시킨다. (Tibero5 r70330 이후 ) 2.5.2. 에러메시지처리 수행중발생할수있는에러메시지에대해서설명한다. Current cursor is not updatable(tberr 2135) 설명 대응방법 Updatable Cursor가비활성화상태인경우또는불가능한쿼리 (view를정의한쿼리에 join문이있는경우 ) 인경우발생한다. Updatable Cursor가비활성화상태인경우연결문자열에 Updatable Cursor=True를추가하고, Updatable Cursor가불가능한쿼리인경우대체할수있는쿼리를작성하거나직접 DML을작성하여수정한다. 2.5.3. 연동할때문제점 연동할때발생할수있는문제점에대해서설명한다. UTF8 글자깨짐현상 [Application] [Enterprise Library] [Tibero OLE DB] [Tibero Server(UTF8)] 와같은구조 ( 중간에다른프레임워크가들어갈수도있음 ) 에서발생할수있는문제점이다. 48 Tibero Driver 연결가이드
설명 대응방법 DB에저장된 UTF8 데이터를애플리케이션에서화면에 ASCII로 ( 영문 Windows의기본캐릭터셋 ) 출력하면서깨지는것으로보통 char, varchar은 char로 nchar, nvarchar은 wchar로바인드하기때문에발생한다. 아래의방법중하나를선택한다. 컬럼타입 char, varchar 을 nchar, nvarchar 로변환한다. Tibero OLE DB 에서 char, varchar 를 wchar 로강제바인드시키는환경변수를다음과 같이설정한다. (Tibero5 r70330 이후 ) FORCED_USE_WCHAR=1 2.6. 예제 본절에서는 OLE DB 를이용한예제를설명한다. 2.6.1. ASP 조회 다음은간단한조회예제이다. <%@ Language=VBScript %> <%Option Explicit%> <HTML> <HEAD> <META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0"> </HEAD> <BODY> <table style="font-size:10pt" border="1"> <% Dim Con, Rs Set Con = Server.CreateObject ("ADODB.Connection") // 아래코드실제사용시에는한줄로사용할것 Con.Open "Provider=tbprov.Tbprov.5;Password=dbtech;Persist Security Info=True ;User ID=dbtech;Data Source=t5" Set Rs = Con.Execute ("Select * From user_objects") 제 2 장 OLE DB 연결 49
while not Rs.eof %> <TR> <TD><%=Rs("OBJECT_NAME")%></TD> <TD><%=Rs("OBJECT_ID")%></TD> <TD><%=Rs("OBJECT_TYPE")%></TD> <TD><%=Rs("OBJECT_TYPE_NO")%></TD> <TD><%=Rs("CREATED")%></TD> <TD><%=Rs("STATUS")%></TD> <TD><%=Rs("TEMPORARY")%></TD> </TR> <% rs.movenext wend Set Rs = Nothing Con.Close Set Con = Nothing %> </table> </BODY> </HTML> Procedure 호출및 LOB 처리 다음은 Procedure 및 LOB 관련예제이다. 테스트오브젝트생성 CREATE TABLE NOTICE(seq number, contents clob); CREATE TABLE NOTICE3(seq number, contents blob); CREATE or REPLACE PROCEDURE UPDATE_NOTICE ( V_SEQ IN number, V_CONTENTS IN CLOB ) AS loba clob BEGIN insert into notice(seq, CONTENTS) values(v_seq, EMPTY_CLOB()); select contents into loba from notice where seq=v_seq; dbms_lob.write(loba,length(v_contents),1,v_contents); COMMIT; END; / 50 Tibero Driver 연결가이드
Procedure 사용 <%@ CodePage=51949 Language="VBScript"%> <% Set objconn = server.createobject("adodb.connection") 'objconn.open "Provider=tbprov.Tbprov.5;Data Source=t5;User ID=dbtech; 'Password=dbtech;" objconn.open "Provider=MSDASQL;DSN=t5;UID=dbtech;PWD=dbtech;" Set cmd= Server.CreateObject("ADODB.Command") contents = "aaaaaaaaaaaaaaaaaaaaaa" with cmd set.activeconnection = objconn.commandtype = 4.CommandText = "UPDATE_NOTICE".Parameters.Append.CreateParameter("@V_SEQ",3, 1, 4).Parameters.Append.CreateParameter("@V_CONTENTS", 201, 1, Len(contents)).Parameters("@V_SEQ") = 4.Parameters("@V_CONTENTS") = contents.execute end with Set cmd = Nothing objconn.close response.write("sql : " & Sql & "<br>") %> CLOB 조회 <% Dim Con, Rs, strqry Set Con = Server.CreateObject ("ADODB.Connection") Con.Open "Provider=MSDASQL;DSN=t5;UID=dbtech;PWD=dbtech;" Set Rs = Server.CreateObject("ADODB.Recordset") Function CLOBRead(pLen, seq) Dim K Dim strmok Dim strlast Dim strreturn Dim Res strmok = int(clng(plen) / 2000) 제 2 장 OLE DB 연결 51
strlast = int(strmok + 1) Set Res = Server.CreateObject("ADODB.Recordset") For K = 1 To strlast squery = "" squery = squery & " SELECT DBMS_LOB.SUBSTR(CONTENTS, 2000, 2000 * (" & K & " - 1) + 1) MEMO FROM NOTICE where seq=" & seq & vbcrlf Res.Open squery, Con strreturn = strreturn & Res("memo") Res.Close Next Set Res = Nothing CLOBRead = strreturn End Function strqry = "SELECT DBMS_LOB.GETLENGTH(contents) CONTENT_LENGTH FROM NOTICE WHERE seq=4" Rs.Open strqry, Con, 3 content = CLOBRead(Rs.Fields("CONTENT_LENGTH"), 4) %> <%=content%> <% Set Rs = Nothing Con.Close Set Con = Nothing %> BLOB 등록 <% Function ReadByteArray(strFileName) Const adtypebinary = 1 Dim bin Set bin = CreateObject("ADODB.Stream") bin.type = adtypebinary bin.open bin.loadfromfile strfilename ReadByteArray = bin.read 52 Tibero Driver 연결가이드
End Function Set objconn = server.createobject("adodb.connection") Set cm = Server.Createobject("ADODB.Command") // 아래코드실제사용시에는한줄로사용할것 objconn.open "Provider=tbprov.Tbprov.5;Data Source=t5 ;User ID=dbtech;Password=dbtech;" strqry = "INSERT INTO NOTICE3 (SEQ, CONTENTS) VALUES (?,?)" response.write("strqry : " & strqry & "<br>") Dim seq notice3테이블에입력할 seq필드값 seq=44 cm.activeconnection = objconn cm.commandtext = strqry cm.parameters.append cm.createparameter("@seq", 3, 1, Len(seq), seq) Dim fileuri fileuri = "D:\tibero\binary\tibero5-bin-5.0-windows64-69860-opt-tested.tar.gz" 'ReadByteArray( 파일이위치한절대경로 ) cm.parameters.append cm.createparameter("@contents", 205, 1,LenB(ReadByteArray(fileURI)),ReadByteArray(fileURI)) 'cm.commandtype = 1 <<= 사용금지 cm.execute Set cmd = Nothing objconn2.close Set objconn2 = Nothing %> 2.6.2. ASP.NET 조회 다음은간단한조회예제이다. (Windows 2008 Server IIS 확인 ) <%@ Import Namespace="System.Data.OleDb" %> <script runat="server"> sub Page_Load dim dbconn,sql,dbcomm,dbread // 아래코드실제사용시에는한줄로사용할것 dbconn=new OleDbConnection("Provider=tbprov.Tbprov.5;User ID=dbtech; Password=dbtech;Data Source=t5;Updatable Cursor=True;") dbconn.open() 제 2 장 OLE DB 연결 53
sql="select sysdate FROM dual" dbcomm=new OleDbCommand(sql,dbconn) dbread=dbcomm.executereader() SystemDate.DataSource=dbread SystemDate.DataBind() dbread.close() dbconn.close() end sub </script> <!DOCTYPE html> <html> <body> <form runat="server"> <asp:repeater id="systemdate" runat="server"> <HeaderTemplate> <table border="1" width="30%"> <tr bgcolor="#b0c4de"> <th>date</th> </tr> </HeaderTemplate> <ItemTemplate> <tr bgcolor="#f0f0f0"> <td><%#container.dataitem("sysdate")%> </td> </tr> </ItemTemplate> <FooterTemplate> </table> </FooterTemplate> </asp:repeater> </form> </body> </html> 54 Tibero Driver 연결가이드
2.6.3. C# 조회 다음은간단한조회예제이다. 예제1 using System; using System.Data; using System.Data.OleDb; using System.Xml.Serialization; public class MainClass { public static void Main () { string straccessconn = "Provider=tbprov.Tbprov.5; Data Source=t5;User ID=dbtech;Password=dbtech"; Console.WriteLine("Connection..."); string straccessselect = "SELECT * FROM test3"; DataSet mydataset = new DataSet(); OleDbConnection myaccessconn = null; try { myaccessconn = new OleDbConnection(strAccessConn); } catch(exception ex) { Console.WriteLine("Error: Failed to create a database connection. \n{0}", ex.message); return; } try { OleDbCommand myaccesscommand = new OleDbCommand(strAccessSelect,myAccessConn); OleDbDataAdapter mydataadapter = new OleDbDataAdapter(myAccessCommand); myaccessconn.open(); mydataadapter.fill(mydataset,"test3"); 제 2 장 OLE DB 연결 55
} catch (Exception ex) { Console.WriteLine("Error: Failed to retrieve the required data from the DataBase.\n{0}", ex.message); return; } finally { myaccessconn.close(); } DataTableCollection dta = mydataset.tables; foreach (DataTable dt in dta) { Console.WriteLine("Found data table {0}", dt.tablename); } Console.WriteLine("{0} tables in data set", mydataset.tables.count); Console.WriteLine("{0} tables in data set", dta.count); Console.WriteLine("{0} rows in Categories table", mydataset.tables["test3"].rows.count); Console.WriteLine("{0} columns in Categories table", mydataset.tables["test3"].columns.count); DataColumnCollection drc = mydataset.tables["test3"].columns; int i = 0; foreach (DataColumn dc in drc) { Console.WriteLine("Column name[{0}] is {1}, of type {2}",i++, dc.columnname, dc.datatype); } DataRowCollection dra = mydataset.tables["test3"].rows; foreach (DataRow dr in dra) { Console.WriteLine("CategoryName[{0}] is {1}", dr[0], dr[1]); } } } 56 Tibero Driver 연결가이드
예제 2 using System; using System.Data; using System.Data.OleDb; class TableAnalysis { static void Main(string[] args) { //data source=name // 아래코드실제사용시에는한줄로사용할것 string sql = "Provider=tbprov.Tbprov.5;User ID=dbtech;Password=dbtech; Data Source=t5;Persist Security Info=True"; //location=ip,port //string sql = "Provider=tbprov.Tbprov.5;Password=dbtech; User ID=dbtech;Location=127.0.0.1,8629,t5;Persist Security Info=True"; OleDbConnection conn = new OleDbConnection(sql); try { conn.open(); // 데이터베이스연결 OleDbCommand cmd = new OleDbCommand(); cmd.commandtext = "select * from all_tables"; // 테이블 cmd.commandtype = CommandType.Text; // 검색명령을쿼리형태로 cmd.connection = conn; //select * from all_tables 결과 OleDbDataReader read = cmd.executereader(); Console.WriteLine("***** ALL_TABLES 테이블 *****"); for (int i = 0; i < read.fieldcount; i++) { Console.WriteLine(" 필드명 : {0} \n", read.getname(i)); } Console.WriteLine(" 총필드개수는 " + read.fieldcount); read.close(); } catch (Exception ex) { Console.WriteLine(" 에러발생 {0}", ex.message); } finally { if (conn!= null) { 제 2 장 OLE DB 연결 57
} } } } conn.close(); // 데이터베이스연결해제 Console.WriteLine(" 데이터베이스연결해제.."); REFCURSOR 다음은 SYS_REFCURSOR 를사용하는예제소스이다. 테스트오브젝트생성 CREATE OR REPLACE PACKAGE pkg003 IS PROCEDURE get_forms(curs out SYS_REFCURSOR); END; CREATE OR REPLACE PACKAGE BODY pkg003 IS -- procedure implementation PROCEDURE get_forms(curs out SYS_REFCURSOR) IS BEGIN open curs FOR select sysdate FROM dual; END; END; 예제소스 string connectionstring = System.Configuration.ConfigurationManager.ConnectionStrings["tibero5_oledb"].ConnectionString; OleDbConnectionTbr myconnection = new OleDbConnectionTbr(connectionString); DataTable dt = new DataTable(); System.Data.OleDb.OleDbDataReader reader = null; try{ myconnection.open(); OleDbCommandTbr cmd = new OleDbCommandTbr(); cmd.connection = myconnection; cmd.commandtext = "pkg003.get_forms"; cmd.commandtype = CommandType.StoredProcedure; cmd.parameters.add("curs", OleDbTypeTbr.Cursor).Direction 58 Tibero Driver 연결가이드
= ParameterDirection.Output; reader = cmd.executereader(); mydatagrid.datasource = reader; mydatagrid.databind(); } catch (Exception) { } finally { reader.close(); myconnection.close(); } 제 2 장 OLE DB 연결 59
제 3 장 JDBC 연결 본장에서는 JDBC 에대한개념과 Tibero JDBC 의드라이버연동에대해서설명한다. 3.1. JDBC 개념 Java Database Connectivity의약자로서 Java로만들어진클래스와인터페이스로이루어진 API이다. DBMS의종류와관련없는독립적인프로그래밍을가능하게해주며 JDBC는 java.sql, javax.sql 두개의패키지에포함된다. java.sql은데이터베이스에접근하고데이터를검색하거나업데이트하는핵심 JDBC API를제공한다. javax.sql은 JDBC 클라이언트가서버측의데이터소스를접근할수있게하는 API를제공한다. JDBC Driver Types Type 1 : JDBC-ODBC Bridge Driver ODBC 같이다른 Data Access API와매핑하는형태의 JDBC API를구현한것이다. 이것은 Native Client Library에종속적으로되는경우가많아이식성에제약이있다. Sun의 JDBC-ODBC Bridge Driver가이에속하지만 JDBC 3.0의지원이나멀티쓰레딩을사용할수없는등의여러가지제약을지닌다. [ 그림 3.1] TYPE1 Type 2 : Native-API Driver Native Code와 Java Code가혼합되어구현이되어있다. 주로 Interface만 Java인경우가많고접근하는데이터소스에따라각기다른 Native Client Library가필요하다. 그래서이것을 Thick Driver 라고도한다. Native Code로인하여이식성에제한이있다. [ 그림 3.2] TYPE2 제 3 장 JDBC 연결 61
Type 3 : Net-Protocol Driver 데이터베이스에독립적인프로토콜을이용하는미들웨어서버와통신하고순수자바클라이언트를사용하는드라이버로미들웨어서버는클라이언트의요청을데이터소스에독립적인프로토콜로변환하여사용한다. 이경우드라이버가직접데이터베이스를제어하지않고미들웨어를통하여제어하기때문에유연성을지닌다. [ 그림 3.3] TYPE3 Type 4 : Native-Protocol Driver 모두자바로구현되어있어플랫폼에제한을받지않으며별도의클라이언트소프트웨어가없이표준자바소켓을이용하여데이터소스와직접통신한다. 보통 Thin Driver라고한다. [ 그림 3.4] TYPE4 3.2. Tibero JDBC 본절에서는 JDBC 드라이버설명과연동하는방법에대해서설명한다. 참고 Tibero 에서는현재 Type 4 만지원한다. 3.2.1. JDBC 드라이버 JDBC 드라이버는 "$TB_HOME/client/lib/jar" 경로에존재한다. 다음은드라이버파일에대한설명이다. 파일명규칙 tibero[db_major_version]-jdbc-[jdk_version]-[debug].jar 62 Tibero Driver 연결가이드
항목 [DB_MAJOR_VERSION] [JDK_VERSION] [DEBUG] 설명 Tibero 제품의메인버전를표시한다. JDBC 드라이버가동작하는 JDK 버전을표시한다. 기본형의경우생략한다. 문제가발생할때로그를발생하는 JDBC 파일 ( 디버그용도 ) 인지알려준다. 사용예 파일명 tibero5-jdbc.jar tibero5-jdbc-dbg.jar tibero5-jdbc-14.jar tibero5-jdbc-14-dbg.jar 설명 JDK( 또는 JRE) 1.6 이상에서수행가능한드라이버파일 ( 기본형 ) 이다. JDK( 또는 JRE) 1.6 이상에서수행가능한 JDBC 파일 ( 디버그용도 ) 이다. JDK( 또는 JRE) 1.4 이상에서수행가능한드라이버파일 (JRE 버전문제가발생할경우주로사용 ) 이다. JDK( 또는 JRE) 1.4 이상에서수행가능한 JDBC 파일 ( 디버그용도 ) 이다. 버전확인 주로 JDBC 리비전정보가필요할때아래와같은방법으로확인할수있다. 형식 java -jar [driver_name] 항목 [driver_name] 설명 JDBC 드라이버파일명이다. 사용예 $ java -jar tibero5-jdbc.jar Tibero JDBC Driver 5.0 (Rev.71713M) Tibero, Co. Copyright(C) 2011-. All rights reserved. 3.2.2. 드라이버연동 Tibero JDBC를가지고서버와연동할때연동할때다음의클래스를사용한다. Connection을맺을때사용하는클래스이름 : com.tmax.tibero.jdbc.tbdriver 데이터소스를사용할때클래스이름 : com.tmax.tibero.jdbc.ext.tbconnectionpooldatasource XA 데이터소스를사용할때클래스이름 : com.tmax.tibero.jdbc.ext.tbxadatasource 제 3 장 JDBC 연결 63
데이터베이스 URL 데이터베이스 URL은 Single 노드구성과 TAC 노드구성으로나누어설명한다. Single 노드구성 1개의 Tibero 서버로구성된경우이다. 사용방법 jdbc:tibero:thin:@<ip>:<port>:<db_name> 항목 <ip> <port> <db_name> 설명접속하려는 Tibero 서버 IP 주소이다. 접속하려는 Tibero 서버포트번호이다. 접속하려는 Tibero 서버 DB 이름이다. 사용예 jdbc:tibero:thin:@127.0.0.1:8629:t5 TAC 노드구성 2 개로구성된 TAC 서버일경우이다. 사용방법 jdbc:tibero:thin:@(description= (failover=on)(load_balance=on) (address_list=(address=(host=<node1_ip>)(port=<node1_port>)) (address=(host=<node2_ip>)(port=<node2_port>)) )(DATABASE_NAME=<db_name>)) 항목 failover load_balance <node1_ip> <node1_port> <node2_ip> <node2_port> <db_name> 설명연결이끊어진경우자동으로복구해주는기능 (on 또는 off 설정 ) 으로순차적방식으로새로운서버에접속하며현재는데이터베이스와의연결만복구한다. 사용자 Connection을여러서버로분산시키는기능 (on 또는 off 설정 ) 으로 Dedicate 방식 (= 전용방식 ) 으로구성할경우해당기능을 off 한다. 1번노드에대한접속정보이다. (IP 주소, 포트번호 ) 2번노드에대한접속정보이다. (IP 주소, 포트번호 ) 접속하려는 TAC 의 DB 이름이다. 64 Tibero Driver 연결가이드
사용예 jdbc:tibero:thin:@(description= (failover=on)(load_balance=on) (address_list=(address=(host=127.0.0.1)(port=8629)) (address=(host=127.0.0.2)(port=8629)) )(DATABASE_NAME=t5)) 3.3. JDBC 전환 본절에서는 Oracle JDBC 를전환하는내용을설명한다. 3.3.1. Oracle JDBC 클래스를변경할때다음을참고한다. Oracle oracle.jdbc.driver.oracletypes.cursor oracle.sql.blob oracle.sql.clob oracle.jdbc.driver.oracleresultset oracle.jdbc.oraclecallablestatement Tibero com.tmax.tibero.tbtypes.cursor com.tmax.tibero.jdbc.tbblob com.tmax.tibero.jdbc.tbclob com.tmax.tibero.jdbc.tbresultset com.tmax.tibero.jdbc.tbcallablestatement 3.4. 문제해결 특정문제가발생했을때해결하는방법을설명한다. 3.4.1. 로그발생 Tibero JDBC 를사용하여특정문제가발생했을때추가적인로그를발생하여확인하는방법이다. 로그가 추가적으로발생하므로일부성능이느려질수있다. 따라서문제가있을때일시적으로만사용한다. 로그발생은다음과같은순서로적용한다. 1. 드라이버교체기존에사용하던 JDBC 드라이버파일을 tibero5-jdbc-dbg.jar와같은디버그용도파일로교체한다. 2. 클라이언트프로그램재기동디버그용도파일을가지고동작할수있도록프로그램을재기동한다. 제 3 장 JDBC 연결 65
3. 로그파일위치확인 ( 해당폴더확인 ) UNIX 계열 : /home/ 사용자이름 Windows 계열 : C:\Documents and Settings\ 사용자이름 4. 로그파일이름확인 tbjdbc-{yymmdd}-{hhmmss}-{s}-{random}.log 형식으로파일이생성된다. 3.5. 예제 본절에서는 JDBC 를이용하여연결하는기본적인형태의예제와특수한타입의예제를설명한다. 3.5.1. 기본예제 다음은 JDBC 를이용한연결예제이다. import java.sql.connection; import java.sql.resultset; import java.sql.sqlexception; import java.sql.statement; import com.tmax.tibero.jdbc.ext.tbdatasource; public class TiberoJDBC { public static void main(string[] args) throws SQLException { TbDataSource tds = new TbDataSource(); tds.seturl("jdbc:tibero:thin:@127.0.0.1:8629:t5"); tds.setuser("dbtech"); tds.setpassword("dbtech"); Connection conn = tds.getconnection(); Statement stmt = conn.createstatement(); String query = "select table_name from user_tables where rownum < 10 " ; ResultSet rs = stmt.executequery(query); String stname=null; int irows = 1; while ( rs.next() ) { stname = rs.getstring("table_name"); System.out.println("row[" + irows + "] : " + stname); 66 Tibero Driver 연결가이드
} irows++; } } rs.close(); stmt.close(); conn.close(); 3.5.2. 타입관련예제 NVARCHAR 처리 com.tmax.tibero.jdbc.tbpreparedstatement에 NCharset을지원하기위해다음과같은 API를제공한다. setncharacterstream() setnclob() setnstring() 다음은 NVARCHAR 처리의예제이다. ds = (DataSource)ctx.lookup("tibero"); conn = ds.getconnection(); ins_pstmt = (TbPreparedStatement)conn.prepareStatement(ins_query); ins_pstmt.setstring(1, "test"); ins_pstmt.setnstring(2, "multinational character"); ARRAY 동일한타입의 Primitive 값이 Array 인경우에만지원이가능하다. 테스트오브젝트생성 CREATE OR REPLACE PACKAGE TYPE_PKG AS TYPE "TY_CHOICE_IDX_ARR" IS VARRAY(20000) OF CLOB; END; / CREATE OR REPLACE PROCEDURE TB_ARRAY_TEST ( I_INPT_EXPC_DIV IN VARCHAR2,... 제 3 장 JDBC 연결 67
) O_CHOICE_PACKET OUT TYPE_PKG.TY_CHOICE_IDX_ARR /* TYPE */ IS... L_DATA TMP_CLOB_RTN CLOB; TYPE_PKG.TY_CHOICE_IDX_ARR; BEGIN -- init L_DATA := TYPE_PKG.TY_CHOICE_IDX_ARR(); TYPE AAA_SET IS TABLE OF CBT_CAT%ROWTYPE; AAA AAA_SET;... FOR I IN AAA.FIRST.. AAA.LAST LOOP -- CLOB return function T_CHOICE_IDX_LIST := FN_CHOICE_LIST_ADD_01(); O_CHOICE_IDX_LIST := O_CHOICE_IDX_LIST T_DELIM_PIPE T_CHOICE_IDX_LIST; END LOOP; L_DATA.EXTEND; L_DATA(L_DATA.COUNT) := O_CHOICE_IDX_LIST 'FALSE' 'string test' O_CHOICE_PACKET := L_DATA; END; / 예제소스 ( 소스전체는아님 ) CallableStatement cstmt = null; Array packetarray = null; callablesql = "begin? :=TB_ARRAY_TEST(?,?,?,?,?); end;"; try{ cstmt = (CallableStatement)con.prepareCall(callableSql); cstmt.setstring(1, domaincd.trim()); cstmt.setstring(2, tsno.trim()); cstmt.setdouble(3, Double.parseDouble(verNo.trim())); cstmt.setstring(4, inptexpcdiv); cstmt.setstring (5, choicegrpno); //out parameter cstmt.registeroutparameter(6, TbTypes.ARRAY, "TYPE_PKG.TY_CHOICE_IDX_ARR" ); cstmt.execute(); 68 Tibero Driver 연결가이드
packetarray = cstmt.getarray(6); // Get the ARRAY object if(packetarray == null){ throw new BCException("no data"); } Object o = packetarray.getarray(); clobs = (Clob[])o; choicegrppacketlist = new ArrayList(clobs.length); Clob clob = null; String packet = null; long cloblength = 0; for( int i = 0 ; i < clobs.length; i++ ){ clob = clobs[i]; cloblength = clob.length(); packet = clob.getsubstring(1, (int)cloblength); choicegrppacketlist.add(jdbccodeconvertor.tokor(packet)); } }catch(sqlexception sqle){ sqle.printstacktrace(); }finally{ if( cstmt!= null ){ try{ cstmt.close(); }catch(sqlexception sqle) { logger.error("callablestatement close Error!"); sqle.printstacktrace(); } } } 제 3 장 JDBC 연결 69
제 4 장 tbesql 연결 본장에서는 tbesql 에대한개념과사용방법에대해서설명한다. 4.1. tbesql 개념 ESQL(Embedded SQL : 내장 SQL) 은프로그래밍언어의연산능력과 SQL의데이터베이스 (Database) 를조작하는능력을결합하기위한방법이며 ANSI 및 ISO 표준으로정의되어있다. tbesql은 ESQL의사용을위해 Tibero가제공하는인터페이스이며 C와 COBOL을제공한다. 4.1.1. tbesql 기본동작 tbesql에서는프리컴파일, 컴파일및링크과정을거친다. 처리가완료된실행파일을가지고실행하게되면 Tibero 서버에접속하게되는것이다. 참고로 tbesql은내부적으로 tbcli(=odbc) 인터페이스를사용한다. 따라서 tbcli(=odbc) 관련환경변수가모두적용가능하다. 다음은 tbesql의기본동작을나타내는그림이다. [ 그림 4.1] tbesql 기본동작 제 4 장 tbesql 연결 71