perl:执行使用select

时间:2017-02-03 16:38:18

标签: oracle perl stored-procedures dbi

尝试通过Perl运行存储过程时遇到一些错误。

以下语句在sqlDeveloper中正常工作并返回预期结果

EXEC alpha.beta.do_something()

这不会产生任何输出,如预期的那样

Select alpha.beta.get_something(alpha.STRING_ARRAY('xyz')) from tableName

这会产生从DBA人员那里获得的输出。它在数据库术语中具有以下格式:Output Type:Ref Cursor。光标有两列,ab

运行Perl时,运行第二个语句时出错。

这是我正在使用的Perl代码:

sub execute_procedure {
    my $dbh       = shift;
    my $procedure = shift;

    my $statement = "BEGIN $procedure; END;"
    my $sth;
    eval {$sth = $dbh->prepare($statement);};
    eval {$sth->execute();};

    if ($@) {
        print "failed";
    } else {
        print "passed";
    }
}

# Call 1
execute_procedure($dbh, "alpha.beta.do_something()")

# Call 2
execute_procedure($dbh, "Select alpha.beta.get_something(alpha.STRING_ARRAY('xyz')) from tableName")

调用1按预期工作,不会产生任何错误

调用2导致此错误

  

"从中选择alpha.beta.get_something(alpha.STRING_ARRAY(' xyz'))   表名"结果:PLS-00428:预计INTO条款   SELECT语句(DBD错误:错误可能在char附近< >指示符附近   6 in' BEGIN< >选择alpha.beta.get_result(alpha.STRING_ARRAY(' xyz'))   来自tableName; END;&#39)

如果我从execute_procedure函数中的语句中删除BEGIN和END,如下所示:

# my $statement = "BEGIN $procedure; END;";
my $statement = "$procedure";

然后它不会产生任何错误,但会返回一个我不知道如何解析的结果

my $result = $sth->fetchrow_hashref;
print Dumper($result)

结果:

$VAR1 = {
  'alpha.beta.get_result(alpha.STRING_ARRAY(\'xyz\'))' => bless( {}, 'DBI::st' )
};

所以,我的问题是

  1. 执行使用SELECT语句的存储过程的正确方法是什么?是应该使用BEGIN $procedure; END;还是BEGIN / END进行调用?

  2. 如何从bless( {}, 'DBI::st' )获取实际数据?我尝试使用不同的提取选项:fetchrowfetchrow_hashref等,但我无法从对象中获取实际数据

1 个答案:

答案 0 :(得分:1)

$VAR1 = { 'alpha.beta.get_result(alpha.STRING_ARRAY(\'xyz\'))' => bless( {}, 'DBI::st' ) };

此处的值为a DBI statement handle。这与my $sth = $dbh->prepare(...)时的结果相同。它可能已经被执行了,所以你可以调用它上面的任何获取方法。

my $result = $sth->fetchrow_hashref;
while (
    my $res = $result->{'alpha.beta.get_result(alpha.STRING_ARRAY(\'xyz\'))'}
        ->fetchrow_hashref
) {
    # ...
}

但这看起来很可怕,你可能不知道钥匙是什么。所以你可能想要迭代所有这些。

my $result = $sth->fetchrow_hashref;
foreach my $key ( keys %${ $result } ) {
    print "Processing results of $key\n";
    while ( my $res = $result->{$key}->fetchrow_hashref ) {
        # do things with the $res

    }
}

您只需找出处理结果的好方法。如果哈希引用只有一个键,上面的循环也可以工作,所以你可以只使用它,并希望总有一个。