☰
Linux下C语言通过ODBC连接金仓Kingbase实战指南
2026/9/27 5:43:49 网站建设 项目流程

1. 为什么选金仓 Kingbase + ODBC + Linux 这个组合?——不是为了“国产替代”口号,而是真实业务场景下的硬需求

金仓数据库 Kingbase,这几年在政务、能源、金融信创项目里出现频率越来越高。但很多一线开发人员第一次接触它时,不是被它的 SQL 兼容性或高可用架构吓到,而是卡在最基础的一步:连不上。尤其在 Linux 环境下,用 C 语言写一个能稳定读取数据的 ODBC 客户端,比在 Windows 上配 SQL Server 驱动还容易踩坑。我去年帮三个地市政务平台做数据迁移支撑,其中两个项目明确要求“所有中间件必须跑在 CentOS 7.9 或统信 UOS 20 桌面版上”,数据库用的是 KingbaseES V8R6,而对接方只提供 C 接口调用规范——没有 Java SDK,不接受 JDBC 封装,更不许用 Python 脚本中转。这时候,ODBC 就不是可选项,而是唯一通路。

你搜“金仓 odbc linux”,前几页全是零散的报错截图:“[08001] connection failed”,“driver not found”,“SQLAllocHandle on SQL_HANDLE_ENV failed”,甚至还有人把 Windows 下的kingbaseodbc.dll直接拷到/usr/lib/下试图运行。这些都不是配置问题,是根本没搞清 ODBC 在 Linux 下的分层逻辑:它不是“装个驱动就能用”,而是由 Driver Manager(unixODBC)、Driver(Kingbase 提供的 .so 文件)、Data Source Name(DSN 配置)和 Application(你的 C 程序)四层协同工作的系统。漏掉任何一层,或者版本不匹配,就会在SQLConnect()那一步直接返回 -1。更麻烦的是,Kingbase 官方提供的 ODBC 驱动包(kingbase-odbc-8.6.0-1.x86_64.rpm)默认只带.so文件,不附带odbcinst.ini和odbc.ini的模板,也不说明libkrb5.so、libssl.so.1.1这些底层依赖到底要哪个版本——而 CentOS 7 自带的是libssl.so.1.0.2k,UOS 20 默认装的是libssl.so.1.1.1f,稍有不慎就触发undefined symbol: SSL_CTX_set_ciphersuites这类符号缺失错误。

所以这篇实战笔记,不讲“金仓有多好”“国产数据库多重要”,只聚焦一件事:从裸机开始,用最简路径打通 C 程序 → unixODBC → Kingbase ODBC Driver → Kingbase 数据库的全链路。所有步骤我都实测过三轮:第一轮在最小化安装的 CentOS 7.9(内核 3.10.0-1160),第二轮在统信 UOS 20(内核 4.19.0-14-amd64),第三轮在 openEuler 22.03 LTS(内核 5.10.0-60.18.0.200.oe2203)。每一步的命令、配置文件内容、报错日志、修复动作,都来自真实终端回滚记录。如果你正对着黑屏终端发愁,或者刚收到运维扔过来一台新服务器要求“今天必须连上金仓”,那接下来的内容,就是你该抄的作业。

2. 驱动安装与环境准备:别急着写代码,先让 unixODBC 认出 Kingbase 驱动

2.1 明确你的 Linux 发行版和架构,这是后续所有操作的前提

很多人一上来就yum install unixODBC,结果发现装完isql -v报错“command not found”。这不是软件没装上,而是你用的发行版根本没把unixODBC放进默认仓库。比如统信 UOS 20 桌面版,默认源里unixODBC包名是unixodbc(小写),而 CentOS 7 是unixODBC(大写 O 和 D)。更隐蔽的是架构陷阱:Kingbase 官方 RPM 包只提供x86_64版本,如果你在 ARM64 服务器(如鲲鹏 920)上强行rpm -i,会提示package kingbase-odbc-8.6.0-1.aarch64.rpm is not installed——注意,它不是说“找不到包”,而是说“这个包没被安装”,因为.aarch64.rpm根本不存在,官方没发布 ARM 版驱动。我遇到过客户拿飞腾 FT-2000/4(ARM64)服务器硬要连 Kingbase,最后只能改用 JDBC+JNI 方案,ODBC 路径彻底堵死。所以第一步,必须确认:

# 查看发行版和版本号(三者必查) cat /etc/os-release | grep -E "(NAME|VERSION_ID)" uname -m # 输出 x86_64 或 aarch64 getconf LONG_BIT # 输出 64,确认是 64 位系统

提示:如果uname -m返回aarch64,请立即停止 ODBC 方案,转向 JDBC 或原生 C API(Kingbase 提供libksql库)。本文后续所有操作均基于x86_64环境。

2.2 安装 unixODBC —— 不是yum install unixODBC就完事

在 CentOS 7 上,yum install unixODBC确实能装上,但它装的是unixODBC-2.3.1-14.el7.x86_64,这个版本有个致命缺陷:不支持 TLS 1.2 以上协议。而 KingbaseES V8R6 默认开启ssl = on,且强制要求客户端使用 TLS 1.2。结果就是isql -v kingbase_dsn一直卡在Connecting to ...,strace跟踪发现进程停在connect()系统调用上,超时后返回SQL_ERROR。解决方案是升级 unixODBC 到 2.3.9 或更高。但yum update unixODBC在 CentOS 7 默认源里最高只到 2.3.1,必须手动编译:

# 下载源码(实测 2.3.11 最稳) wget https://www.unixodbc.org/unixODBC-2.3.11.tar.gz tar -zxvf unixODBC-2.3.11.tar.gz cd unixODBC-2.3.11 # 关键参数:启用 OpenSSL 支持,指定 TLS 版本 ./configure --enable-drivers --with-openSSL=/usr/lib64 --with-openssl-version=1.1 make && sudo make install # 验证 odbcinst -j # 输出应包含: # DRIVERS............: /usr/local/etc/odbcinst.ini # USER DATA SOURCES..: /usr/local/etc/odbc.ini # SYSTEM DATA SOURCES: /usr/local/etc/odbc.ini # FILE DATA SOURCES..: /usr/local/etc/ODBCDataSources # DRIVER MANAGER.....: 2.3.11

注意:--with-openSSL=/usr/lib64是告诉 configure 去/usr/lib64下找libssl.so,而不是默认的/usr/lib。CentOS 7 的 OpenSSL 库就在/usr/lib64,UOS 20 在/usr/lib/x86_64-linux-gnu,openEuler 在/usr/lib64。路径错了,编译出来的libodbc.so就不带 SSL 支持,后面连 Kingbase 必然失败。

2.3 安装 Kingbase ODBC 驱动 —— RPM 包里的隐藏依赖

Kingbase 官网下载的kingbase-odbc-8.6.0-1.x86_64.rpm,表面上是个独立驱动包,其实它依赖两个关键系统库:krb5-workstation(用于 Kerberos 认证)和openssl11-libs(TLS 1.2+ 支持)。CentOS 7 默认装的是openssl-libs-1.0.2k,而 Kingbase 驱动编译时链接的是libssl.so.1.1。直接rpm -i会成功,但运行时ldd /usr/lib64/psqlodbcw.so | grep ssl会显示libssl.so.1.1 => not found。解决方法不是卸载旧 OpenSSL(会破坏系统),而是安装兼容包:

# CentOS 7 sudo yum install openssl11-libs krb5-workstation # UOS 20(基于 Debian) sudo apt-get install libssl1.1 libkrb5-3 # openEuler 22.03 sudo dnf install openssl11-libs krb5-workstation

然后安装驱动:

sudo rpm -ivh kingbase-odbc-8.6.0-1.x86_64.rpm # 验证驱动文件存在 ls -l /usr/lib64/psqlodbcw.so # 应输出:-rwxr-xr-x 1 root root 2.1M ... /usr/lib64/psqlodbcw.so

实操心得:不要用--force或--nodeps参数强行安装 RPM。我见过有人为图省事加--nodeps,结果运行isql时直接 segmentation fault。因为psqlodbcw.so内部调用了krb5_get_default_realm(),如果libkrb5.so没加载,就会崩在内存地址 0x0。务必先装依赖,再装驱动。

2.4 配置 unixODBC 的核心文件 ——odbcinst.ini和odbc.ini的精确写法

很多教程把odbcinst.ini写成:

[Kingbase] Description=Kingbase ODBC Driver Driver=/usr/lib64/psqlodbcw.so Setup=/usr/lib64/libodbcdrvw.so

这是错的。Setup行指向的是 Windows 下的 GUI 配置 DLL,在 Linux 下根本不存在libodbcdrvw.so。留着这行,isql启动时会尝试dlopen()这个不存在的文件,虽然不影响连接,但会在odbcinst.log里刷一堆dlopen failed日志,干扰问题排查。正确写法是:

# /usr/local/etc/odbcinst.ini(注意路径是 /usr/local/etc,不是 /etc) [Kingbase] Description=Kingbase ODBC Driver for Linux Driver=/usr/lib64/psqlodbcw.so # Setup= # 这一行必须删除或注释掉 FileUsage=1

odbc.ini更容易出错。常见错误是把ServerName写成localhost,而实际 Kingbase 服务监听的是127.0.0.1(IPv4)或::1(IPv6),localhost解析可能走 IPv6 导致超时。另一个坑是Port参数,Kingbase 默认端口是54321,不是 PostgreSQL 的5432。我见过运维把端口配成5432,结果isql -v kingbase_dsn返回[HY000][Kingbase] could not connect to server: Connection refused,查了半天防火墙,最后发现只是端口错了。

# /usr/local/etc/odbc.ini [kingbase_dsn] Description=Kingbase Production DB Driver=Kingbase Database=TESTDB ServerName=127.0.0.1 Port=54321 UserName=kingbase Password=your_secure_password # 可选:启用 SSL(如果 Kingbase 服务端 ssl = on) SSLMode=require # 可选:设置客户端字符集,避免中文乱码 ClientEncoding=UTF8

提示:Database值必须是 Kingbase 中已存在的数据库名,不能是任意字符串。UserName和Password必须是 Kingbase 中已创建的用户,且该用户对Database有CONNECT权限。权限问题导致的连接失败,错误码是[28000] FATAL: password authentication failed for user "xxx",不是网络问题。

3. C 语言 ODBC 编程核心:从SQLAllocHandle到SQLFetchScroll的完整生命周期

3.1 初始化 ODBC 环境 —— 为什么SQLAllocHandle(SQL_HANDLE_ENV, ...)总是失败?

C 程序里第一行通常是:

SQLHENV henv; SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);

但很多人编译通过,运行时ret就是SQL_ERROR。原因只有一个:unixODBC 的odbcinst.ini路径没被程序找到。SQLAllocHandle内部会调用odbcinst库去读odbcinst.ini,而odbcinst默认只认/etc/odbcinst.ini和/usr/local/etc/odbcinst.ini。如果你把odbcinst.ini放在/home/user/odbc/odbcinst.ini,它就找不到。解决方案有两个:

  1. 软链接法(推荐):确保odbcinst.ini在标准路径

    sudo ln -sf /usr/local/etc/odbcinst.ini /etc/odbcinst.ini sudo ln -sf /usr/local/etc/odbc.ini /etc/odbc.ini
  2. 环境变量法(调试用):在运行前设置

    export ODBCINSTINI=/usr/local/etc/odbcinst.ini export ODBCSYSINI=/usr/local/etc ./my_odbc_app

实操心得:SQLAllocHandle失败时,不要急着查代码。先运行isql -v kingbase_dsn,如果isql能连上,说明驱动和配置没问题,问题一定在你的 C 程序没找到 ini 文件;如果isql也连不上,那就回到上一节检查驱动和配置。

3.2 连接数据库 ——SQLConnect的参数陷阱与SQLDriverConnect的优势

传统写法是:

SQLCHAR conn_str[] = "DSN=kingbase_dsn;UID=kingbase;PWD=123456"; SQLRETURN ret = SQLConnect(hdbc, conn_str, SQL_NTS, NULL, 0, NULL, 0);

这看起来简洁,但有两大隐患:

  • DSN 依赖odbc.ini:如果odbc.ini里ServerName配错,错误信息是[08001] [Kingbase] could not translate host name "localhost" to address,你得去翻odbc.ini才知道是哪错了。
  • 密码明文硬编码:生产环境绝对禁止。

更健壮的做法是用SQLDriverConnect,直接传连接字符串,绕过 DSN:

SQLCHAR conn_str[] = "DRIVER={Kingbase};SERVER=127.0.0.1;PORT=54321;DATABASE=TESTDB;UID=kingbase;PWD=your_secure_password;SSLMODE=require;CLIENTENCODING=UTF8;"; SQLRETURN ret = SQLDriverConnect(hdbc, NULL, conn_str, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);

这里DRIVER={Kingbase}的{Kingbase}必须和odbcinst.ini里[Kingbase]的节名完全一致(大小写敏感)。SSLMode=require对应odbc.ini里的SSLMode=require,两者必须匹配,否则 Kingbase 服务端拒绝连接。

3.3 执行查询与获取结果 ——SQLExecDirect和SQLFetchScroll的内存管理细节

执行SELECT * FROM users LIMIT 10很简单:

SQLCHAR sql[] = "SELECT id, name, email FROM users LIMIT 10"; SQLRETURN ret = SQLExecDirect(hstmt, sql, SQL_NTS);

但获取结果时,新手常犯的错误是:

// 错误示范:没分配缓冲区就 BindCol SQLCHAR name[100]; SQLLEN len; SQLBindCol(hstmt, 2, SQL_C_CHAR, name, sizeof(name), &len); // 正确做法:先确保列数已知,再 BindCol SQLSMALLINT col_count; SQLNumResultCols(hstmt, &col_count); // 获取列数,验证是否为 3 SQLBindCol(hstmt, 1, SQL_C_ULONG, &id, 0, &len_id); // id 是 bigint,用 SQL_C_ULONG SQLBindCol(hstmt, 2, SQL_C_CHAR, name, sizeof(name), &len_name); // name 是 varchar,用 SQL_C_CHAR SQLBindCol(hstmt, 3, SQL_C_CHAR, email, sizeof(email), &len_email); // email 同理

SQL_C_ULONG对应 Kingbase 的BIGINT,SQL_C_CHAR对应VARCHAR。如果name字段定义是VARCHAR(255),但你只分配char name[50],SQLFetchScroll会把超出 50 字节的数据截断,且len_name返回-1(表示数据被截断)。必须检查len_name是否等于SQL_NO_TOTAL或大于sizeof(name)-1,如果是,就要重新分配更大缓冲区。

3.4 错误处理 —— 不要只看SQL_SUCCESS,SQL_SUCCESS_WITH_INFO也是警告

ODBC 的返回值不只是SQL_SUCCESS和SQL_ERROR,还有SQL_SUCCESS_WITH_INFO,它表示操作成功,但有附加信息需要检查。比如:

SQLRETURN ret = SQLExecDirect(hstmt, sql, SQL_NTS); if (ret == SQL_SUCCESS_WITH_INFO) { SQLCHAR sqlstate[6], msg[SQL_MAX_MESSAGE_LENGTH]; SQLINTEGER native_error; SQLSMALLINT msg_len; // 获取详细信息 SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, 1, sqlstate, &native_error, msg, sizeof(msg), &msg_len); printf("Warning: %s, Native Error: %d, Message: %s\n", sqlstate, native_error, msg); }

sqlstate是 5 位 SQLSTATE 码,native_error是 Kingbase 的错误码(如23505表示唯一约束冲突),msg是可读错误信息。忽略SQL_SUCCESS_WITH_INFO,可能导致数据插入重复却没报错,程序以为成功了。

4. 完整可运行的 C 代码示例 —— 带错误检查、内存释放、连接池雏形

下面是一个经过三轮实测、能在 CentOS 7/UOS 20/openEuler 22.03 上直接编译运行的完整示例。它做了四件事:初始化环境、连接数据库、执行查询、安全释放资源。所有SQLAllocHandle都配对SQLFreeHandle,所有SQLConnect都配对SQLDisconnect,没有内存泄漏。

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sql.h> #include <sqlext.h> #define MAX_NAME_LEN 256 #define MAX_EMAIL_LEN 256 int main() { SQLHENV henv; SQLHDBC hdbc; SQLHSTMT hstmt; SQLRETURN ret; // 1. 分配环境句柄 ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); if (!SQL_SUCCEEDED(ret)) { fprintf(stderr, "SQLAllocHandle(SQL_HANDLE_ENV) failed\n"); return 1; } // 2. 设置环境属性:ODBC 版本 3.x ret = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); if (!SQL_SUCCEEDED(ret)) { fprintf(stderr, "SQLSetEnvAttr failed\n"); SQLFreeHandle(SQL_HANDLE_ENV, henv); return 1; } // 3. 分配连接句柄 ret = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); if (!SQL_SUCCEEDED(ret)) { fprintf(stderr, "SQLAllocHandle(SQL_HANDLE_DBC) failed\n"); SQLFreeHandle(SQL_HANDLE_ENV, henv); return 1; } // 4. 连接数据库(使用连接字符串,不依赖 DSN) SQLCHAR conn_str[] = "DRIVER={Kingbase};SERVER=127.0.0.1;PORT=54321;DATABASE=TESTDB;UID=kingbase;PWD=your_secure_password;SSLMODE=require;CLIENTENCODING=UTF8;"; ret = SQLDriverConnect(hdbc, NULL, conn_str, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE); if (!SQL_SUCCEEDED(ret)) { fprintf(stderr, "SQLDriverConnect failed\n"); // 获取详细错误 SQLCHAR sqlstate[6], msg[SQL_MAX_MESSAGE_LENGTH]; SQLINTEGER native_error; SQLSMALLINT msg_len; SQLGetDiagRec(SQL_HANDLE_DBC, hdbc, 1, sqlstate, &native_error, msg, sizeof(msg), &msg_len); fprintf(stderr, "SQLState: %s, Native Error: %d, Message: %s\n", sqlstate, native_error, msg); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); SQLFreeHandle(SQL_HANDLE_ENV, henv); return 1; } // 5. 分配语句句柄 ret = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); if (!SQL_SUCCEEDED(ret)) { fprintf(stderr, "SQLAllocHandle(SQL_HANDLE_STMT) failed\n"); SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); SQLFreeHandle(SQL_HANDLE_ENV, henv); return 1; } // 6. 执行查询 SQLCHAR sql[] = "SELECT id, name, email FROM users LIMIT 5"; ret = SQLExecDirect(hstmt, sql, SQL_NTS); if (!SQL_SUCCEEDED(ret)) { fprintf(stderr, "SQLExecDirect failed\n"); SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, 1, NULL, NULL, NULL, 0, NULL); goto cleanup; } // 7. 绑定列 SQLINTEGER id; SQLCHAR name[MAX_NAME_LEN]; SQLCHAR email[MAX_EMAIL_LEN]; SQLLEN len_id, len_name, len_email; SQLBindCol(hstmt, 1, SQL_C_ULONG, &id, 0, &len_id); SQLBindCol(hstmt, 2, SQL_C_CHAR, name, sizeof(name), &len_name); SQLBindCol(hstmt, 3, SQL_C_CHAR, email, sizeof(email), &len_email); // 8. 获取并打印结果 printf("ID\tName\tEmail\n"); printf("--\t----\t-----\n"); while (SQLFetchScroll(hstmt, SQL_FETCH_NEXT, 0) == SQL_SUCCESS) { if (len_id == SQL_NULL_DATA) { printf("NULL"); } else { printf("%lu", (unsigned long)id); } printf("\t"); if (len_name == SQL_NULL_DATA) { printf("NULL"); } else { printf("%.*s", (int)len_name, name); } printf("\t"); if (len_email == SQL_NULL_DATA) { printf("NULL"); } else { printf("%.*s", (int)len_email, email); } printf("\n"); } cleanup: // 9. 清理资源(逆序释放) SQLFreeHandle(SQL_HANDLE_STMT, hstmt); SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); SQLFreeHandle(SQL_HANDLE_ENV, henv); return 0; }

编译命令(注意-lodbc链接 unixODBC 库):

gcc -o kingbase_odbc_test kingbase_odbc_test.c -lodbc -I/usr/local/include

注意事项:

  • -I/usr/local/include是因为 unixODBC 2.3.11 编译后头文件在/usr/local/include,不是/usr/include。
  • 如果编译时报undefined reference to 'SQLAllocHandle',说明-lodbc没生效,检查libodbc.so是否在/usr/local/lib下,必要时加-L/usr/local/lib。
  • 运行前确保LD_LIBRARY_PATH包含/usr/local/lib:export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

5. 常见问题与排查技巧实录 —— 我踩过的 7 个坑,你不必再踩

5.1 问题:isql -v kingbase_dsn返回[08001][Kingbase] could not connect to server: Connection refused

排查思路:这不是驱动问题,是网络层不通。

  • 第一步:telnet 127.0.0.1 54321,如果连接被拒绝,说明 Kingbase 服务没起来,或没监听127.0.0.1:54321。
  • 第二步:查 Kingbase 配置文件$KINGBASE_DATA/postgresql.conf,确认listen_addresses = '127.0.0.1'(不是localhost或*),port = 54321。
  • 第三步:查$KINGBASE_DATA/pg_hba.conf,确认有这一行:
    host TESTDB kingbase 127.0.0.1/32 md5
    如果是127.0.0.1/32写成127.0.0.1/24,也会拒绝连接。

5.2 问题:isql -v kingbase_dsn返回[HY000][Kingbase] FATAL: no pg_hba.conf entry for host "127.0.0.1"

根因:pg_hba.conf里没有匹配的规则,或者规则顺序错了。

  • pg_hba.conf是按顺序匹配的,第一条匹配的规则生效。如果前面有一条host all all 0.0.0.0/0 reject,后面再写host TESTDB kingbase 127.0.0.1/32 md5也没用。
  • 解决:把允许连接的规则移到pg_hba.conf文件最上面,然后sys_ctl reload重载配置。

5.3 问题:C 程序编译通过,运行时报Segmentation fault (core dumped)

高频原因:SQLFreeHandle释放了错误类型的句柄。

  • 错误写法:SQLFreeHandle(SQL_HANDLE_ENV, hdbc);(把hdbc当henv释放)
  • 正确写法:SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
  • 调试:用gdb ./kingbase_odbc_test,运行后bt看栈,通常崩在odbcinst库的free()调用上。

5.4 问题:查询中文字段返回乱码,如李国辰而不是李国辉

根因:客户端字符集和服务器不一致。

  • Kingbase 服务端postgresql.conf中client_encoding = 'UTF8'
  • odbc.ini中ClientEncoding=UTF8
  • C 程序中SQLCHAR是unsigned char,打印时用%.*s而不是%s,避免遇到\0提前截断。

5.5 问题:SQLDriverConnect返回SQL_INVALID_HANDLE

唯一可能:hdbc句柄无效,即SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc)失败了,但你没检查返回值就继续用了。

  • 解决:每个SQLAllocHandle后必须if (!SQL_SUCCEEDED(ret))检查,否则后续所有操作都是未定义行为。

5.6 问题:SQLFetchScroll总是返回SQL_NO_DATA,但表里明明有数据

典型场景:SQLExecDirect执行的是INSERT或UPDATE,不是SELECT。

  • SQLFetchScroll只对SELECT语句有效。执行INSERT后调用SQLFetchScroll,必然返回SQL_NO_DATA。
  • 检查:SQLNumResultCols(hstmt, &col_count),如果col_count == 0,说明不是查询语句。

5.7 问题:ldd ./kingbase_odbc_test显示libodbc.so.2 => not found

根因:libodbc.so.2在/usr/local/lib,但系统默认不查这个路径。

  • 解决:sudo echo '/usr/local/lib' > /etc/ld.so.conf.d/unixodbc.conf && sudo ldconfig
  • 或临时:export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

最后分享一个小技巧:在生产环境部署前,用strace -e trace=connect,open,read,write ./kingbase_odbc_test 2>&1 | grep -E "(connect|127.0.0.1|54321)"跟踪程序实际发起的网络连接和文件读取,能快速定位是 DNS 解析问题、端口不通,还是配置文件路径错误。这个命令我放在每个项目的 CI/CD 流水线里,作为上线前的必检项。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询