Как использовать подключение к DB2 с помощью DBI и mod_perl?

У меня возникли проблемы с работой драйвера DBI IBM DB2 с mod_perl. Мой тестовый сценарий:

#!/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).

Запуск Apache 2.2.3, mod_perl 2.0.4 под RHEL5.

У этого парня была та же проблема, что и у меня: http://www.mail-archive.com/[email protected]/msg22909.html Но я понятия не имею, как он это исправил. Какое отношение mod_php4 имеет к mod_perl?

Любая помощь будет принята с благодарностью, мне не повезло с Google.

Обновление:

Как указал 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, используя SetEnv и PerlSetEnv в httpd.conf, но безуспешно.

Примечание. Я отредактировал код, чтобы определить, связана ли проблема с сохраняемостью глобальных переменных.


person Matthew    schedule 23.04.2010    source источник
comment
Это относится к тому, что неправильная библиотека загружается php в процесс apache, и это влияет на скрипт, когда он работает под mod_perl (также в том же процессе apache), в отличие от CGI (который является отдельным процессом), возможно, стоит протестировать это без PHP.   -  person MkV    schedule 23.04.2010
comment
Вы можете попробовать получить DBD::DB2::dr::data_sources(); он должен возвращать массив источников данных, убедитесь, что он включает SAMPLE.   -  person MkV    schedule 23.04.2010
comment
Вы правы, если я отключу PHP, я получу другую ошибку: Ошибка распределения общей среды! Настроили ли вы клиентскую среду DB2? Что само по себе проблема, но я видел это раньше. Раньше это означало, что переменная среды DB2INSTANCE не задана. Теперь я на самом деле установил его с помощью «SetEnv» и «PerlSetEnv», но они, похоже, не действуют. Но, кроме того, на сервере работают PHP и Perl, поэтому я не могу просто отключить PHP, чтобы решить проблему. Как я могу исправить первоначальную проблему, не отключая PHP вместе?   -  person Matthew    schedule 23.04.2010
comment
Если PHP не использует ODBC, вы можете попробовать пересобрать его без поддержки ODBC. Вы можете попробовать предварительно загрузить DBD::DB2 и установить переменные среды DB2 в сценарии запуска mod_perl.   -  person MkV    schedule 23.04.2010
comment
Спасибо james2vegas. Единственный способ отключить ODBC, перестроить его? Или я могу просто отключить его в php.ini? Я просто спрашиваю, потому что PHP был установлен как пакет, а не скомпилирован из исходного кода.   -  person Matthew    schedule 23.04.2010
comment
Понятно! Проблема была с pdo_odbc, поэтому ее отключение в /etc/php.d/pdo_odbc.ini решило проблему. Кроме того, вы были правы в отношении установки переменных среды в сценарии запуска. Я новичок в переполнении стека (поэтому я не знаком с практикой), но вы хотели опубликовать ответ, чтобы я мог дать вам баллы?   -  person Matthew    schedule 23.04.2010
comment
Согласно coding.derkeiler.com/Archive/ Perl/perl.dbi.users/2010-01/ вы можете попробовать установить для переменной окружения PERL_DL_NONLAZY значение 1 (вы можете попробовать сделать это перед предварительной загрузкой DBD::DB2 в сценарии запуска. (игнорируйте это, так как вы получили это)   -  person MkV    schedule 23.04.2010


Ответы (2)


Это кажется решенным, для справки: отключите поддержку PHP ODBC в /etc/php.d/pdo_odbc.ini, установите переменные среды и предварительно загрузите DBD::DB2 в сценарии запуска mod_perl, хотя можно использовать PERL_DL_NONLAZY установите значение 1, чтобы принудительно загрузить правильную библиотеку.

person MkV    schedule 23.04.2010
comment
Ах, значит, DBD загружался забавно? Я бы хотел, чтобы этот материал был задокументирован больше ... кажется, что легко столкнуться с трудным путем. :( - person Ether; 23.04.2010
comment
Проблема в том, что разделяемые библиотеки DB2 и ODBC экспортируют функции SQL_XXXX с одинаковыми именами, а последняя переопределяла первую. - person MkV; 24.04.2010

Старый добрый DBI не будет работать в mod_perl; все идет шатко, когда ваш процесс разветвляется, и вы снова пытаетесь использовать свой дескриптор базы данных. Вам необходимо использовать Apache::DBI (это замена DBI ), или, что еще лучше, используйте постмодернистскую оболочку DBI, такую ​​как DBIx::Connector.

Вы можете прочитать более подробную информацию здесь, в руководстве Apache по использованию mod_perl с реляционными базами данных. .

person Ether    schedule 23.04.2010
comment
На самом деле при втором взгляде кажется, что у вас установлен Apache::DBI... Я собираюсь сесть в поезд, но я копну глубже, когда вернусь к терминалу. - person Ether; 23.04.2010
comment
Спасибо, чувак, да, у меня установлен Apache::DBI и загружен в httpd.conf. - person Matthew; 23.04.2010