无法在 linux 机器上通过 ODBC 连接到 informix

Posted

技术标签:

【中文标题】无法在 linux 机器上通过 ODBC 连接到 informix【英文标题】:Cannot Connect to informix through ODBC on linux machine 【发布时间】:2019-03-13 12:50:41 【问题描述】:

我正在运行 CentOS 7 的虚拟机上工作,我正在尝试通过一些 php 使用 ODBC (unixODBC) 连接到 Informix 数据库。

我使用的是 php7.0,我已经安装了 unixODBC-2.3.7 以及 informix sdk 包 (iif.12.10.FC12DE.linux-x86_64)。

我已经这样配置了 odbc.ini 和 odbcinst.ini:

odbcinst.ini:

[ODBC Drivers]
IBM INFORMIX ODBC DRIVER=Installed
[IBM INFORMIX ODBC DRIVER]
Driver=/opt/IBM/Informix_Software_Bundle/lib/cli/iclis09b.so
Setup=/opt/IBM/Informix_Software_Bundle/lib/cli/iclis09b.so
APILevel=1
ConnectFunctions=YYY
DriverODBCVer=03.80
FileUsage=0
SQLLevel=1
smProcessPerConnect=Y

odbc.ini:

[ODBC Data Sources]
informix_db=IBM INFORMIXODBC DRIVER

[informix_db]
Driver=/opt/IBM/Informix_Software_Bundle/lib/cli/iclis09b.so
Description=IBM INFORMIX ODBC DRIVER
HostName=xxx.xxx.xxx.xxx
Service=xxxx
Database=xxx
LogonID=xxx
pwd=xxx
ServerName=xxx
Client_Locale=xxx
DB_Locale=xxx

然后我使用以下命令设置环境变量:

export INFORMIXDIR=/opt/IBM/Informix_Software_Bundle
export INFORMIXSERVER=xxx
export LD_LIBRARY_PATH=$INFORMIXDIR/lib/cli

我的php代码如下:

<?php 
$dbUserName=xxx;
$dbPassword=xxx;
$conn=odbc_connect("Driver=IBM INFORMIX ODBC DRIVER;HOSTNAME=xxx;Database=xxx;PORT=xxx;PROTOCOL=onsoctcp;", $dbUserName, $dbPassword);
 if (!$conn)
 
    echo odbc_errormsg();
 
 else 
    $sql="CALL somequery";
    $res=odbc_exec($conn,$sql);
    odbc_result_all($res);
 
?>

不幸的是,当我运行 php 时,我收到以下错误:

[unixODBC][Driver Manager]Can't open lib '/opt/IBM/Informix_Software_Bundle/lib/cli/iclis09b.so' : file not found

我在similar question 上读到这可能是由 DriverVersion 错误引起的,所以我在 odbcinst.ini 中尝试了 03.80 和 02.70(使用 php 和 unixODBC 安装的 odbc)。

我是 linux 的新手,不知道可能是什么其他问题导致的?也许我将环境变量设置为 false?

谢谢。

编辑

在我尝试以下操作后,使用 isql 命令有效: -添加以下环境变量:INFORMIXSQLHOSTSCLIENT_LOCALEDB_LOCALEODBCINIONCONFIG - 添加 onconfig 文件并进行配置。 -添加sqlhosts文件并进行配置。

仍在研究如何使 php 代码工作(仍然报同样的错误)

希望对您有所帮助。

编辑#2 通过终端运行php可以正常使用,并且我可以使用以前的数据库成功查询informix数据库,只有当我通过浏览器调用php代码(使用apache)时它才不起作用。

正如某人在different post 上所建议的那样,这是在驱动程序库所在的目录中运行ls -l 所产生的结果:

[root@administration-pc cli]# ls -l
total 21748
-rwxr-xr-x 3 informix informix 1865750 Jun 25  2018 iclis09b.so
-rwxrwxrwx 3 informix informix 1907069 Jun 25  2018 iclit09b.so
-rwxr-xr-x 2 informix informix   32805 Jun 25  2018 idmrs09a.so
-rw-r--r-- 2 informix informix 3595434 Jun 25  2018 libcli.a
-rw-r--r-- 2 informix informix   32864 Jun 25  2018 libdmr.a
-rw-r--r-- 2 informix informix 3595434 Jun 25  2018 libifcli.a
-rwxr-xr-x 3 informix informix 1865750 Jun 25  2018 libifcli.so
-rw-r--r-- 2 informix informix   32864 Jun 25  2018 libifdmr.a
-rwxr-xr-x 2 informix informix   32805 Jun 25  2018 libifdmr.so
-rwxr-xr-x 3 informix informix 1865750 Jun 25  2018 libixcli.so
-rwxrwxrwx 3 informix informix 1907069 Jun 25  2018 libtcli.so
-rw-r--r-- 1 informix informix 3593510 Jun 25  2018 libthcli.a
-rwxrwxrwx 3 informix informix 1907069 Jun 25  2018 libthcli.so
-rw-r--r-- 1 root     root           8 Mar 13 16:22 sample.txt

here 是 apache 的 phpinfo() 的结果;和here 用于通过终端运行的php。

我还为两者运行了exec('whoami'),Apache 返回apache,而终端返回root

我尝试更改 httpd.conf 以便 Userroot 而不是 apache 让我不再启动 apache。

另外,将iclis09b.so 的权限更改为 apache 似乎也不起作用。

EDIT#3(解决方案)

Apache 显然无法访问环境变量,所以你必须将所有环境变量都添加到它...

我的位于/etc/sysconfig/httpd ...

【问题讨论】:

您可以以informix 用户身份尝试odbc 管理器中包含的is​​ql 工具:isql -v databasename 来验证配置。可能 php 以没有访问 informix 目录权限的用户启动。 需要在 LD_LIBRARY_PATH 中包含 cli 和 esql。例如:LD_LIBRARY_PATH=/opt/ibm/informix/ids1210fc10/lib:/opt/ibm/informix/ids1210fc10/lib/esql:/opt/ibm/informix/ids1210fc10/lib/cli @jacques 是的,我试过了,它给了我同样的错误......但我确实尝试使用 php 从库所在的同一目录中读取,它确实让我简单文件获取内容;所以我假设它不是权限问题?我对 linux 真的很不好:/ 是的,我确实尝试过包含 cli 和 esql 路径... @A.JAlhorr - 你不应该接受一个不能真正解决你的问题的答案。最好写你自己的答案,确实解决你的问题,并接受。简而言之,当作为 CGI 运行时(mod_php 确实如此),您必须使用 setenv 调用在 Apache httpd.conf 或直接在 php 脚本中设置必要的环境变量。 (请注意,比较您的php_info 输出显示LD_LIBRARY_PATH 设置为命令行php 而不是apachemod_php...) 【参考方案1】:

您提到的所有参考 sn-p 都指向直接使用 Informix ODBC 驱动程序,这很好。我找不到任何可能导致您遇到错误的 sn-p 问题。此刻我对错误文本 sn -p [unixODBC][Driver Manager] 有点疑惑。我的意思是,当应用程序直接引用 Informix ODBC 驱动程序时,不应该出现 unixODBC 驱动程序管理器。您可以尝试使用以下值的 LD_LIBRARY_PATH 吗?

export LD_LIBRARY_PATH=$INFORMIXDIR/lib:$INFORMIXDIR/lib/esql:$INFORMIXDIR/lib/cli

仅供参考:由于您已经创建了一个 DSN(使用 INI 文件),您可以在 PHP 应用程序使用的连接字符串中指定 DSN 名称,例如:

"DSN=informix_db; uid=xxx; pwd=xxxx;"

如果您想尝试使用纯 ODBC 示例应用程序连接(我的意思是在 PHP 环境之外)进行故障排除,那么这里是 ODBC 应用程序示例代码。 https://github.com/OpenInformix/ODBCExamples/blob/master/src/IfxOdbcSample1.c

https://github.com/OpenInformix/ODBCExamples/blob/master/src/odbc.ini

https://github.com/OpenInformix/ODBCExamples/blob/master/src/makefile

https://github.com/OpenInformix/ODBCExamples/blob/master/src/envc.bsh

【讨论】:

您好,感谢您的帮助,我已经尝试了 LD_LIBRARY_PATH 但它不起作用:/ 我刚刚发现我可能使用了错误的 odbc.ini 和 odbcinst.ini;我使用直接位于 etc/ 目录中的文件,而不是 unixODBC 文件夹中的文件,我猜它们是 php ODBC 的文件?至于DSN文件,我不是很明白,要不要把dsn uid和pwd放在[informix_db]下面的odbc.ini里面?我试图从终端使用 isql -v 命令,但它给了我完全相同的错误。我想我会尝试解决它 使用您的 ODBC 示例应用程序。无论如何,非常感谢您的帮助 您可以在 INI 文件中指定 uid 和 pwd,这只是一个选择问题。如果在 INI 文件中指定所有属性,则只需在连接字符串中指定 DSN 名称。 “DSN=informix_db”。如果您在 INI 和连接字符串中都指定了属性,那么连接字符串上的属性将优先(并忽略 INI 文件中指定的相同属性。) @Satyan - 如果 ODBC 应用程序是通过链接构建的,则 ODBC 驱动程序管理器始终在图片中,无论 ODBC 应用程序使用的是 DSN-less 还是 DSN-full 的连接字符串.这实际上是构建与 DBMS 无关的基于 ODBC 的应用程序的好处,因为驱动程序管理器可以处理许多转换(在 ODBC 版本、Unicode 编码和其他事物之间),从而消除了应用程序和驱动程序的此类责任。跨度> @A.JAlhorr - 您可能希望使用一组 odbc.iniodbcinst.ini 文件,通常在 /etc/ 中,并带有来自任何其他当前位置的符号链接。您通常可以混合多个现有文件的内容。您通常还可以通过$ODBCINI$ODBCINSTINI 环境变量告诉应用程序使用特定文件(覆盖默认位置的文件,如/etc/odbc.ini~/.odbc.ini

以上是关于无法在 linux 机器上通过 ODBC 连接到 informix的主要内容,如果未能解决你的问题,请参考以下文章

无法通过 ODBC 将 Access 连接到 SQLlite

64 位 DBeaver 无法连接到 ODBC 源 - “参数编号超出范围”。

无法通过 odbc 连接到 Microsoft Azure 数据库

CodeIgniter 3.1.10:无法通过 DSN 使用 ODBC 连接到远程数据库

无法通过 Windows 2012 上的系统 dsn 使用 ODBC 连接连接到 SQL Server 2008

CakePHP 和使用 Unixodbc 连接到 MS Access db