1

一連の挿入ステートメントを作成してテーブルのバックアップを作成するという問題があります。

入力はテーブル名で、各テーブルは異なる数の列を持つことができます。データ型は varchar2、number、または date のみであると想定されています

だから私はこのコード行を持っています:

execute immediate fetchStmt;

ここで、fetchStmt は次のようになります。

fetch tableColCursor into valuesArray(1), valuesArray(2), ...,  valuesArray(n)

これは、カーソルから各行をフェッチし、それを varray に入れるだけです。ステートメント自体は、即時実行ステートメントにない場合に機能します。

即時実行では SQL クエリまたは PL/SQL ブロックしか処理できないことは知っています。問題は、どうすればこれを機能させることができるか、または問題に対する同様の解決策は何ですか?

コンパイル時には、テーブルとその列、およびそれらのデータ型が不明であることに注意してください。

4

1 に答える 1

2

EXECUTE IMMEDIATE完全なステートメントのみを処理できます。つまり、SQL ステートメントまたは PLSQL ブロック ( を使用[DECLARE]..BEGIN..END)。

さらに、この方法で実行されたブロックは、呼び出しブロックからの変数を認識しません (同じスコープを共有しません)。たとえば、これは機能しません。

DECLARE
  l NUMBER := 1;
  k NUMBER := 0;
BEGIN
  EXECUTE IMMEDIATE 'BEGIN l := k; END;';
END;

とがサブブロックで定義されていないためl、上記のコードはエラーを生成します。k代わりに、入出力変数を使用する必要があります。

DECLARE
  l NUMBER := 1;
  k NUMBER := 0;
BEGIN
  EXECUTE IMMEDIATE 'BEGIN :P1 := :P2; END;' USING OUT l, k;
  dbms_output.put_line(l); -- return 0
END;

あなたの場合、変数の数がわからないので、使用できませんEXECUTE IMMEDIATE。使用することもできますDBMS_SQLが、もっと簡単な方法があると思います。すでに動作しているコードを見つけることができます (たとえば、Oracle APEX 内に存在します)。または、必要な INSERT 文字列を生成する SELECT を実行して自分でプログラムすることもできます。この方法では、(テーブルの列に応じて) SQL ステートメントを動的に生成する必要があります。ステートメントは次のようになります (TEST(a,b,c)すべての列が整数であるテーブルの場合 [他のデータ型に適応する必要があります]):

SELECT 'INSERT INTO test(a,b,c) VALUES ('||a||', '||b||', '||c||');'
  FROM test
于 2012-11-16T10:26:54.440 に答える