简介:Informix Client SDK 4.10 for Windows 是面向 Windows 32 位平台数据库应用开发者的客户端开发套件,主要用于构建、调试和维护与 Informix 数据库交互的应用程序,适合需要维护旧系统连接层或进行数据库迁移升级的开发与运维人员。压缩包共 13 个文件,约 176.72MB,以 6 个 txt 技术参考、3 个 dll 运行库、1 个 properties 连接配置、1 个 pdf 安装文档、1 个 html 发布说明和 1 个 exe 安装程序为主,覆盖 ODBC、OLEDB、ESQL/C、C++、.NET 等接口说明,便于按技术栈查阅。其价值在于提供 JAB/JDBC 访问接口、连接参数配置样例以及开发者指南和 API 参考,读者可据此理解客户端连接配置、错误处理、性能优化与安全设置,并了解 OAT 在线应用传输在数据库升级迁移中的配置思路。已有 620 人学习,适合作为 Informix 客户端开发与运维的案头参考资料。
1. Informix Client SDK 4.10 For Windows:老系统迁移时为什么还得回头找它
去年帮一个做生产报表的团队换机器,后台数据库是十几年前上的,前端那台 Windows 机器一关机就再也起不来。新机器装好系统,Excel 连不上、老 C 程序跑不起来、连库里的表名都读不到,翻了一下午才发现缺的不是数据库,而是客户端开发包。这类现场里,Informix Client SDK 4.10 For Windows 就是那个“补丁”——它把 ODBC 驱动、ESQL/C 预编译器、SetNet32 配置工具、dbaccess 验证工具和一整套演示程序打在一个安装包里,装上之后,老的 C 程序重新编译、Excel 和自研小工具重新取数才有落脚点。
这篇写给还在维护存量 Informix 系统、需要在 Windows 侧重装客户端或做数据抽取的人。新项目选型不用往下看,这套东西的价值全在“把已经跑了很多年的东西接上”,而不是“从头搭一套新的”。
2. 拆开安装包:ODBC 驱动和 ESQL/C 预编译器各管一段路
搜这个包的人经常会看到两种写法,informix client sdk 4.10和informix client sdk 4.1.0,指的是同一个 4.10 系列,只是历史版本号的书写习惯不同,下载时别被版本号写法带偏。装之前先把它内部的几块东西分清楚,后面配不通的时候才知道该查哪一层。
2.1 四类组件与它们各自解决的连接问题
打开安装目录,bin、lib、incl、etc这几个子目录基本能把整套东西的功能暴露出来。
ODBC 驱动是大多数人真正要用的那一块。它注册到 Windows 的 ODBC 子系统里,Excel、Power BI、C# 的System.Data.Odbc、C++ 里直接调 ODBC API 的程序,都通过它和数据库说话。驱动本身只负责协议转换,它不知道你的服务器在哪、端口是多少,这些信息来自 sqlhosts 条目和连接串。
ESQL/C 是另一条完全不同的路。它不是运行期组件,而是编译期工具:esql这个命令把.ec文件中EXEC SQL开头的语句翻译成 C 函数调用,再交给 Visual C++ 的编译器生成 exe。用这条路的前提是你手里有源码。只有二进制的时候,ESQL/C 帮不上忙,只能走 ODBC 或者找厂商要新版本。
SetNet32 是配置入口,图形界面,改完之后落到注册表和 sqlhosts 文件里。它管的是“这台机器怎么找到那台数据库服务器”,包括主机名、协议、服务名、服务器名和一批环境变量。很多人配不通连接,问题就出在这一层,而不是驱动。
剩下的是验证工具,dbaccess 最常用,ilogin 也能做连通性测试。它们的价值在于把“驱动有没有装对”和“网络通不通”这两件事拆开判断——装完先跑 dbaccess,通了再折腾应用程序,顺序反了会浪费很多时间。
2.2 32 位和 64 位安装包怎么选
Windows 上这两个安装包是分开的,选错的表现非常典型:程序报“未找到数据源名称”或者“指定的 DSN 包含驱动程序和应用程序之间的体系结构不匹配”。
判断依据只有一个,看调用方的位数,不看操作系统的位数。64 位 Windows 上照样可以跑 32 位程序,照样需要 32 位驱动。常见的踩坑组合是老版本的取数工具是 32 位的,机器重装成 64 位系统之后顺手装了 64 位驱动,结果工具一直连不上,查半天网络都没问题。
ODBC 数据源管理器本身也分两套:
- 64 位:
C:\Windows\System32\odbcad32.exe - 32 位:
C:\Windows\SysWOW64\odbcad32.exe
名字容易看反,SysWOW64 那个才是 32 位的。在 64 位管理器里建的 DSN,32 位程序看不见,反之亦然。
两个版本能不能装同一台机器?我一般会分开目录装,各自设自己的INFORMIXDIR,不往同一个目录覆盖。同目录覆盖安装容易把驱动注册项和 PATH 里的 DLL 搅在一起,后面查版本会非常痛苦。
2.3 装之前先做五项核对
装包本身不复杂,翻车基本都在装完才发现信息不全。装之前我会先把这五项确认掉,能省掉后面一半的返工。
| 核对项 | 怎么确认 | 缺了会怎样 |
|---|---|---|
| 服务器名(DBSERVERNAME) | 问 DBA,或在服务端onstat -c里找 | 连接串里 Server 字段填错,报 -908 |
| 监听端口 | 服务端 sqlhosts 对应条目的服务名/端口 | 网络层直接连不上,超时 |
| 网络可达 | Test-NetConnection 主机 -Port 端口 | 报连接失败,误判成驱动问题 |
| 应用位数 | 看 exe 是 32 位还是 64 位 | 装错安装包,报架构不匹配 |
| 安装账号权限 | 本地管理员 | 驱动注册项写不进 HKLM,DSN 建不出来 |
数据库账号和权限另外算,那属于服务端的事。客户端这边最容易被忽略的是端口——很多现场只记得服务器名,端口是默认值还是自定义的没人记得,装完连不上再回头查,来回折腾。
3. 用 SetNet32 配一条 onsoctcp:从主机名到连接串
客户端装完之后的所有配置,本质上是在回答一个问题:给定一个服务器名,怎么找到那个 IP 的那个端口。Informix 的做法是靠 sqlhosts 条目,SetNet32 只是这个文件的图形化编辑器。
3.1 在 SetNet32 里建条目
从开始菜单打开 SetNet32,先看 Host Information 页。这一页填错任何一个字段都连不上,逐个说清楚。
- Current Host:本机保存的一组配置的别名,随便起,只影响本机保存多套环境时怎么区分
- HostName:数据库服务器的 IP 或可解析的主机名。内网环境我直接填 IP,省掉 DNS 这一层不确定性
- Protocolname:TCP 网络一般选
onsoctcp,这是最常见的组合 - Service Name:服务名或端口号,填
9088这种数字最省事,填服务名要确保 services 文件里有对应记录 - Server Name:数据库服务器名,必须和服务端 sqlhosts 里的名字完全一致,大小写敏感
- Options:一般留空,走 SSL 或特定网络配置时才需要
- User Name / Password:可以留空,运行时再输入,把密码写进注册表不是好习惯
填完点 “Make Default”,让它对整台机器生效。不点的话只写到当前用户下,换一个账号登录就没了,这是很隐蔽的一个坑。
Environment 页里有几个变量值得顺手设掉:INFORMIXSERVER指向刚建的那个服务器名,INFORMIXDIR指向安装目录,CLIENT_LOCALE和DB_LOCALE留到字符集那一节再统一处理。改完这些,注册表里HKEY_CURRENT_USER\Software\Informix\Setnet32下会多出一组键值,可以用 regedit 核对一眼。
3.2 手写 sqlhosts 和服务名登记的场合
图形界面在单机场景够用,但要批量部署、要写进交付脚本,就得直接动文件。
sqlhosts 文件的位置由环境变量INFORMIXSQLHOSTS指定,默认是%INFORMIXDIR%\etc\sqlhosts。一行一条记录,字段之间用空白分隔:
# dbservername nettype hostname servicename options ol_app onsoctcp 10.0.0.21 9088第一列是客户端认的服务器名,必须和连接串里Server=的值一致。第二列是网络协议,和 SetNet32 里选的 Protocolname 对应。第三列是主机,第四列是端口或服务名。以#开头的是注释。
服务名要额外登记到 Windows 的 services 文件,路径是C:\Windows\System32\drivers\etc\services,追加一行:
sqlexec 9088/tcp如果 sqlhosts 里直接写数字端口,这一步可以跳过。但只要有一个环境用了服务名写法,就得保证每台机器上都有这条记录,否则报错信息会非常含糊,只说连不上,不说为什么。
改完文件之后,环境变量也要跟上。命令行里临时设一份,验证阶段够用:
set INFORMIXDIR=C:\Informix\Client-SDK set INFORMIXSERVER=ol_app set INFORMIXSQLHOSTS=%INFORMIXDIR%\etc\sqlhosts set PATH=%INFORMIXDIR%\bin;%PATH%INFORMIXSERVER就是连接时的默认服务器名,配好之后 dbaccess 不带参数也能连上。PATH里加bin目录是为了让dbaccess、esql这些命令能被直接找到,不加的话只能 cd 进去跑。
3.3 用 dbaccess 做第一次握手
配置完别急着开应用程序,先用 dbaccess 验证。它是最小依赖的客户端,能把“配置对不对”和“程序写得对不对”分开。
dbaccess -V先看版本能不能跑起来。能打印版本,说明 DLL 加载没问题。然后再连库:
echo select count(*) from systables; | dbaccess appdb -appdb换成实际库名,-表示 SQL 从标准输入读。这条命令能返回一个数字,说明从主机解析、端口、协议、认证到 SQL 执行整条链路是通的。
连不上的时候,dbaccess会给出 SQLCODE。常见的几个值:-908 是连不上服务器,方向是主机名或端口;-329 是认证失败;-23101 及附近一段是 locale 相关。看错误码比看文字描述准得多。
想确认服务端 locale,可以连上之后查系统表:
echo "select * from sysmaster:sysdbslocale;" | dbaccess sysmaster -这条查的是每个库的 locale 设置,客户端DB_LOCALE要和目标库那一行对上,后面字符集一节还会用到。
3.4 ODBC 连接串的字段拆解
dbaccess 通了,ODBC 不一定通——它走的是驱动注册项,和 command line 工具是两套路径。
先在 ODBC 管理器里确认驱动已经注册。命令行更快:
Get-OdbcDriver | Where-Object { $_.Name -like "*INFORMIX*" } | Select-Object Name, Platform这条列出本机所有名字里带 INFORMIX 的驱动,Platform会告诉你是 32 位还是 64 位。名字要原样抄到连接串里,多一个括号少一个版本后缀都会报 IM002。
连接串的样子:
Driver={IBM INFORMIX ODBC DRIVER (64-bit)}; Host=10.0.0.21; Server=ol_app; Service=9088; Protocol=onsoctcp; Database=appdb; Uid=informix; Pwd=******;每个字段的含义和 sqlhosts 一一对应:Host是主机,Server是服务器名,Service是端口,Protocol是协议,Database是目标库。Driver的值必须和上一步查到的完全一致,机器上如果注册名不带位数后缀,就照实际查到的写。
连接串可以直接用,也可以先建成 DSN,再让程序引用 DSN 名。我倾向直接写连接串,配置文件一放就能换环境,不用每台机器去点 ODBC 管理器。代价是连接串里出现明文密码,得靠配置文件权限兜着。
4. 两条调用链落地:ESQL/C 编译和 ODBC 程序接入
配置通了以后,剩下的是应用侧怎么调。两条路差别很大,选哪条取决于你手里有没有源码。
4.1 esql 命令与 Visual C++ 环境
ESQL/C 的编译命令本身很简单,难的是它依赖 C 编译器,而 Windows 上 C 编译器来自 Visual Studio,环境变量没配好就会报找不到 cl.exe。
call "C:\Program Files\Microsoft Visual Studio\VC\vcvarsall.bat" x86 set INFORMIXDIR=C:\Informix\Client-SDK set PATH=%INFORMIXDIR%\bin;%PATH% esql -o demo.exe demo.ec第一行加载 VC 的编译环境,x86表示编 32 位程序,编 64 位就换成x64,这个参数必须和安装的 CSDK 位数一致。第二行第三行把esql加进 PATH。第四行是实际编译,-o指定输出文件名。
对应的.ec源文件大概长这样:
#include <stdio.h> EXEC SQL include sqlca; int main(void) { EXEC SQL BEGIN DECLARE SECTION; char srv[64] = "appdb"; int cnt = 0; EXEC SQL END DECLARE SECTION; EXEC SQL connect to :srv; if (sqlca.sqlcode != 0) { printf("connect failed, sqlcode=%d\n", sqlca.sqlcode); return 1; } EXEC SQL select count(*) into :cnt from systables; printf("tables=%d\n", cnt); EXEC SQL disconnect current; return 0; }两个细节值得说。所有要传给 SQL 的宿主变量,必须写在EXEC SQL BEGIN DECLARE SECTION和END DECLARE SECTION之间,写在区间外esql识别不到,编译期就报错。sqlca是通信区,sqlcode为 0 表示成功,负数是错误码,正好和 dbaccess 报的那套对得上,排查时可以互相印证。
esql会自己拼出 include 路径和库路径,一般不用手写-I和-L。如果报找不到sqlca.h之类的头文件,先确认INFORMIXDIR有没有设对,而不是急着加参数。
4.2 ODBC 程序里 SQLDriverConnect 的写法
C 里直接调 ODBC API 的代码长一些,但胜在不依赖编译器版本,换台机器重新编也能过。
#include <windows.h> #include <sql.h> #include <sqlext.h> #include <stdio.h> int main(void) { SQLHENV henv = SQL_NULL_HENV; SQLHDBC hdbc = SQL_NULL_HDBC; SQLRETURN rc; char conn[512] = "Driver={IBM INFORMIX ODBC DRIVER (64-bit)};" "Host=10.0.0.21;Server=ol_app;Service=9088;" "Protocol=onsoctcp;Database=appdb;Uid=informix;Pwd=secret;"; 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); rc = SQLDriverConnect(hdbc, NULL, (SQLCHAR *)conn, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { printf("connect failed, rc=%d\n", rc); return 1; } printf("connected\n"); SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); SQLFreeHandle(SQL_HANDLE_ENV, henv); return 0; }SQLSetEnvAttr里指定 ODBC 3.x 版本,不设的话有些驱动行为会退回旧语义。SQLDriverConnect的最后一个参数SQL_DRIVER_NOPROMPT表示不许弹窗,无人值守场景必须加上,否则跑到一半卡在对话框上。编译时要链接odbc32.lib,头文件用系统自带的sql.h就行,不需要 Informix 的特定头文件。
这套代码的好处是不依赖INFORMIXDIR,只要驱动注册好、连接串写对就能跑。迁移的时候把连接串抽到配置文件里,换环境改一个文件就够。
4.3 CLIENT_LOCALE 和 DB_LOCALE 对齐
中文环境里字符集是最容易出玄学问题的地方:数据能取到,但显示成问号;或者反过来,写进去的中文查出来乱码。
规则不复杂:DB_LOCALE设置的是数据库使用的字符集,CLIENT_LOCALE设置的是客户端和数据之间转换用的字符集。两者必须兼容,最简单的做法是设成一样的。
set CLIENT_LOCALE=zh_CN.GB18030-2000 set DB_LOCALE=zh_CN.GB18030-2000如果库里存的是 GBK,就都设成zh_CN.57372;纯英文库用en_US.819也行。关键是先查清楚目标库实际是什么,用 3.3 节那条查sysdbslocale的命令,看目标库那一行的值,客户端照着设。
ODBC 连接串里也能带这两个参数,效果和环境变量一样:
CLIENT_LOCALE=zh_CN.GB18030-2000;DB_LOCALE=zh_CN.GB18030-2000;不是所有驱动版本都认连接串里的这两个键,设了没生效就退回环境变量。写完记得重启应用,环境变量是进程启动时读的,改完不重启不生效——这个坑我踩过,改了半天以为没起作用。
5. 避坑与排查:五类高频翻车现场的处理顺序
下面这五条是按出现频率排的,遇到问题建议从上往下过一遍,别一上来就重装。
5.1 连接阶段的三类报错
现象一:报“未找到数据源名称,并且未指定默认驱动程序”,错误码 IM002。
原因:连接串里的Driver=值和本机注册表里的实际驱动名对不上,或者根本就是位数装错了——64 位程序加载 32 位驱动注册项。
解决:先用Get-OdbcDriver把本机实际名字打出来,原样抄进连接串。再确认程序的位数和驱动的位数一致,可以用Platform字段核对。两个版本都装了的话,注意连接串里的名字带不带(64-bit)后缀,别抄错。
现象二:dbaccess 报 -908,网络层面能 ping 通但连不上。
原因:三种可能——sqlhosts 里的服务器名和服务端不一致;端口填错或服务名没在 services 文件里登记;主机名解析失败,特别是填了主机名但 DNS 不认的情况。
解决:按顺序验证。先Test-NetConnection 10.0.0.21 -Port 9088确认端口可达;再核对 sqlhosts 第一列和服务端onstat -c里的 DBSERVERNAME 是否一致;主机字段直接换成 IP,绕开解析问题。三步走完基本能定位。
现象三:中文数据变成问号或乱码,连接本身是通的。
原因:CLIENT_LOCALE和DB_LOCALE没设,或者设了没重启应用,或者两者不匹配。
解决:查sysmaster:sysdbslocale拿到目标库的实际 locale,把两个变量设成一致,然后彻底重启进程。命令行里set只对当前窗口生效,服务方式跑的应用要改系统环境变量或者服务配置。
5.2 编译期和运行期的两个坑
现象四:esql报找不到cl.exe,或者编译一半报头文件缺失。
原因:没有加载 Visual Studio 的编译环境,或者vcvarsall.bat的位数参数和 CSDK 位数不一致。
解决:先call vcvarsall.bat x86(或x64)再跑esql,顺序不能反。位数必须和安装的 CSDK 对齐,32 位 CSDK 配 64 位编译器会在链接阶段报符号找不到。路径里有空格记得加引号。
现象五:同一台机器以前装过旧版客户端,新装的版本行为不对,或者程序启动就报找不到入口点。
原因:PATH 里旧版本的bin目录排在前面,进程加载了旧版 DLL,和头文件版本对不上。
解决:把INFORMIXDIR和 PATH 里的路径统一到新目录,用where dbaccess确认实际调用的是哪个。旧版本目录没删干净的话,光改环境变量不够,注册表里的驱动项也可能还指向旧路径,得一并清理。
这五个坑覆盖了大部分现场问题。剩下的零散情况,比如权限不足写不进注册表、防火墙拦了端口,报错信息都比较直白,反而好处理。
6. 交付前的收尾:静默安装、环境固化和一次自检
单机自己用,装完能连上就算完事。要交付到十几台机器上,就得把安装和配置都做成脚本,否则每台都靠手点,迟早出错。
6.1 静默安装与环境固化
安装包基于 InstallShield,静默安装的常见写法是:
setup.exe /s /v"/qn /l*v C:\temp\csdk_install.log"/s表示走静默模式,/v后面的参数透传给内部的 MSI 引擎,/qn是不显示界面,/l*v打详细日志。不同 build 的参数细节会有差异,第一次跑务必留日志,装完先看日志末尾有没有 1603 之类的错误码,再确认目录和驱动项都生成了。
环境变量用setx写进系统,比手工点开系统属性可靠:
setx INFORMIXDIR "C:\Informix\Client-SDK" /M setx INFORMIXSERVER "ol_app" /M setx INFORMIXSQLHOSTS "C:\Informix\Client-SDK\etc\sqlhosts" /M/M表示写系统级变量,不加就只写当前用户。写完之后新开的命令行才读得到,已经打开的窗口不会刷新。
6.2 一份跑完就能判断通不通的自检脚本
$drv = Get-OdbcDriver | Where-Object { $_.Name -like "*INFORMIX*" } "driver: " + ($drv.Name -join ', ') "INFORMIXDIR = " + [Environment]::GetEnvironmentVariable('INFORMIXDIR','Machine') "INFORMIXSERVER= " + [Environment]::GetEnvironmentVariable('INFORMIXSERVER','Machine') Test-NetConnection -ComputerName 10.0.0.21 -Port 9088 | Select-Object ComputerName, RemotePort, TcpTestSucceeded三段分别对应驱动、环境变量、网络。三段全绿再去调应用,任何一段红了都先解决它,别越级排查。
这个脚本我一般放在交付包的根目录,接手的同事双击就能看结果,省掉一轮“你那边装的什么版本”的来回确认。从那以后我每次交付客户端,都要先把这份自检跑一遍再签字,宁可多花五分钟,也不想在对方现场对着一个 IM002 干瞪眼。希望帮到你。
本文还有配套的精品资源,点击获取