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
>
>




Reply via email to