2010-04-23 43 views
2

我在使用DBI的IBM DB2驱动程序与mod_perl一起工作时遇到了问题。我的测试脚本是:如何使用DBI和mod_perl连接DB2?

#!/usr/bin/perl 

use strict; 
use CGI; 
use Data::Dumper; 
use DBI; 

{ 
    my $q; 
    my $dsn; 
    my $username; 
    my $password; 
    my $sth; 
    my $dbc; 
    my $row; 

    $q = CGI->new; 
    print $q->header; 
    print $q->start_html(); 

    $dsn = "DBI:DB2:SAMPLE"; 
    $username = "username"; 
    $password = "password"; 

    print "<pre>".$q->escapeHTML(Dumper(\%ENV))."</pre>"; 

    $dbc = DBI->connect($dsn, $username, $password); 

    $sth = $dbc->prepare("SELECT * FROM SOME_TABLE WHERE FIELD='SOMETHING'"); 
    $sth->execute(); 
    $row = $sth->fetchrow_hashref(); 
    print "<pre>".$q->escapeHTML(Dumper($row))."</pre>"; 

    print $q->end_html; 
} 

此脚本可用作CGI,但不能在mod_perl下运行。我在Apache的错误日志中出现此错误:

DBD::DB2::dr connect warning: [unixODBC][Driver Manager]Data source name not found, and no default driver specified at /usr/lib/perl5/site_perl/5.8.8/Apache/DBI.pm line 190. 
DBI connect('SAMPLE','username',...) failed: [unixODBC][Driver Manager]Data source name not found, and no default driver specified at /data/www/perl/test.pl line 15 

首先,为什么它使用ODBC?本地DB2驱动程序已安装(因此它可用作CGI)。

在RHEL5下运行Apache 2.2.3,mod_perl 2.0.4。

这家伙和我有同样的问题: http://www.mail-archive.com/[email protected]/msg22909.html 但我不知道他是如何修复它的。 mod_php4与mod_perl有什么关系?

任何帮助将不胜感激,我没有与谷歌运气。

更新

由于james2vegas指出,这个问题有事情做与PHP:我禁用PHP一起,我得到了一个不同的错误:

Total Environment allocation failure! Did you set up your DB2 client environment? 

我相信这个错误与环境变量设置不正确,即DB2INSTANCE。但是,我无法关闭PHP来解决这个问题(我需要它为一些遗留应用程序)。所以我现在有2个问题:

  1. 如何解决原始问题而不禁用PHP所有在一起?
  2. 我该如何解决环境问题?

我已经设置DB2INSTANCE,DB2_PATH和SQLLIB变量正确使用SetEnvPerlSetEnvhttpd.conf,但没有运气。

注意:我编辑了代码以确定问题是否与Global Variable Persistence有关。

+0

这是指错误的库被php加载到apache的进程中,并且当它在mod_perl下运行时(也在同一个apache进程中)而不是CGI(它是独立的过程),可能值得在没有PHP的情况下进行测试。 – MkV 2010-04-23 02:29:14

+0

您可以尝试获取DBD :: DB2 :: dr :: data_sources();它应该返回一组数据源,确保它包含SAMPLE。 – MkV 2010-04-23 02:42:15

+0

你是对的,如果我禁用PHP我得到一个不同的错误: 总环境分配失败!您是否设置了DB2客户端环境? 这本身就是一个问题,但我以前见过。在过去,这意味着没有设置环境变量DB2INSTANCE。现在我确实使用'SetEnv'和'PerlSetEnv'来设置它们,但它们似乎没有效果。 但此外,服务器运行PHP和Perl,所以我不能只关闭PHP来解决问题。如何在不禁用PHP al的情况下解决最初的问题? – Matthew 2010-04-23 02:50:48

回答

1

这似乎解决了,以供参考:在/etc/php.d/pdo_odbc.ini禁用PHP的ODBC支持,设置环境变量和的mod_perl的启动脚本预加载DBD::DB2,虽然有可能使用PERL_DL_NONLAZY设置为1强制加载正确的库。

+0

啊,所以DBD被加载了很有趣?获得更多文档......似乎很容易陷入困境:( – Ether 2010-04-23 14:41:29

+0

问题是DB2和ODBC的共享库都导出了名称相同的SQL_XXXX函数,后者覆盖了前者。 – MkV 2010-04-24 10:09:50

1

普通旧的DBI不能在mod_perl中工作;当你的进程分叉并且你尝试再次使用你的db句柄的时候,它会一帆风顺。您需要使用Apache::DBI(它是DBI的直接替代品),或者甚至更好使用DBIx::Connector之类的后现代DBI包装。

您可以在这里阅读更多的细节,在Apache's guide to using mod_perl with relational databases

+0

实际上,第二次看起来它确实显示你已经安装了Apache :: DBI ......我即将登上火车,但是当我回到终端时,我会深入挖掘 – Ether 2010-04-23 00:59:56

+0

谢谢你,是的,我确实已经安装了Apache :: DBI并加载到了httpd.conf中 – Matthew 2010-04-23 01:19:13