Hi all,
Few weeks ago, I posted a problem about DBD::Oracle as following.
> I am trying to use DBD::Oracle1.12 on mod_perl2.
> But it doesn't work fine.
> It shows error as following in error_log at $dbh = DBI->connect.
>
> ----[error_log]----
> DBI->connect(ynt0) failed: (UNKNOWN OCI STATUS 1804) OCIInitialize. Check
> ORACLE_HOME and NLS settings etc. at
> /yopt/httpd-2.0.39_prefork_perl5.6.1normal/cgi-bin/test1.cgi line 42
> [Mon Jul 29 20:15:37 2002] [error] 25703: ModPerl::Registry: `Cannot
connect:
> (UNKNOWN OCI STATUS 1804) OCIInitialize. Check ORACLE_HOME and
> NLS settings etc.at
> /yopt/httpd-2.0.39_prefork_perl5.6.1normal/cgi-bin/test1.cgi line 42.
> --------
This error meaned I didn't set Oracle %ENV or wrong.
I set %ENV correctly, and my debug code showed Oracle %ENV correctly.
I couldn't find the reason at this time...
But today I resolved this problem!
The reason was posted by Doug to the dev list. Here it is:
> -------
> the issue is that environ[] is not thread safe. so mod_perl2 unties %ENV
> from the underlying environ[] array under the perl-script handler.
> i assume the oracle driver or client library uses getenv() (which fetches
> from the environ[] array). when %ENV is untied from environ[], perl-land
> will see %ENV changes, but C-land will not see the coresponding changes
> in environ[].
> the 'modperl' handler does not untie %ENV from environ[].
>
> so, one should avoid setting %ENV values whenever possible.
> and if it is required, should be done at startup time.
> ------
So, I added Oracle %ENV script in my startup.pl as following and it worked
fine!
----[startup.pl]----
use Apache2 ();
use lib qw(/yopt/httpd-2.0.39_prefork_perl5.6.1normal/cgi-bin);
# enable if the mod_perl 1.0 compatibility is needed
# use Apache::compat ();
use ModPerl::Util (); #for CORE::GLOBAL::exit
use Apache::RequestRec ();
use Apache::RequestIO ();
use Apache::RequestUtil ();
use Apache::Server ();
use Apache::ServerUtil ();
use Apache::Connection ();
use Apache::Log ();
use APR::Table ();
use ModPerl::Registry ();
use Apache::Const -compile => ':common';
use APR::Const -compile => ':common';
# add by atsushi 2002/08/22
$ENV{'ORACLE_HOME'} = '/u01/app/oracle/product/9.0.1';
$ENV{'ORACLE_SID'} = 'ynt0';
$ENV{'NLS_LANG'} = 'japanese_japan.ja16euc';
1;
--------
But..., I want to change $ENV{'ORACLE_SID'} dynamically, because I have many
DB to connect.
Currently my perl program handles the target DB SID by user http request.
I hope we can change %ENV for DBD::Oracle on perl script in the future.
Thank you Stas for helping this matter!
Atsushi
PS : I attache my environment and my perl script.
- perl5.6.1(non thread)
- DBI-1.30
- DBD-Oracle-1.12
- mod_perl1.99_04(DSO build)
- apache2.0.39(prefork)
- Oracle9.0.1.3 for Linux in same machine
----[test1.cgi]----
use DBI;
my $dsn = 'dbi:Oracle:';
my $user = 'username/password';
my $password = '';
$ENV{'ORACLE_HOME'} = '/u01/app/oracle/product/9.0.1'; # don't work, no
means...
$ENV{'ORACLE_SID'} = 'ynt0'; # don't work, no means...
$ENV{'NLS_LANG'} = 'japanese_japan.ja16euc'; # don't work, no means...
print "ORACLE_HOME=$ENV{'ORACLE_HOME'}<br>\n";
print "ORACLE_SID=$ENV{'ORACLE_SID'}<br>\n";
print "NLS_LANG=$ENV{'NLS_LANG'}<br>\n";
print "DSN=$dsn$ENV{'ORACLE_SID'}<br>\n";
$dbh = DBI->connect("$dsn$ENV{'ORACLE_SID'}", $user, $password)
or die "Cannot connect: ".$DBI::errstr;
...
--------
----[httpd.conf]----
LoadModule perl_module modules/mod_perl.so
.......
<IfModule mod_perl.c>
PerlRequire "/yopt/httpd-2.0.39_prefork_perl5.6.1normal/conf/startup.pl"
PerlModule ModPerl::Registry
<Location /cgi-bin>
SetHandler perl-script
PerlResponseHandler ModPerl::Registry
PerlOptions +ParseHeaders
Options +ExecCGI
</Location>
</IfModule>
--------
----- Original Message -----
From: "Stas Bekman" <[EMAIL PROTECTED]>
To: "Atsushi Fujita" <[EMAIL PROTECTED]>
Cc: <[EMAIL PROTECTED]>
Sent: Wednesday, July 31, 2002 11:18 AM
Subject: Re: mod_perl2 & DBD::Oracle problem
> Atsushi Fujita wrote:
> > Hi all,
> >
> > I am trying to use DBD::Oracle1.12 on mod_perl2.
> > But it doesn't work fine.
> > It shows error as following in error_log at $dbh = DBI->connect.
> >
> > ----[error_log]----
> > DBI->connect(ynt0) failed: (UNKNOWN OCI STATUS 1804) OCIInitialize. Check
> > ORACLE_HOME and NLS settings etc. at
> > /yopt/httpd-2.0.39_prefork_perl5.6.1normal/cgi-bin/test1.cgi line 42
> > [Mon Jul 29 20:15:37 2002] [error] 25703: ModPerl::Registry: `Cannot
connect:
> > (UNKNOWN OCI STATUS 1804) OCIInitialize. Check ORACLE_HOME and
> > NLS settings etc.at
> > /yopt/httpd-2.0.39_prefork_perl5.6.1normal/cgi-bin/test1.cgi line 42.
> > --------
> >
> >
> > ----[test1.cgi]----
> > use DBI;
> >
> > my $dsn = 'dbi:Oracle:';
> > my $user = 'username/password';
> > my $password = '';
> >
> > $ENV{'ORACLE_HOME'} = '/u01/app/oracle/product/9.0.1';
> > $ENV{'ORACLE_SID'} = 'ynt0';
> > $ENV{'NLS_LANG'} = 'japanese_japan.ja16euc';
> >
> > print "ORACLE_HOME=$ENV{'ORACLE_HOME'}<br>\n";
> > print "ORACLE_SID=$ENV{'ORACLE_SID'}<br>\n";
> > print "NLS_LANG=$ENV{'NLS_LANG'}<br>\n";
> > print "DSN=$dsn$ENV{'ORACLE_SID'}<br>\n";
> >
> > $dbh = DBI->connect("$dsn$ENV{'ORACLE_SID'}", $user, $password)
> > or die "Cannot connect: ".$DBI::errstr;
> > ...
> > --------
> >
> > At first, I suspect that the reason is %ENV in this script.
> > But I set surely, and this output as following.
> >
> > ----[Broser output HTML]----
> > ORACLE_HOME=/u01/app/oracle/product/9.0.1
> > ORACLE_SID=ynt0
> > NLS_LANG=japanese_japan.ja16euc
> > DSN=dbi:Oracle:ynt0
> >
> > Internal Server Error
> > The server encountered an internal error or misconfiguration and was
unable to
> > complete your request.
> > ....
> > --------
> >
> > And if I turned off the mod_perl, it works fine on normal CGI-script.
> > This error occurred only mod_perl.
> > (I tested mod_perl1.26 & apache 1.3.26, it worked fine...)
> >
> > My machine is as following.
> > - perl5.6.1(non thread)
> > - DBI-1.30
> > - DBD-Oracle-1.12
> > - mod_perl1.99_04(DSO build)
> > - apache2.0.39(prefork)
> >
> >
> > ----[httpd.conf]----(is this wrong??)
> > LoadModule perl_module modules/mod_perl.so
> > .......
> > <IfModule mod_perl.c>
> > PerlModule ModPerl::Registry
> > <Location /cgi-bin>
> > SetHandler perl-script
> > PerlResponseHandler ModPerl::Registry
> > PerlOptions +ParseHeaders
> > Options +ExecCGI
> > </Location>
> > </IfModule>
> > --------
>
> Do you suggest that %ENV is getting lost along the way? Or can it be
> some other problem? I don't have Oracle to test with. Or can you think
> of some other way to reproduce the problem without depending on Oracle
> being installed?
>
> Can you please test with the following two approaches:
>
> 1.
>
> instead of using ModPerl::Registry, use Apache::Registry. Of course
> configure <Location> to use Apache::Registry.
>
> use Apache::compat;
> use Apache::Registry; # hopefull you have mod_perl 1.0 installed
>
> any change when you use the Apache::Registry from 1.0? Currently the
> only difference (mainly) is that ModPerl::Registry doesn't chdir() into
> the script's dir. (which eventually will change)
>
> 2. use a mod_perl handler
>
>
> __________________________________________________________________
> Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
> http://stason.org/ mod_perl Guide ---> http://perl.apache.org
> mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
> http://modperlbook.org http://apache.org http://ticketmaster.com
>
>