本文介绍如何使用 Odbc 连接 Kingbase 数据库,并提供连接代码示例。
前提条件
确保已设置基本的应用开发环境。
确保已安装与驱动对应版本的数据库,且数据库连接可用。
确保当前支持 Odbc 开发:
- Linux:确保已安装 unixOdbc
- Windows:默认支持 Odbc
确保 Odbc 支持开发环境:
系统架构:
Linux:x86_64、arm、loongarch、mips、sw
Windows:V9 版本提供64位支持
编译器:
Linux:仅支持依赖 glibc 的编译器
Windows:依赖 msvc120 的运行时库
满足以上条件后,可通过金仓官网下载页面(电科金仓-成为世界卓越的数据库产品与服务提供商)获取对应版本架构的 Dci 驱动。
操作实例 - Linux
安装并部署驱动
Odbc 驱动包目录如下所示:
Odbc
├── kdbodbcw.so
├── libcrypto.so.1.1
├── libkci.so.5
├── libodbcinst.so.2
└── libssl.so.1.1
先确保当前环境已经安装 unixOdbc(推荐安装 unixOdbc-2.3.4)
下载 unixOdbc 源码包,执行以下命令编译安装:
./configure --prefix=`pwd`/release make make install
复制安装后,可通过
odbcinst --version
查看 unixOdbc 版本:unixODBC 2.3.4
复制创建测试程序文件夹 test_odbc,文件夹目录如下所示:
test_odbc
├── lib
│ ├── kdbodbcw.so
│ ├── libcrypto.so.1.1
│ ├── libkci.so.5
│ ├── libodbcinst.so.2
│ └── libssl.so.1.1
├── Makefile
├── odbc.ini
├── odbcinst.ini
└── test_odbc.c以下所有操作均在该路径下进行。
配置 Odbc 数据源
新建文件 odbcinst.ini 和 odbc.ini
- odbcinst.ini 配置如下所示,生成了一个 kdbodbc test driver 的驱动配置, Driver 用于指定 Odbc 驱动路径:
[kdbodbc test driver] Description = KingbaseES ODBC driver (Unicode version), for regression tests Driver = /home/kingbase/test_odbc/lib/kdbodbcw.so
复制- odbc.ini 配置如下所示,生成了一个 DSN 名为 KingbaseES 的 Odbc 配置,Driver 指向 kdbodbc test driver 的驱动路径,该配置文件用于指定 Odbc 连接参数及配置信息:
[KingbaseES] Description = kdbodbc regression test DSN Driver = kdbodbc test driver Servername = 127.0.0.1 Port = 54321 Username = system Password = 123456 Database = test
复制配置对应文件后,可将配置路径添加到当前命令行窗口的环境变量中,使 unixOdbc 能正确识别 Odbc 驱动配置信息。
以下是一个将当前路径下的 odbcinst.ini 和 odbc.ini 添加到环境变量的示例:
export ODBCSYSINI=. export ODBCINSTINI=./odbcinst.ini export ODBCINI=./odbc.ini
复制配置完成后,可通过
odbcinst -j
查看信息:unixODBC 2.3.4 DRIVERS............: ./ SYSTEM DATA SOURCES: ./odbc.ini FILE DATA SOURCES..: ./ODBCDataSources USER DATA SOURCES..: ./odbc.ini SQLULEN Size.......: 8 SQLLEN Size........: 8 SQLSETPOSIROW Size.: 8
复制测试 Odbc 驱动能否连接到数据库
使用 unixOdbc 的命令
isql DSNName
,可通过 unixOdbc 直接测试驱动是否成功加载并尝试连接到数据库,示例如下:$ isql KingbaseES +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+
复制
开发源程序
以下是一个插入并执行查询的具体示例。
导入 unixOdbc 的头文件:
#include "sql.h" #include "sqlext.h"
复制初始化 Odbc 环境
使用
SQLAllocHandle()
创建 SQLHENV 实例,创建成功后,使用SQLSetEnvAttr()
设置刚刚创建的 SQLHENV 实例:SQLHENV hEnv; // 1. 初始化 ODBC 环境 SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv); SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
复制连接数据库
使用
SQLAllocHandle()
创建 SQLHDBC 实例,创建成功后,使用SQLConnect()
连接到数据库:SQLHDBC hDbc; SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc); // SQLConnect(hDbc, DSN, SQL_NTS, user, SQL_NTS, password, SQL_NTS) SQLConnect(hDbc, (SQLCHAR*)"KingbaseES", SQL_NTS, (SQLCHAR*)"system", SQL_NTS, (SQLCHAR*)"123456", SQL_NTS);
复制创建测试表
使用
SQLAllocHandle()
创建 SQLHSTMT 实例,用于执行 SQL 语句相关操作,建表语句不需要绑定参数,使用SQLExecDirect()
执行 SQL:SQLHSTMT hStmt; const char *sqlDropTb = "drop table if exists test_odbc;"; const char *sqlCreateTb = "create table test_odbc (id int, name varchar(100));"; // 3. 创建表 SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt); SQLExecDirect(hStmt, (SQLCHAR*)sqlDropTb, SQL_NTS); SQLExecDirect(hStmt, (SQLCHAR*)sqlCreateTb, SQL_NTS);
复制插入数据
使用
SQLPrepare()
创建插入的预备语句,创建成功后,使用SQLBindParameter()
绑定参数,最后使用SQLExecute()
执行 SQL:// 4. 插入数据(绑定参数) const char *sqlInsertTb = "insert into test_odbc values (?, ?)"; SQLINTEGER inId = 1; SQLCHAR inName[] = "KKKingbase"; SQLPrepare(hStmt, (SQLCHAR*)sqlInsertTb, SQL_NTS); SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &inId, 0, NULL); SQLBindParameter(hStmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 100, 0, inName, 0, NULL); SQLExecute(hStmt);
复制查询并打印结果集
使用
SQLExecDirect()
执行查询,再使用SQLBindCol()
绑定输出的查询结果,循环使用SQLFetch()
遍历结果集并打印结果:// 5. 执行查询 SQLRETURN ret; const char *sqlSelectTb = "select * from test_odbc"; SQLINTEGER outId; SQLCHAR outName[100]; SQLExecDirect(hStmt, (SQLCHAR*)sqlSelectTb, SQL_NTS); // 绑定查询结果 SQLBindCol(hStmt, 1, SQL_C_LONG, &outId, 0, NULL); SQLBindCol(hStmt, 2, SQL_C_CHAR, outName, sizeof(outName), NULL); // 获取查询结果并打印 while ((ret = SQLFetch(hStmt)) != SQL_NO_DATA) { if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) { printf("ID: %d, Name: %s\n", outId, outName); } else { CHECK_ERROR(ret, hStmt, SQL_HANDLE_STMT); } }
复制释放资源
// 6. 清理 SQLFreeHandle(SQL_HANDLE_STMT, hStmt); SQLDisconnect(hDbc); SQLFreeHandle(SQL_HANDLE_DBC, hDbc); SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
复制
编译
使用 gcc 编译,需要显示指定 unixOdbc 库文件安装路径,以下是示例使用的 Makefile:
all:prog LDFLAGS = -L unixOdbc/lib -lodbc CFLAGS = -g -Wall CPPFLAGS = -I unixOdbc/include ODBC_CONFIG = unixOdbc/bin/odbc_config LIBODBC := $(shell $(ODBC_CONFIG) --libs) prog: test_odbc.c gcc test_odbc.c $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o testOdbc $(LIBODBC) clean: -rm testOdbc
复制
备注
Makefile 中涉及的 unixOdbc 路径需要自行修改为实际安装的 unixOdbc 路径。
编写好 Makefile 后,使用 make
命令编译程序:
$ make
复制
会在当前路径下生成 testOdbc 的可执行程序。
运行
运行程序,程序期望输出如下:
$ ./testOdbc Connected to the database. Table created successfully. Data inserted successfully. ID: 1, Name: KKKingbase
复制
驱动包 SSL 库与系统环境的 SSL 库冲突
原因:系统环境的依赖库版本过高,或应用程序运行时错误加载了系统环境的SSL库。
解决:Linux 下可通过 ldd 应用程序名,如
ldd testOdbc
查看当前环境下的依赖关系,确保运行应用程序时加载驱动包提供的 SSL 库,若仍然有 SSL 相关报错,则确定是驱动包提供的 SSL 库无法在当前环境下使用,此时请联系技服获取 Odbc 静态依赖 SSL 库的驱动包来解决 SSL 依赖冲突问题。