PL / SQLブロックに直接ddlステートメントを記述できないのはなぜですか


11

なぜPL / SQLブロックに直接ddlステートメントを書き込めないのか、たとえば、

CREATE OR REPLACE PROCEDURE test IS
BEGIN
    truncate table table_name; // error
END test;
/

だが、

CREATE OR REPLACE PROCEDURE test IS
BEGIN
    execute immediate 'truncate table table_name'; // works fine
END test;
/

なぜ2番目が正常に実行されたのですか?

回答:


7

ドキュメントで言うように:

PL / SQLプログラム単位内で次のタイプの文を実行できるのは、動的SQLのみです。

  • CREATE、DROP、GRANT、REVOKEなどのデータ定義言語(DDL)ステートメント

TRUNCATE操作がありますDDL

を使用する場合EXECUTE IMMEDIATEDDL実行する操作は暗黙的COMMITに現在のトランザクションになることに注意してください。


1

PL / SQLコード内のDDLは、実際の必要性よりも例外です。解析は構造検証と見なすことができ、構造が実行時に変更されると失われます。プロシージャは、他のオブジェクト(テーブル、または他のpl / sqlコード、ビューなど)を再度解析することを目的としています。依存オブジェクトが変更されるたびに、再コンパイルする必要があります。したがって、構造の変更以外の解析済みコードを作成することは検証できず、コンパイルもできません。ケースを検討する

DROP TABLE T1;

解析時にテーブルが見つかり、プロシージャが正常にコンパイルされますが、最初の実行時にテーブルが削除され、コードが無効になります(次回DROP TABLEがエラーになる)。同様に、テーブルDDLを変更すると再コンパイルが必要になるため、コード解析の利点が失われます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.