5

1 つの Execute Immediate ステートメント内で複数の ddl ステートメントを実行しようとしています。これはかなり簡単だと思いましたが、間違っているようです。

アイデアは次のとおりです。

declare v_cnt number; 

begin 

select count(*) into v_cnt from all_tables where table_name='TABLE1' and owner = 'AMS'; 

if v_cnt = 0 then 

execute immediate 'CREATE TABLE TABLE1(VALUE VARCHAR2(50) NOT NULL)  ALTER TABLE TABLE1 ADD (MYVAL2 NVARCHAR2(10))'; 

end if; 

end;

ただし、これはエラーになります

ORA-00911: 無効な文字 ORA-06512: 10 行目

バッチ内の各ステートメントは、自分で実行すると正常に実行されます。このステートメントを取得して実行すると、正常に実行されます (2 つのステートメントの間に ; を使用)。を削除すると; ステートメント間で、無効なオプションに関する別のエラーが発生します

計画では、テーブルを構築し、このテーブルのすべての変更ステートメントを含むテーブル スキーマをエクスポートし、インストール/更新プロセスの一部として別のシステムに対してバッチを実行できるようにする予定です。

では、これらの DDL ステートメントを単一の即時実行内でバッチ処理するにはどうすればよいでしょうか? または、必要なことを行うためのより良い方法はありますか?

私は少しオラクル初心者ですが、認めざるを得ません。お待ちいただきありがとうございます。

4

2 に答える 2

4

セミコロンは、Oracle の SQL 構文の一部ではありません。SQL*Plus およびその他のクライアント側ツールは、セミコロンを使用して SQL ステートメントの終了を通知しますが、サーバーはそれを認識しません。

SQL*Plus に強制的にセミコロンを DB に渡すことができます。

SQL> set sqlterminator off
SQL> select * from user_tables;
  2  /
select * from user_tables;
                         *
ERROR at line 1:
ORA-00911: invalid character

このステートメントを取得して実行すると、正常に実行されます (2 つのステートメントの間に ; があります)使用しているクライアント ツールは、DB への 2 つの呼び出しに分割します。

したがって、即時実行内で複数のステートメントを渡すことはできないと思います。

匿名の PL/SQL ブロックを含む文字列を使用して execute immediately を呼び出すことができ、その中で execute immediately を個別に呼び出すことができると思います...そして、それを行うポイントが何であるかはわかりません。;)

于 2009-08-06T22:24:35.893 に答える
2

なぜ単一の EXECUTE IMMEDIATE 呼び出しが必要なのですか? 確かに2つの呼び出しとしてそれを行いますか?

各 DDL ステートメントには暗黙的な COMMIT が含まれているため、単一の呼び出しとして実行することによる同時実行の利点はないことに注意してください。

また、最初の呼び出しでテーブルを正しく設定しないのはなぜですか? あなたはできる...

CREATE TABLE TABLE1(VALUE VARCHAR2(50) NOT NULL, MYVAL2 NVARCHAR2(10))

...2 つの呼び出しを必要とする代わりに。

また、DBMS_METADATA を見たことがありますか... テーブルなどのオブジェクトの DDL を生成できます。

于 2009-08-06T21:33:38.037 に答える