1

SELECTPL/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 と prepare/execute の違いを理解する必要があります。do は、ステートメント ハンドルを返しません (操作の成功または影響を受けた行数を示すステータスを返します)。その結果、fetch を呼び出すためのステートメント ハンドルがないため、do を使用して行をフェッチすることはできません。do メソッドは通常、DDL または挿入/更新/削除ステートメントに使用されます。

prepare メソッドはステートメント ハンドルを返すため、SQL が select ステートメントであった場合は、そこから行をフェッチできます。

あなたがしようとしていることを私が誤解している場合は、私に知らせてください。いくつかの例をあげることができます。

于 2013-02-01T08:59:19.960 に答える
2

私は PL/SQL にはあまり詳しくありませんが、SQL 文字列が複数のステートメントのように非常によく似ていることは知っています。セキュリティ対策として、DBI は一度に 1 つのステートメントしか実行しません。おそらく、 のみを実行declareし、残りを無視しています。

select直接実行するのではなく、このようにしている理由はありますか? $sql(余分なビットがないset toを除いて、同一のコードselect * from ..........です。) より一般的なケースでストアド プロシージャを動的に宣言しようとしている場合、/ toのdo代わりに DBI のメソッドを使用するほうがうまくいくかもしれません (またはそうでないかもしれません)。それを宣言してから、別のステップとして実行します。prepareexecuteexecute

于 2013-02-01T07:57:21.763 に答える