PERL:DBI connect('','system',...)失败:ERROR OCIEnvNlsCreate使用dbi个人包时

时间:2014-11-27 14:10:16

标签: oracle perl dbi

我正在尝试使用DBD :: Oracle创建一个应用程序类。我有ORACLE_HOME和ORACLE_SID环境变量的问题。

当我在BEGIN机箱中设置这些变量时,它可以正常工作,参见示例:

#!/usr/bin/perl
use strict;
use warnings;
use Switch;
use DBI;

# Debug
use Data::Dumper;

package DBIAgent;

BEGIN
{
    $ENV{ORACLE_HOME}="/app/oracle/product/11.2.0/db_1";
    $ENV{ORACLE_SID}="DB01";
}

sub new {
    my $class = shift;
    my $self = {
        _username => shift,
        _password => shift,
        _database => shift,
        _logger => shift
    };

    $self->{_oracleConnected} = 0;

    bless $self, $class;
    return $self;    
}

sub TO_JSON {
  return { %{ shift() } };
}

sub connect {
    my ( $self ) = @_;
    foreach (sort keys %ENV) { 
        $self->{_logger}->log ("INFORMATION - $_  =  $ENV{$_}");
    }

    $self->{_logger}->log ("INFORMATION - Username " . $self->{_username});
    $self->{_logger}->log ("INFORMATION - Password " . $self->{_password});

    eval {
        $self->{_oracleConnexion} = DBI->connect("dbi:Oracle:", $self->{_username}, $self->{_password}, {ora_verbose=>6}) or die ("ERROR - Unable to connect to database " . $self->{_database} . " - " . $! . " SQL ERROR: " . $DBI::errstr);
    };

    if ($@) {
        $self->{_oracleConnected} = 0;
        $self->{_logger}->log ($@);
    } else {
        $self->{_oracleConnected} = 1;
        $self->{_logger}->log ("INFORMATION - Connected to database " . $self->{_database});
    }

    return $self->{_oracleConnected};
}

sub getSqlResult {
    my ( $self, $sqlName, $sqlText ) = @_;
    my $resultSet;

    eval {
        $resultSet = $self->{_oracleConnexion}->selectall_arrayref($sqlText) or die ("ERROR - Execution for sql " . $sqlName . " on database " . $self->{_database} . " failed - SQL ERROR: " . $DBI::errstr);
    };

    if ($@) {
        $self->{_logger}->log ($@);
        return "";
    } else {
        return $resultSet;
    }
}

sub close {
    my ( $self ) = @_;

    $self->{_oracleConnexion}->disconnect();
    $self->{_oracleConnected} = 0;
    $self->{_logger}->log ("INFORMATION - Disconnected from database " . $self->{_connexionInfo}->{database});
}

# Getters / Setters

sub getConnected {
    my( $self ) = @_;
    return $self->{_oracleConnected};
}

1;

当我删除BEGIN部分时,出现以下错误: DBI connect('','system',...)失败:ERROR OCIEnvNlsCreate

我的Oracle体系结构可能有多个ORACLE_HOME,因此我想将其作为变量参数。

我尝试在创建DBIAgent对象之前设置它,但是我得到了同样的错误。我拥有,我必须在使用DBI之前设置这些变量;命令被调用。

有没有办法参数BEGIN部分,还是有另一种方法可以做到这一点?

感谢您的帮助。 Ragards

2 个答案:

答案 0 :(得分:1)

%ENV哈希是一种访问shell环境变量的方法。因此,您可以在调用之前通过在程序外部设置环境变量来解决问题。

$ export ORACLE_HOME=/app/oracle/product/11.2.0/db_1
$ export ORACLE_SID=DB01
$ ./name_of_your_program

不要忘记删除整个BEGIN块。

答案 1 :(得分:0)

您在这里使用了两个非常目的的环境变量。


如果要连接到不同的Oracle实例,请转储/覆盖ORACLE_SID环境变量,并使用DBD::Oracle->connect中的连接字符串传递SID。 文档中的一行显示了这个例子:

$dbh = DBI->connect('dbi:Oracle:host=foobar;sid=DB;port=1521', 'scott/tiger', '');

更多详情@ https://metacpan.org/pod/DBD::Oracle#connect


另一方面,

ORACLE_HOME指向计算机上安装的Oracle客户端软件的位置,并告诉DBD::Oracle的XS组件在哪里可以找到要链接的必要库。我真的没想到你想在生产环境中制作这个变量的好理由。全新安装DBD::Oracle需要针对相同的客户端库编译这些XS组件这一事实很容易使您的尝试复杂化。您可能希望在机器上使用最新版本。 ORACLE_HOME几乎总是由登录脚本,/ etc / init.d脚本或特定的cron作业设置。

一个例外可能是在测试环境中,但在这种情况下,您可能已经准备好改变环境变量来测试每个候选客户端。