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
。光标有两列,a
和 b
运行通过 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' )
};
所以,我的问题是
执行使用 SELECT 语句的存储过程的正确方法是什么?应该使用 BEGIN $procedure; END;
还是不使用 BEGIN
/END
来调用它?
如何从 bless( {}, 'DBI::st' )
获取实际数据?我尝试使用不同的获取选项:fetchrow
、fetchrow_hashref
等,但我无法从对象
获取实际数据
$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 中只有一个键,上面的循环也可以工作,所以你可以随便使用它并希望总是只有一个。
我在尝试通过 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
。光标有两列,a
和 b
运行通过 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' )
};
所以,我的问题是
执行使用 SELECT 语句的存储过程的正确方法是什么?应该使用
BEGIN $procedure; END;
还是不使用BEGIN
/END
来调用它?如何从
bless( {}, 'DBI::st' )
获取实际数据?我尝试使用不同的获取选项:fetchrow
、fetchrow_hashref
等,但我无法从对象 获取实际数据
$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 中只有一个键,上面的循环也可以工作,所以你可以随便使用它并希望总是只有一个。