| 免费下载:IBM® Informix® 11.7 试用版(包括 Ultimate Edition、Developer Edition 和 Innovator-C Edition) |
|---|
| 下载更多的 IBM 软件试用版,并加入 IBM 软件下载与技术交流群组,参与在线交流。 |
开放数据库连接 (ODBC) 是一种接口,提供对关系和非关系数据库服务器的统一数据访问。它是一种基于 X/Open Call Level Interface (CLI)(用于访问来自数据库服务器的数据)的软件 API。它允许您使用对所有 ODBC 驱动程序通用的标准 API 编写数据库应用程序,使您无需使用特定于具体数据库的方式编写应用程序。这有助于减少开发时间,使解决方案更具可移植。
ODBC 应用程序的典型组件包括:
- ODBC 客户端:使用 ODBC API 与数据库服务器交互的应用程序。
- ODBC Driver:一个或一组包含针对特定数据库服务器的 ODBC API 实现的库。
- ODBC Driver Manager:一个或一组可供 ODBC 客户端用来与 ODBC Driver 交互的库。
Informix ODBC Driver 是 IBM Informix CSDK 包的一部分。它符合 Microsoft® 开放数据连接 (ODBC) 3.5 版标准。Informix ODBC Driver 支持多种 IBM Informix 数据库服务器,比如 IBM Informix Ultimate Edition 和 IBM Informix Choice Edition。请参见 参考资料 一节,获取展示数据库服务器兼容性的 IBM Informix ODBC Driver 版本说明的链接。
在 Microsoft Windows® 上,ODBC Driver 会在 CSDK 安装期间自动注册。Informix ODBC Driver 的名称为 IBM Informix ODBC Driver。
在 UNIX® 和 Linux® 平台上,ODBC Driver 通常通过库的名称进行引用。下面的列表描述了 Informix CSDK 包中包含的不同版本的 Informix ODBC Driver 库:
- libifcli.a 或 libcli.a:针对单个非多线程应用程序的静态版本
- libifcli.so 或 iclis09b.so:针对单个非多线程应用程序的共享版本
- libthcli.a:针对多线程应用程序的静态版本
- libthcli.so 或 iclit09b.so:针对多线程应用程序的共享版本
- libifdrm.so 或 idmrs09a.so:针对 Driver Manager Replacement (DMR) 的共享库
文件扩展名因平台不同而有所不同。
如图 1 所示,ODBC 应用程序可在以下 3 种配置下使用这些库:
- 直接链接到驱动程序 (A):Informix ODBC Driver 库直接供 ODBC 应用程序使用。
- 链接 ODBC Driver Manager (B):ODBC 客户端应用程序链接到一个 ODBC Driver Manager,ODBC Driver Manager 执行加载和使用 ODBC Driver 所需的所有操作,充当应用程序与 ODBC Driver 之间的中间层。
- 链接到 Driver Manager Replacement 和驱动程序 (C) :除了 Informix ODBC Driver 之外,Informix CSDK 包还包含一个 Driver Manager Replacement (DRM) 库(不可用于 Windows)。这个库提供了 ODBC Driver Manager 的大部分功能,如果没有在机器上安装 ODBC Driver Manager,则该库可供 ODBC 客户端使用。
图 1. ODBC 客户端应用程序与 Informix 服务器的连接
ODBC Driver Manager 是一个软件层,管理用户应用程序与 ODBC Driver 之间的通信。ODBC Driver Manager 执行以下工作:加载和卸载应用程序所需的合适的 ODBC Driver,以及验证传递给驱动程序的 API 参数,等等。当应用程序使用驱动程序管理器时,API 调用由 ODBC Driver Manager 处理,后者执行基本的错误检查,然后处理这些调用,或者如果需要,将它们传递给底层的 ODBC Driver。
ODBC Driver Manager 软件由大部分 UNIX 和 Linux 平台的第三方供应商提供。在 Microsoft Windows 或 MAC OS X 等一些操作系统上,ODBC Driver Manager 是操作系统的一部分。
ODBC Driver Manager 使用的典型配置文件包括:
- odbcinst.ini:包含特定于 Driver Manager 的信息,比如哪些驱动程序可用于 Driver Manager,以及所有 DSN 中共享的配置参数。
- odbc.ini:包含 ODBC Data Source Name 或 DSN 的信息。DSN 定义一个数据库连接。odbc.ini 提供连接到数据库所需的所有信息,以及特定于 ODBC Driver 的配置参数。
odbcinst.ini 文件包含一组已安装在 UNIX 系统上的 ODBC 驱动程序,以及每个驱动程序的特性属性,比如共享库的位置。此文件通常是 ODBC Driver Manager 的一部分,它的默认位置为 system /etc 目录。
Informix CSDK 包中还包含清单 1 中所示的示例 odbcinst.ini 文件,它包含在安装目录下的 /etc 子目录下(由 INFORMIXDIR 环境变量指定)。
清单 1. 示例 odbcinst.ini 文件
[ODBC Drivers] IBM INFORMIX ODBC DRIVER=Installed [IBM INFORMIX ODBC DRIVER] Driver=/extra/informix/lib/cli/iclit09b.so Setup=/extra/informix/lib/cli/iclit09b.so APILevel=1 ConnectFunctions=YYY DriverODBCVer=03.51 FileUsage=0 SQLLevel=1 smProcessPerConnect=Y |
odbc.ini 文件包含数据源配置信息,供 ODBC Driver 和 ODBC Driver Manager 使用。odbc.ini 的默认位置是用户主目录 (/odbc.ini),但此位置可使用 ODBCINI 环境变量进行更改。
CSDK 包中提供了 Informix ODBC Driver 的示例 odbc.ini 文件,如清单 2 所示。它位于 CSDK 安装目录(通常由 INFORMIXDIR 环境变量指定)下的 etc 子目录中。
清单 2. 示例 odbc.ini 文件
[ODBC Data Sources] Infdrv1=IBM INFORMIX ODBC DRIVER Infdrv2=IBM INFORMIX ODBC DRIVER ; ; Define ODBC Database Driver's Below - Driver Configuration Section ; [Infdrv1] Driver=/extra/informix/lib/cli/iclit09b.so Description=IBM INFORMIX ODBC DRIVER Database=stores_demo LogonID=odbc pwd=odbc Servername=ids_server1 [Infdrv2] Driver=/extra/informix/lib/cli/iclis09b.so Description=IBM INFORMIX ODBC DRIVER Database=stores_demo LogonID=odbc pwd=odbc Servername=ids_server2 CursorBehavior=0 CLIENT_LOCALE=en_us.8859-1 DB_LOCALE=en_us.8859-1 TRANSLATIONDLL=/extra/informix/lib/esql/igo4a304.so ; ; UNICODE connection Section ; [ODBC] ;uncomment the below line for UNICODE connection ;UNICODE=UCS-4 ; ; Trace file Section ; Trace=0 TraceFile=/tmp/odbctrace.out InstallDir=/extra/informix TRACEDLL=idmrs09a.so |
参见 参考资料 section,获取 IBM Informix ODBC Driver 指南的链接,可在其中获得所有 odbc.ini configuration 参数的完整描述。
结合使用 ODBC Driver 和 ODBC Driver Manager
odbc.ini 中指定的一些参数在结合使用 Informix ODBC Driver 和第三方 ODBC Driver Manager 时至关重要。设置 ODBC Driver 时的最常见问题是 Unicode 参数。
odbc.ini 文件中的 Unicode 参数用于指定驱动程序所需的 Unicode 参数。它因平台不同而有所不同,甚至在不同 ODBC Driver 管理器之间也是不同的。IBM Informix ODBC Driver 支持 UCS-2、UCS-4 和 UTF-8 编码,如表 1 所示。
表 1. ODBC Driver Manager 的默认 Unicode 值
| DRIVER MANAGER | Unicode |
|---|---|
| UnixODBC | UCS-2 |
| DataDirect | UTF-8 |
| iODBC | UCS-4 |
下一节提供了针对最常见平台的实用 ODBC.INI 文件的示例。
Linux 发行版通常不包含 ODBC Driver Manager。
UnixODBC 是一个开源 ODBC Driver Manager,它是 Linux 平台上最常用的驱动程序管理器。您可以在 参考资料 一节中找到构建和配置 UnixODBC 的信息。
UnixODBC Driver Manager 使用的默认 Unicode 编码为 UCS-2。这意味着 odbc.ini 文件中的 Unicode 参数应该为 UCS-2,否则使用 Unicode ODBC API 应用程序将无法正常工作。
清单 3 中的输出给出了 UnixODBC Driver Manager 所使用的 odbc.ini 文件的内容。
清单 3. 用于 UnixODBC Driver Manager 的 odbc.ini 文件
[stores7] Driver=/usr3/370uc1/lib/cli/iclit09b.so Description=IBM INFORMIX ODBC DRIVER Database=stores7 LogonID=informix pwd=password Servername=irk1150 ; ; UNICODE connection Section ; [ODBC] ;uncomment the below line for UNICODE connection UNICODE=UCS-2 ; ; Trace file Section ; Trace=0 TraceFile=/tmp/odbctrace.out InstallDir=/usr3/370uc1 TRACEDLL=idmrs09a.so |
UnixODBC Driver Manager 中包含两个 ODBC 客户端工具。这些工具可用于测试 ODBC Driver 的配置是否有效。
ISQL 是一个基本的 ANSI ODBC 客户端。它使用了 ANSI ODBC API,所以它不会受到 Unicode 参数的影响。IUSQL 类似于 ISQL,但它使用了 Unicode ODBC API。
在尝试使用 ODBC Driver 之前,请确保已经正确设置了环境。Informix ODBC Driver 使用 Informix 本机库与数据库服务器通信。这些库使用 INFORMIXDIR 和 INFORMIXSQLHOSTS 等环境变量来查找连接所需的配置和资源文件。在下面的示例中,Informix CSDK 包安装在 “/usr3/csdk370” 中,所以环境变量 INFORMIXDIR 指向该目录:
informix@irk:/usr3/370uc1$ cat $INFORMIXDIR /usr3/csdk370 |
您使用的 IDS 服务器的名称(在 odbc.ini 中定义)为 irk1150,这表明您应该在 Informix sqlhosts 文件中拥有该服务器的通信参数。
informix@irk:/usr3/370uc1$ cat INFORMIXSQLHOSTS | grep irk1150 irk1150 onsoctcp irk.bedfont.uk.ibm.com 9089 |
清单 4 中所示的输出展示了如何通过 odbc.ini 使用 IUSQL 工具。
清单 4. 使用 IUSQL
informix@irk:/usr3/370uc1$ iusql -v stores7
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL> SELECT dbinfo('version', 'major') version FROM systables WHERE tabid=1
+--------+
| version|
+--------+
| 11 |
+--------+
SQLRowCount returns -1
1 rows fetched
SQL>
|
如果 odbc.ini 中包含不正确的 Unicode 值,则会导致一个错误,如清单 5 所示。
清单 5. 使用错误的 Unicode 值的示例
informix@irk:/usr3/370uc1$ grep UNICODE $ODBCINI ; UNICODE connection Section ;uncomment the below line for UNICODE connection UNICODE=UCS-4 informix@irk:/usr3/370uc1$ iusql -v stores7 [unixODBC][ [unixODBC][ [ISQL]ERROR: Could not SQLDriverConnect informix@irk:/usr3/370uc1$ |
该错误是因为应用程序使用的 Unicode 编码 (UCS-2) 与驱动程序管理器所使用的编码 (UCS-4) 不匹配所导致。
另一个可在 Linux OS 上使用的 ODBC Driver 管理器是 Progress DataDirect。在 Linux 平台上,DataDirect ODBC Driver Manager 使用 UTF-8 作为 Unicode 编码。安装包中包含两个 ODBC 客户端应用程序,您可使用它们测试 ODBC Driver 的配置是否有效。
清单 6 中的输出给出了通过 IBM Informix ODBC Driver 连接到 Informix 数据库服务器的 demoodbc
库。
清单 6. 使用 demoodbc 连接到 Informix
$ grep UNICODE $ODBCINI ; UNICODE connection Section ;uncomment the below line for UNICODE connection UNICODE=UTF-8 $ $ pwd /usr3/datadirect/samples/demo $ ./demoodbc -uid informix -pwd password stores7 ./demoodbc DataDirect Technologies, Inc. ODBC Sample Application. ./demoodbc: will connect to data source 'stores7' as user 'informix/password'. First Name Last Name Hire Date Salary ---------- --------- --------- ------ Tyler Bennett 2077-06-01 32000 John Rappl 2087-07-15 47000 George Woltman 2082-08-07 53500 Adam Smith 2088-01-15 18000 ... ... SQLFetch returns: SQL_NO_DATA_FOUND $ |
Unicode 参数是 odbc.ini 文件在 UnixODBC 和 DataDirect 之间唯一不同的地方。与以前一样,如果此参数的值不正确,应用程序将无法进行连接,并且不会出现任何有意义的错误消息,如清单 7 所示。
清单 7. 使用错误 Unicode 的示例
$ grep UNICODE $ODBCINI ; UNICODE connection Section ;uncomment the below line for UNICODE connection UNICODE=UCS-2 $ ./demoodbc -uid informix -pwd password stores7 ./demoodbc DataDirect Technologies, Inc. ODBC Sample Application. ./demoodbc: will connect to data source 'stores7' as user 'informix/password'. SQLConnect: Failed... SQLSTATE = 365 NATIVE ERROR = 0 MSG = 523 364 SQLConnect: Retrying Connect. SQLConnect: Failed... SQLConnect: Retrying Connect. SQLConnect: Failed... SQLConnect: Retrying Connect. No connection could be established. $ |
AIX 机器上的 UnixODBC 将 UCS-2 用于 Unicode,如清单 8 所示。
清单 8. AIX 上的 Unicode
$ uname -a AIX portland 3 5 005929BA4C00 $ grep UNICODE $ODBCINI ; UNICODE connection Section ;uncomment the below line for UNICODE connection UNICODE=UCS-2 $ echo $INFORMIXDIR /usr2/support/products/SDK-3.70.UC1 $ iusql -v stores7 informix password +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ SQL> select tabid from systables where tabname='systables' +------------+ | tabid | +------------+ | 1 | +------------+ SQLRowCount returns -1 1 rows fetched SQL> quit $ |
任何其他值将导致连接失败。
当在 AIX 平台上使用 DataDirect ODBC Driver Manager 时,UTF-8 是 odbc.ini 中所需的 Unicode 值。清单 9 中的输出显示了在 AIX 机器上使用的 odbc.ini 内容。
清单 9. AIX 上的 odbc.ini 内容
$ echo $INFORMIXDIR /usr2/support/products/SDK-3.70.UC1 $ cat $ODBCINI [stores7] Driver=/usr2/support/products/SDK-3.70.UC1/lib/cli/iclit09b.so Description=IBM INFORMIX ODBC DRIVER Database=stores7 LogonID=informix pwd=password Servername=gholmes1150 ; ; UNICODE connection Section ; [ODBC] ;uncomment the below line for UNICODE connection UNICODE=UTF-8 ; ; Trace file Section ; Trace=0 TraceFile=/tmp/odbctrace.out InstallDir=/usr2/support/products/SDK-3.70.UC1 TRACEDLL=idmrs09a.so $ |
就像在 AIX 上一样,默认情况下,UnixODBC Driver Manager 需要将 odbc.ini 文件中的 Unicode 参数设置为 UCS-2,如清单 10 中所示。
清单 10. Solaris 上的 odbc.ini
$ uname -a SunOS gholmes 5.9 Generic_122300-17 sun4u sparc SUNW,Ultra-5_10 $ which iusql /usr/local/bin/iusql $ ldd /usr/local/bin/iusql libodbc.so.1 => /usr/local/lib/libodbc.so.1 libiconv.so.2 => /usr/local/lib/libiconv.so.2 libodbcinst.so.1 => /usr/local/lib/libodbcinst.so.1 libltdl.so.7 => /usr/local/lib/libltdl.so.7 libreadline.so.4 => /usr/local/lib/libreadline.so.4 libcurses.so.1 => /usr/lib/libcurses.so.1 libdl.so.1 => /usr/lib/libdl.so.1 libthread.so.1 => /usr/lib/libthread.so.1 libc.so.1 => /usr/lib/libc.so.1 libgcc_s.so.1 => /usr/local/lib/libgcc_s.so.1 /usr/platform/SUNW,Ultra-5_10/lib/libc_psr.so.1 $ grep UNICODE $ODBCINI ; UNICODE connection Section ;uncomment the below line for UNICODE connection UNICODE=UCS-2 $ iusql -v stores7 +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ SQL> quit $ |
另一方面,DataDirect ODBC Driver Manager 将 UTF-8 用于 Unicode,如清单 11 中所示。
清单 11. Solaris 上的 DataDirect Driver Manager
$ pwd /usr3/datadirect/samples/demo $ ldd demoodbc libodbc.so => /usr3/datadirect/lib/libodbc.so libCrun.so.1 => /usr/lib/libCrun.so.1 libm.so.1 => /opt/SUNWspro/lib/libm.so.1 libw.so.1 => /usr/lib/libw.so.1 libthread.so.1 => /usr/lib/libthread.so.1 libc.so.1 => /usr/lib/libc.so.1 libsocket.so.1 => /usr/lib/libsocket.so.1 libdl.so.1 => /usr/lib/libdl.so.1 libIXicu20.so => /usr3/datadirect/lib/libIXicu20.so libodbcinst.so => /usr3/datadirect/lib/libodbcinst.so libnsl.so.1 => /usr/lib/libnsl.so.1 libposix4.so.1 => /usr/lib/libposix4.so.1 libmp.so.2 => /usr/lib/libmp.so.2 libaio.so.1 => /usr/lib/libaio.so.1 libmd5.so.1 => /usr/lib/libmd5.so.1 /usr/platform/SUNW,Ultra-5_10/lib/libc_psr.so.1 /usr/platform/SUNW,Ultra-5_10/lib/libmd5_psr.so.1 $ grep UNICODE $ODBCINI ; UNICODE connection Section ;uncomment the below line for UNICODE connection UNICODE=UTF-8 $ ./demoodbc -uid informix -pwd password stores7 ./demoodbc DataDirect Technologies, Inc. ODBC Sample Application. ./demoodbc: will connect to data source 'stores7' as user 'informix/password'. First Name Last Name Hire Date Salary Dept ---------- --------- --------- ------ ---- Tyler Bennett 2077-06-01 32000 D101 John Rappl 2087-07-15 47000 D050 George Woltman 2082-08-07 53500 D101 … … |
OpenSource iODBC Driver Manager 使用 4 个字节来表示 Unicode 代码点 (UCS-4)。清单 12 中的示例显示了通过 Informix ODBC Driver 连接到 Informix 数据库的 iodbctest iODBC 示例工具的输出。
清单 12. iodbctest iODBC 示例工具
./iodbctest iODBC Demonstration program This program shows an interactive SQL processor Driver Manager: 03.51.0001.0908 Enter ODBC connect string (? shows list): dsn=stores7;uid=informix;pwd=ximrofni Driver: 3.50.0000 3.50.U SQL>select tabid from systables where tabid=1 tabid ----------- 1 result set 1 returned 1 rows. SQL> SQL>quit Have a nice day.# # grep UNICODE $ODBCINI ;uncomment the below line for UNICODE connection UNICODE=UCS-4 # |
清单 13 显示了 HP/UX 机器上的 UnixODBC,它将 UCS-2 用于 Unicode。
清单 13. HP/UX 上的 UnixODBC
# uname -a HP-UX nanook B.11.11 U 9000/800 2812716602 unlimited-user license # grep UNICODE $ODBCINI ; UNICODE connection Section ;uncomment the below line for UNICODE connection UNICODE=UCS-2 # iusql -v stores7 informix password +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ SQL> quit # |
DataDirect ODBC Driver Manager 需要 Unicode=UTF-8,如清单 14 中所示。
清单 14. Unicode=UTF-8
# grep UNICODE $ODBCINI ; UNICODE connection Section ;uncomment the below line for UNICODE connection UNICODE=UTF-8 # pwd /usr3/products/DataDirect/samples/demo # ./demoodbc -uid informix -pwd password stores7 ./demoodbc DataDirect Technologies, Inc. ODBC Sample Application. ./demoodbc: will connect to data source 'stores7' as user 'informix/password'. First Name Last Name Hire Date Salary Dept ---------- --------- --------- ------ ---- Tyler Bennett 2077-06-01 32000 D101 John Rappl 2087-07-15 47000 D050 George Woltman 2082-08-07 53500 D101 … … |
清单 15 中的输出显示了一个简单的 ODBC 客户端代码,该代码连接到一个给定的 DSN,并选择 systables 目录表中的前 3 行。
清单 15. ODBC 客户端代码
informix@irk:~$ cat test.c
/* ----- test.c ------ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include "sql.h"
#include "sqlext.h"
#define BUFFER_LEN 10
#define ERRMSG_LEN 200
SQLINTEGER CheckError ( SQLRETURN rc,
SQLSMALLINT handleType,
SQLHANDLE handle,
SQLCHAR* errmsg)
{
SQLRETURN retcode = SQL_SUCCESS;
SQLSMALLINT errNum = 1;
SQLCHAR sqlState[6];
SQLINTEGER nativeError;
SQLCHAR errMsg[ERRMSG_LEN];
SQLSMALLINT textLengthPtr;
if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
{
while (retcode != SQL_NO_DATA)
{
retcode = SQLGetDiagRec (handleType, handle, errNum, sqlState,
&nativeError, errMsg, ERRMSG_LEN,
&textLengthPtr);
if (retcode == SQL_INVALID_HANDLE)
{
fprintf (stderr, "SQL_INVALID_HANDLE!\n");
return 1;
}
if (( retcode == SQL_SUCCESS) ||
( retcode == SQL_SUCCESS_WITH_INFO))
fprintf (stderr, "ERROR: %d: %s : %s \n",
(int)nativeError, sqlState, errMsg);
errNum++;
}
fprintf (stderr, "%s\n", errmsg);
return 1;
}
else
return 0;
}
int main (long argc, char* argv[])
{
SQLHDBC hdbc;
SQLHENV henv;
SQLHSTMT hstmt;
SQLCHAR dsn[100];
SQLRETURN rc = 0;
SQLINTEGER in;
SQLCHAR sname[15+1];
SQLLEN lcode = 0;
SQLLEN lsname = 0;
if (argc != 2)
{
fprintf (stdout, "Please specify a DSN!\n");
return(1);
}
else
sprintf((char *) dsn, "%s", (char *)argv[1]);
fprintf (stdout, "Connecting to DSN : %s\n", dsn);
rc = SQLAllocHandle (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
if (rc != SQL_SUCCESS)
{
fprintf (stdout, "SQLAllocHandle failed\n");
return ;
}
rc = SQLSetEnvAttr (henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0);
if (CheckError (rc, SQL_HANDLE_ENV, henv, (SQLCHAR *) "SQLSetEnvAttr failed\n"))
return ;
rc = SQLAllocHandle (SQL_HANDLE_DBC, henv, &hdbc);
if (CheckError (rc, SQL_HANDLE_ENV, henv, (SQLCHAR *) "SQLAllocHandle failed\n"))
return ;
rc = SQLConnect (hdbc, dsn, SQL_NTS, (SQLCHAR *) "", SQL_NTS,
(SQLCHAR *) "", SQL_NTS);
if (CheckError (rc, SQL_HANDLE_DBC, hdbc, (SQLCHAR *) "SQLConnect failed\n"))
return ;
fprintf (stdout, "Connected to %s\n",dsn);
rc = SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt );
if (CheckError (rc, SQL_HANDLE_DBC, hdbc, (SQLCHAR *) "SQLAllocHandle failed\n"))
return ;
rc = SQLPrepare (hstmt, (SQLCHAR *) "SELECT FIRST 3 tabname FROM systables;",
SQL_NTS);
if (CheckError (rc, SQL_HANDLE_STMT, hstmt, (SQLCHAR *) "SQLPrepare failed\n"))
return ;
rc = SQLExecute (hstmt);
if (CheckError (rc, SQL_HANDLE_STMT, hstmt, (SQLCHAR *) "SQLExecute failed\n"))
return ;
rc = SQLBindCol (hstmt, 1, SQL_C_CHAR, &sname, sizeof(sname), &lsname);
if (CheckError (rc, SQL_HANDLE_STMT, hstmt, (SQLCHAR *) "SQLBind failed\n"))
return ;
while ((rc = SQLFetch(hstmt))!=SQL_NO_DATA_FOUND)
fprintf (stdout, "TABNAME = %s\n", sname);
SQLFreeStmt (hstmt, SQL_CLOSE);
SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
SQLDisconnect (hdbc);
SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
SQLFreeHandle (SQL_HANDLE_ENV, henv);
}
/* ----- test.c ------ */
|
使用 –lodbc 标志会告诉链接器将 ODBC 库添加到可执行文件中,如清单 16 中所示。
清单 16. -lodbc flag
informix@irk:~$ cc test.c -lodbc -o test informix@irk:~$ ldd test linux-gate.so.1 => (0xb8072000) libodbc.so.1 => /usr/local/lib/libodbc.so.1 (0xb7ff1000) libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e8e000) libltdl.so.7 => /usr/lib/libltdl.so.7 (0xb7e85000) libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7e81000) libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7e68000) /lib/ld-linux.so.2 (0xb8073000) informix@irk:~$ ./test stores7 Connecting to DSN : stores7 Connected to stores7 TABNAME = systables TABNAME = syscolumns TABNAME = sysindices informix@irk:~$ |
在尝试设置第三方驱动程序管理器时,您可以检查以下问题来验证常见的连接级问题。
- INFORMIXDIR 环境变量可能设置不正确。
- INFORMIXSQLHOSTS 变量拥有针对 Informix 服务器的合适的值。
- 检查并确保共享库路径已正确设置,例如:LD_LIBRARY_PATH, SHLIB_PATH。
- 确保您使用了相同的 32 或 64 个二进制字节。您可以使用 file/truss/strace 这样的工具检查已加载哪些二进制文件,这可以发现环境中的错误。
- 您也可以使用 UnixODBC Driver 跟踪、ODBC Driver 跟踪或 SQLIDEBUG 调试问题。
一个示例错误为 [ISQL]ERROR: Could not SQLDriverConnect。
UnixODBC Driver 跟踪为您提供了从应用程序调用的 ODBC API 的名称信息,以及它们的参数。如果发生严重的问题,(有可能是 unixODBC 中的问题),您可以通过查看生成它的行号,在源代码文件中找到它。您可以将 ODBCINST.INI 文件中的 Trace 参数设置为 Yes 来启用跟踪,如清单 17 中所示。
清单 17. 将 Trace 参数设置为 Yes
[ODBC] ; Trace file Section ; Trace=Yes TraceFile=/tmp/odbctrace.out |
ODBC Driver 跟踪为你能提供了从应用程序调用的 ODBC API 的名称信息,以及它们的参数。当开发 ODBC 应用程序时,常见的错误常常发生在为 API 提供参数值时。您可以使用所提供的 ODBC Trace 工具,生成对 ODBC Driver 的所有 ODBC 调用的跟踪文件。在 Windows 系统上,您可使用 ODBC Data Source Administrator (odbcad32.exe) 启用 ODBC Trace。在 UNIX 机器上,您可在 ODBC.INI 文件中将 Trace 参数设置为 1 来启用跟踪,如清单 18 中所示。
清单 18. 在 UNIX 机器上启用跟踪
; Trace file Section ; Trace=1 TraceFile=/tmp/odbctrace.out InstallDir=/usr2/support/products/SDK-3.70.UC1 TRACEDLL=idmrs09a.so |
清单 19 中的输出显示了 ODBC 跟踪文件中的一些条目。
清单 19. ODBC 跟踪文件中的条目
ppid=0010303e,pid=00000001 EXIT SQLPrepare SQLHSTMT 0x20154AA8 SQLCHAR * select tabname from systables where tabid=1; SQLINTEGER 45 with return code 0 (SQL_SUCCESS) ppid=0010303e,pid=00000001 EXIT SQLPrepareW SQLHSTMT 0x20154AA8 SQLWCHAR select tabname from systables where tabid=1; SQLINTEGER -3 with return code 0 (SQL_SUCCESS) ppid=0010303e,pid=00000001 ENTER SQLExecute SQLHSTMT 0x20154AA8 ppid=0010303e,pid=00000001 EXIT SQLExecute SQLHSTMT 0x20154AA8 with return code 0 (SQL_SUCCESS) ppid=0010303e,pid=00000001 ENTER SQLNumResultCols SQLHSTMT 0x20154AA8 SQLSMALLINT * 804399056 ppid=0010303e,pid=00000001 EXIT SQLNumResultCols SQLHSTMT 0x20154AA8 SQLSMALLINT * 804399056 with return code 0 (SQL_SUCCESS) |
ODBC 使用 SQLI 协议与 IDS 服务器通信。SQLIDEBUG 跟踪包含在客户端应用程序与 IDS 服务器之间传递的所有消息。您可以在 Informix 客户端上通过以下方式定义的 SQLIDEBUG 环境变量来启用 SQLIDEBUG 跟踪:SQLIDEBUG=2:/tmp/sqlitrace。
Informix 通信库将跟踪传入一系列文件中的所有 SQLI 消息中,每个连接一个文件,还提供了 SQLIDEBUG 变量中提供的前缀路径。
SQLIDEBUG 包含在服务器与客户端之间传递的二进制格式的 SQLI 包。要获得可读的输出,则必须使用 sqliprint 工具(在 Windows 平台上名为 sqliprt.exe)。此工具也包含在 Informix CSDK 包中。
清单 20 中的输出展示了如何设置 SQLIDEBUG,以及如何解码所生成的 SQLI 跟踪文件。
清单 20. 设置 SQLIDEBUG
informix@irk:/usr3/370uc1$ export SQLIDEBUG=2:/tmp/sqlitrace informix@irk:/usr3/370uc1$ iusql test informix password +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ SQL> select tabid from systables where tabname='systables'; +------------+ | tabid | +------------+ | 1 | +------------+ SQLRowCount returns -1 1 rows fetched SQL> quit informix@irk:/usr3/370uc1$ ls -la /tmp/sqlitrace* -rwxr-xr-x 1 informix informix 766 2011-06-02 09:50 /tmp/sqlitrace_28920_12100_8627490 informix@irk:/usr3/370uc1$ informix@irk:/usr3/370uc1$ sqliprint -o trace.txt /tmp/sqlitrace_28920_12100_8627490 informix@irk:/usr3/370uc1$ |
清单 21 中的输出显示了解码的 trace.txt 文件中的一节。
清单 21. 解码的 trace.txt 文件
C->S (68) Time: 2011-06-02 09:50:06.84851 SQ_PREPARE # values: 0 CMD.....: "select tabid from systables where tabname='systables'; " [55] SQ_NDESCRIBE SQ_WANTDONE SQ_EOT S->C (62) Time: 2011-06-02 09:50:06.85346 SQ_DESCRIBE Stmt Type...........: 2 Server Stmt Id......: 0 Estimated Cost......: 0 Size of output tuple: 4 # output fields.....: 1 Size of string table: 6 0) Field 'tabid' Index into string table: 0 Starting offset in tuple: 0 Type....................: SERIAL; NOT NULLABLE Length : 4 (0x4) SQ_DONE |
您可以在 参考资料 一节中找到有关 ODBC 和 SQLIDEBUG 跟踪的更多信息。
本文可用作结合使用 Informix ODBC Driver 与第三方驱动程序管理器(比如 UnixODBC 和 Data Direct)的快速指南。此外,本文还提供了常见连接问题的疑难解答技巧和跟踪选项。
学习
- 参阅 IBM Informix ODBC Driver 指南,您可以在其中获得显示数据库服务器兼容性的所有 odbc.ini 配置参数的完整描述。
- 了解 IBM Informix ODBC Driver 的 数据库服务器兼容性。
- 访问 developerWorks 的 Informix 产品专题,查阅文章和教程,连接其他资源以充实您的 Informix 技能。
- 随时关注针对各种 IBM 产品和 IT 行业主题的 developerWorks 技术活动 和 网络广播。
- 在 developerWorks 中国网站 Information Management 专区 了解 Information Management 的更多信息。查找技术文档、操作文章、培训、下载、产品信息等。
- 关注 Twitter 上的 developerWorks。
- 观看 developerWorks 演示中心,其中包含的内容非常丰富,从面向初学者的产品安装和设置演示,到面向有经验的开发人员的高级功能。
获得产品和技术
- 下载 IBM Informix 客户端软件开发工具包 (SDK)。
- 下载 试用版:Informix Dynamic Server Express Edition V11.50。
- 下载 unixODBC Driver Manager。
- 在 IBM Informix 开发人员手册 中查找有关 ODBC 和 SQLIDEBUG 的更多信息。
- 使用 IBM 产品评估试用版软件 构建您的下一个开发项目,这些软件可直接从 developerWorks 下载获得,或者在 IBM SOA 人员沙箱 中花几小时学习如何有效实现面向服务的架构。
讨论
- 参与论坛讨论。
- 访问 developerWorks 博客 并加入 developerWorks 中文社区,developerWorks 社区是一个面向全球 IT 专业人员,可以提供博客、书签、wiki、群组、联系、共享和协作等社区功能的专业社交网络社区。

