【发布时间】:2017-06-21 02:26:06
【问题描述】:
我在尝试通过 Perl 运行存储过程时遇到了一些错误。
以下语句在 sqlDeveloper 中运行良好并返回预期结果
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 导致此错误
"选择 alpha.beta.get_something(alpha.STRING_ARRAY('xyz')) from tableName" 导致:PLS-00428:在这个中需要一个 INTO 子句 SELECT 语句(DBD 错误:错误可能在字符的 > 指示符附近 6 in 'BEGIN >Select alpha.beta.get_result(alpha.STRING_ARRAY('xyz')) 来自表名;结束;')
如果我从 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' )
};
所以,我的问题是
执行使用 SELECT 语句的存储过程的正确方法是什么?应该使用
BEGIN $procedure; END;调用还是不使用BEGIN/END?如何从
bless( {}, 'DBI::st' )获取实际数据?我尝试使用不同的获取选项:fetchrow、fetchrow_hashref等,但我无法从对象中获取实际数据
【问题讨论】:
-
这看起来很眼熟。在过去的几天里,您是否已经问过同样的问题?
-
是的,我昨天确实问过这个问题,但它缺少细节,人们要求我提供代码。我刚刚更新了另一个问题,很快就会删除它
-
现在非常清楚了。看我的回答。
-
请注意
DBI模块不允许您同时使用prepare和execute多个语句。另外,$dbh->prepare('BEGIN')是否成功取决于数据库驱动程序,创建事务的规范方法是在执行事务之前设置$dbh->{AutoCommit} = 0,然后相应地设置$dbh->commit或$dbh->rollback。AutoCommit默认启用,如果您将其设置为 false 值,则您请求的每个数据库操作都将被记录,等待执行或丢弃。
标签: oracle perl stored-procedures dbi