db2 真的是别具一格,c语言直接访问 db2 数据库吧,得必须指定数据表名,编译的时候还得用 bind 进行绑定,并且把生成的绑定文件一起发布,遇到环境发生改变的时候,原来编译的程序,还得二次绑定和编译。使用 unixODBC 虽然可以避免这个问题吧,它的 odbc 配置居然和其他的不一样,奇葩了。
过程记录下一下,别忘记了。
首先配置 odbc 的访问:
在当前用户的主目录下,配置三个文件,分别是 .odbc.ini , .odbcinst.ini , .db2cli.ini , 内容如下:
.odbcinst.ini 文件
-
[PostgreSQL]
-
Description = ODBC for PostgreSQL
-
Driver = /usr/lib/psqlodbc.so
-
Setup = /usr/lib/libodbcpsqlS.so
-
Driver64 = /usr/lib64/psqlodbc.so
-
Setup64 = /usr/lib64/libodbcpsqlS.so
-
FileUsage = 1
-
-
[MySQL]
-
Description = ODBC for MySQL
-
Driver = /usr/lib/libmyodbc5.so
-
Setup = /usr/lib/libodbcmyS.so
-
Driver64 = /usr/lib64/libmyodbc5.so
-
Setup64 = /usr/lib64/libodbcmyS.so
-
FileUsage = 1
-
-
[ODBC]
-
Trace = yes
-
Tracefile = /tmp/odbc.log
-
-
[DB2]
-
Description = DB2
-
Driver = /opt/ibm/db2/V11.1/lib32/libdb2.so
-
Driver64 = /opt/ibm/db2/V11.1/lib64/libdb2o.so
-
FileUsage = 1
这里面,别的就不说明了,只说明重点看 DB2 的配置部分。
.odbc.ini 文件
-
[ODBC Data Sources]
-
dbschema = db2inst1
-
-
[sample]
-
Description = Sample
-
Driver = DB2
这里重点看 sample 段,这个部分我为了简单,和我在安装数据库的时候,利用 db2sample 生成的示例库采用了同一个名字。这个名字是可以修改的,你可以随意起一个名字,但是这个名字要与你下面在 .db2cli.ini 文件中定义的对应内容保持一致。
.db2cli.ini 文件
-
[sample]
-
hostname ="192.168.137.202"
-
pwd ="db2inst1"
-
port ="50000"
-
PROTOCOL =TCPIP
-
database ="sample"
-
uid ="db2inst1"
这里面的节点名 sample 和上面的 .odbc.ini 中的节点名字要保持一致。
特别注意说明的,db2 的 odbc 驱动参数,必须采用如下的方式进行配置,否则在下面的测试代码中,会造成连接数据库失败。
下面是我用 c 语言编写的通过 unixODBC 访问 DB2 数据库的示例代码。
testODBCConnectDB2.c
-
//testODBCConnectDB2.c;
-
-
#include <stdio.h>
-
#include <string.h>
-
#include <stdlib.h>
-
-
#include "sql.h"
-
#include "sqlcli.h"
-
#include "sqlext.h"
-
-
int main(void)
-
{
-
SQLHENV henv;//环境句柄
-
SQLHDBC hdbc;//连接句柄
-
SQLHSTMT hstmt;//语句句柄
-
SQLINTEGER len;
-
SQLCHAR szName[50];
-
SQLRETURN ret;
-
SQLSMALLINT columns;
-
-
int i = 0;
-
-
-
ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
-
ret = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
-
ret = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
-
-
if ((ret = SQLConnect(hdbc, (SQLCHAR *)"sample", SQL_NTS, (SQLCHAR *) "db2inst1", SQL_NTS, (SQLCHAR *) "db2inst1", SQL_NTS)) == SQL_ERROR)//连接数据库
-
{
-
printf("SQLConnect Error !\n");
-
return(-1);
-
}
-
-
SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt);
-
-
if ((ret = SQLExecDirect(hstmt, (SQLCHAR *) "select * from VPROJ", SQL_NTS)) == SQL_ERROR)// 执行语句
-
{
-
printf("SQLExecDirect Error !\n");
-
return(-2);
-
}
-
SQLNumResultCols(hstmt, &columns); // 获取每行的列数
-
while (SQL_NO_DATA != SQLFetch(hstmt))
-
{
-
for ( i = 0 ; i <= columns ; i++ )
-
{
-
bzero(szName,50);
-
SQLGetData (hstmt, i, SQL_C_CHAR, szName, 50, &len);//读取数据
-
if ( i == 0 )
-
printf("%s ", szName);
-
else
-
printf("| %s ", szName);
-
-
if ( i == columns )
-
printf("\n");
-
}
-
}
-
-
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
-
SQLDisconnect(hdbc);
-
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
-
SQLFreeHandle(SQL_HANDLE_ENV, henv); return(0);
-
}
这个代码是我拿别人的代码进行修改的,原代码在编译的时候没有通过,我进行了小改动。
改动的地方不重要,重要的说明是如下语句:
-
if ((ret = SQLConnect(hdbc, (SQLCHAR *)"sample", SQL_NTS, (SQLCHAR *) "db2inst1", SQL_NTS, (SQLCHAR *) "db2inst1", SQL_NTS)) == SQL_ERROR)//连接数据库
注意这个中间的 sample , 这个是服务名,也就是你的 .odbc.ini 和 .db2cli.ini 中配置的数据源的节点名称。
{BANNED}中国第一个 db2inst1 是访问 db2 数据库的用户名,也就是在 .db2cli.ini 中配置的 uid , 第二个 db2inst1 是访问 db2 数据库的用户的密码,也就是在 .db2cli.ini 中配置的 pwd 。
其他地方没有要说明的了。
Makefile 文件:
-
#makefile:
-
-
#DB2PATH为DB的安装目录
-
DB2PATH=/opt/ibm/db2/V11.1
-
-
INCL = -I $(DB2PATH)/include -I. -I $(HOME)/source_code/include
-
-
all: testodbc
-
-
DEFINES = -m64 -D _LINUX_
-
-
.SUFFIXES:.c.o
-
.c.o:
-
$(CC) $(DEFINES) $(INCL) -c $*.c
-
-
objs= testODBCConnectDB2.o
-
-
testodbc: $(objs)
-
gcc -o testodbc $(objs) -lncurses -lrt -lpthread -L $(DB2PATH)/lib64 -ldb2
-
-
clean:
-
rm -rf *.o testodbc
仅作为记录吧 。
补充说明一下:
当前用户的 .bashrc 文件中,必须添加如下语句,否则会造成 odbc 访问 db2 数据库失败。
if [ -f /home/db2inst1/sqllib/db2profile ]; then
. /home/db2inst1/sqllib/db2profile
fi
阅读(207) | 评论(0) | 转发(0) |