perl:执行使用 select 的存储过程

perl: executing stored procedure which uses select

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

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

EXEC alpha.beta.do_something()

这不会像预期的那样生成任何输出

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

这会生成 DBA 人员提供给我们的输出。它在 DB 术语中具有以下格式: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 导致此错误

"Select alpha.beta.get_something(alpha.STRING_ARRAY('xyz')) from tableName" results in :PLS-00428: an INTO clause is expected in this SELECT statement (DBD ERROR: error possibly near <> indicator at char 6 in 'BEGIN <>Select alpha.beta.get_result(alpha.STRING_ARRAY('xyz')) from tableName; END;')

如果我像这样从 execute_procedure 函数的语句中删除 BEGIN 和 END:

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

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

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 等,但我无法从对象

  3. 获取实际数据
$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

    }
}

你只需要想出一个好的方法来处理结果。如果 hash ref 中只有一个键,上面的循环也可以工作,所以你可以随便使用它并希望总是只有一个。