1

我有一个SELECT使用 PL/SQL 代码生成的动态 SQL 语句。

declare
  sql_query clob;
begin
  sql_query := 'select * from ...........';
  execute immediate sql_query;
end;

我想将上述动态生成的SELECT语句的输出检索到 Perl 中的数组中。我已经在 Perl 中尝试过的是,

$sql = "declare
    sql_query clob;
  begin
    sql_query := 'select * from ...........';
    execute immediate sql_query;
  end;";

$sql_prep = $dbh->prepare($sql) or die "Cannot prepare.";
$sql_prep->execute() or die "Cannot execute.";

while (@row = $sql_prep->fetchrow_array ()) {
  print "@row\n";
}

我得到的错误是,

DBD::Oracle::st fetchrow_array failed: ERROR no statement executing (perhaps you need to call execute first) [for Statement "declare
........
........
"] at ./script.pl line 60.

我是 PL/SQL 的新手,我不确定我是否遵循了正确的路径。有人可以给我建议吗?

提前致谢!

——沙昆塔拉

4

2 回答 2

3

将来,当您发布时,如果您显示更多代码可能会有所帮助-在这种情况下,完整的 SQL 可能会有所帮助,并且至少可以确定哪一行引发了错误(它说第 60 行,而您没有第 60 行)。

你不能做你想做的事。您可以在 Perl 中动态创建 SQL 并将其传递给准备、执行然后 fetchXXX(或使用其中一种 select* 方法),或者如果您需要在 PL/SQL 中动态创建 SQL,则需要创建一个过程它返回一个 SYS_REFCURSOR(参见 DBD::Oracle 示例)。

正如之前的海报提到的 do 方法,您似乎误解了他,您应该意识到 do 和准备/执行之间的区别。do 不返回语句句柄(它返回指示操作成功或受影响的行数的状态)。因此,您无法使用 do 取回任何行,因为没有可以调用 fetch 的语句句柄。do 方法通常用于 DDL 或插入/更新/删除语句。

prepare 方法返回一个语句句柄,因此如果 SQL 是一个 select 语句,您可以从中获取行。

如果我误解了你试图做的事情,请告诉我,我可以给你一些例子。

于 2013-02-01T08:59:19.960 回答
2

我对 PL/SQL 不是特别熟悉,但我知道您的 SQL 字符串看起来很像多条语句,并且作为安全预防措施,DBI 一次只会执行一条语句。也许它只是运行declare并忽略其余部分。

您是否有理由这样做而不是select直接运行?(相同的代码,除了$sql设置为select * from ..........没有额外的位。)如果您尝试在更一般的情况下动态声明存储过程,您可能(或可能不会)使用 DBI 的do方法而不是prepare/execute来获得更好的运气声明它,然后execute作为单独的步骤运行它。

于 2013-02-01T07:57:21.763 回答