【问题标题】:Perl DBD::ODBC stuck using the same ODBC Driver ManagerPerl DBD::ODBC 使用相同的 ODBC 驱动程序管理器卡住
【发布时间】:2014-05-12 05:47:53
【问题描述】:

我有一个问题,在重新编译和重新安装后,我无法让 Perl DBD::ODBC 使用 unixODBC。它之前已安装。

我已编译 DBD::ODBC 以使用 DataDirect ODBC 驱动程序管理器。我现在想重新编译它以使用 unixODBC。然而,尽管从新的源代码开始,配置(它选择 unixODBC),然后编译和安装,它似乎卡在使用 DataDirect ODBC 驱动程序管理器。我已经从 Perl 模块文件夹中删除了所有文件(我知道),但是重新安装后问题仍然存在。

我正在从源代码编译,因为我正在安装的服务器没有 Internet 连接,所以我没有使用 CPAN。

我在 Solaris 10 上使用 unixODBC 1.2.3 和 Perl 5.8.4(它与环境匹配)。

我已经删除了我能找到的所有内容:

 1. cd /usr/perl5/site_perl/5.8.4/sun4-solaris-64int/auto/DBD/
 2. sudo rm -R ODBC
 3. cd /usr/perl5/site_perl/5.8.4/sun4-solaris-64int/DBD/
 4. sudo rm -R ODBC
 5. sudo rm ODBC.pm
 6. cd /usr/perl5/5.8.4/man/man3/
 7. sudo rm DBD::ODBC.3
 8. sudo vi /usr/perl5/5.8.4/lib/sun4-solaris-64int/perllocal.pod

然后我删除了perllocal.pod 中 DBD::ODBC 的所有条目。

当我运行 perl Makefile.PL 时,我可以看到它正在查找 unixODBC。

Looking for odbc_config at /usr/local/unixODBC_sp64/bin/odbc_config
  Found odbc_config (via /usr/local/unixODBC_sp64/bin/odbc_config) version 2.3.2

  odbc_config reports --prefix=/usr/local/unixODBC_sp64
  odbc_config reports --include-prefix=/usr/local/unixODBC_sp64/include
  odbc_config reports --lib-prefix=/usr/local/unixODBC_sp64/lib
  ODBC INC dir set to /usr/local/unixODBC_sp64/include from odbc_config
  ODBC LIB dir set to /usr/local/unixODBC_sp64/lib from odbc_config
Using ODBC HOME /usr/local/unixODBC_sp64

This looks like a unixodbc type of driver manager.
Looking for odbcinst
  odbcinst -j reports:

unixODBC 2.3.2
DRIVERS............: /usr/local/unixODBC_sp64/etc/odbcinst.ini
SYSTEM DATA SOURCES: /usr/local/unixODBC_sp64/etc/odbc.ini
FILE DATA SOURCES..: /usr/local/unixODBC_sp64/etc/ODBCDataSources
USER DATA SOURCES..: /usr/local/unixODBC_sp64/etc/odbc.ini

这是我编译和安装模块的环境中与 ODBC 相关的所有环境变量

LD_LIBRARY_PATH=/usr/local/unixODBC_sp64/lib:
LD_LIBRARY_PATH_64=/usr/local/unixODBC_sp64/lib:
PATH=/usr/local/unixODBC_sp64/bin:/usr/sfw/bin:/usr/ccs/bin:/opt/SUNWspro/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/bin
ODBCINI=/usr/local/unixODBC_sp64/etc/odbc.ini
ODBCHOME=/usr/local/unixODBC_sp64

当我运行测试时,我仍然看到来自 DataDirect 驱动程序管理器的错误:

DBI connect('lksdjhf','ljkshdf',...) failed: [DataDirect][ODBC lib] System information file not found. Please check the ODBCINI environment variable. (SQL-IM002) at ./test_odbcdb2.pl line 19

忽略它找不到驱动程序的事实,因为没有填充 odbc.ini。我正在使用垃圾连接进行测试,因为我想从 unixODBC 看到同样的错误消息。

我用于测试的 Perl 脚本如下。它适用于 DataDirect 驱动程序管理器。

#!/usr/bin/perl -w

use DBI;
use DBD::ODBC;
use DBD::DB2::Constants;

print "Enter Data Source Name:";
my $dsn =<STDIN>;
chomp $dsn;
my $data_source = "DBI:ODBC:$dsn";
print "Enter Username:";
my $user =<STDIN>;
print "Enter password:";
my $password =<STDIN>;
chomp $user;
chomp $password;

# Connect to the db2 database using odbc
my $dbh = DBI->connect($data_source, $user, $password, {AutoCommit =>1})
                or die "Can't connect to $data_source: $DBI::errstr";
$stmt = "SELECT current timestamp from sysibm.sysdummy1; ";
$sth = $dbh->prepare($stmt);
$sth->execute();

#associate variable with output columns...

$sth->bind_col(1,\$timestap);
while ($sth->fetch) {
           print "The time is: $timestap\n";
}
$dbh->disconnect;

【问题讨论】:

  • ./test_odbcdb2.pl line 19 包含什么?
  • my $dbh = DBI->connect($data_source, $user, $password, {AutoCommit =>1}) 或死“无法连接到 $data_source: $DBI::errstr” ;
  • @slayedbylucifer - 我已将完整的测试 Perl 脚本添加到问题中。谢谢。
  • 过去,我使用unixodbcfreetds。在继续使用 perl 之前,我会使用 tqlisql 进行连接测试。如果对您有帮助,请查看我在另一篇文章中的回答:stackoverflow.com/a/21252539/1251660
  • 感谢@slayedbylucifer,但使用isql 附带的unixODBC 没有连接问题。由于 DBD::ODBC 没有引用正确的驱动程序管理器,我什至没有达到连接点。

标签: perl odbc dbi unixodbc dbd


【解决方案1】:

你没有说你是否在构建结束时进行了 make install,但我假设你做了。

你没有说那些 LD_LIBRARY_xx 环境变量是否也刚刚设置或导出。

首先,解决其他 cmets。

  1. “DBI:ODBC:$dsn”确实应该是“dbi:ODBC:$dsn”。
  2. Perl DBI 会根据“dbi:”之后的字符串加载驱动程序,所以 “ODBC”加载 DBD::ODBC 模块。
  3. “它是在 DBD::ODBC 配置时选择哪个 要使用的 ODBC 驱动程序管理器”不正确。仅配置 选择要编译的驱动程序管理器。我不相信 链接器的“运行路径”指令在链接时提供。那么你 可以愉快地针对 unixODBC 构建并针对您的 DD 运行 似乎在做。

在您的 Perl 树中找到 ODBC.so(它应该在一个名为 DBD/ODBC 的目录中,例如 /home/martin/perl5/perlbrew/perls/perl-5.19.10/lib/site_perl/5.19.10/x86_64 -linux/auto/DBD/ODBC/ODBC.so)。现在在其上运行“ldd ODBC.so”并查看输出中 libodbc.so 的来源,例如:

$ ldd ./blib/arch/auto/DBD/ODBC/ODBC.so
        libodbc.so.1 =>  /usr/local/lib/libodbc.so.1
        libdl.so.1 =>    /usr/lib/libdl.so.1
        libthread.so.1 =>        /usr/lib/libthread.so.1
        libc.so.1 =>     /usr/lib/libc.so.1
        /usr/platform/SUNW,Ultra-5_10/lib/libc_psr.so.1

这里的动态链接器正在使用 /usr/local/lib/libodbc.so.1 解决对 libodbc.so.1 的依赖。您需要告诉动态链接器在它现在查看的任何位置之前查看您的 unixODBC lib 目录。使用 LD_LIBRARY_PATH 可能不起作用 - 特别是如果您以 root 身份运行并且有全局方式告诉动态喜欢者在哪里查找。阅读您的 ld.so.1 第 1 节手册页。

【讨论】:

  • 作者本人提供了很多很好的信息。谢谢。 +1。
  • 对不起,我还没有检查这个。我一直很忙,现在生病了。我会在几天内试一试,然后告诉你。感谢您的回复。
  • 啊,是的,非常有趣。 LD_LIBRARY_PATH 本身并没有什么问题,但是因为 ODBC.so 是 32 位的,而我们使用的 ODBC 驱动程序管理器是 64 位的,所以它绕过了驱动程序管理器中的驱动程序,直到找到所有的 libodbc.so通往 LD_LIBRARY_PATH 中最后一个条目的路径,即 /usr/lib。
  • $ ldd /usr/perl5/site_perl/5.8.4/sun4-solaris-64int/auto/DBD/ODBC/ODBC.so libodbc.so => /usr/local/unixODBC_sp32/lib/ libodbc.so libodbc.so (VERS_3.52) => (未找到版本) libthread.so.1 => /usr/lib/libthread.so.1 libc.so.1 => /usr/lib/libc.so .1 libgcc_s.so.1 => /usr/sfw/lib/libgcc_s.so.1 libm.so.2 => /usr/lib/libm.so.2 /lib/libm/libm_hwcap1.so.2 /platform /sun4v/lib/libc_psr.so.1
  • 如果我使用 32 位驱动程序管理器会出现不同的问题,我必须研究一下,但看起来你让我走上了正确的道路。谢谢。我会传递结果。我认为有些地方发生了变化,因为现在它没有找到它想要的 libodbc.so 版本(它在我之前测试时确实做到了,但肯定有一些变化)。在您的帮助下,我似乎已经接近解决方案了,尽管我们现在面临的 32 位与 64 位的复杂性可能比我们想象的要多。
猜你喜欢
  • 2013-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 1970-01-01
  • 1970-01-01
  • 2013-06-30
相关资源
最近更新 更多