7

Oracle PL/SQL ブロックで動的 SQL が許可される理由

begin
    execute immediate 'drop table table_name';
end;

しかし、静的ではありませんか?

begin
    drop table table_name;
end;

答えが「言語がそのように機能するため」よりも洞察に満ちていることを願っています。

4

3 に答える 3

9

答えは、PL/SQL は動的ポリモーフィズムをサポートしていないということです。静的ポリモーフィズムのみをサポートするため、

すべての PL/SQL は、ツリー構造の中間言語である Ada の「DIANA」 -> 記述的中間属性表記法を生成します。DIANA は、コンパイラによって内部的に使用されます。

コンパイル時に、PL/SQL ソース コードがシステム コードに変換され、対応する DIANA が生成されます。ここで、コンパイル時に存在しない create table ステートメントのような DDL ステートメントがあった場合、プログラムの実行後に作成されると考えてください。PL/SQLエンジンはどのようにDIANAを生成しますか????

DIANA は、PL/SQL でサブプログラムをチェック/検証するために重要な役割を果たします。これが必要なのは、サブプログラムがテーブル、ビュー、シノニム、またはその他のストアド プロシージャなどのデータベース オブジェクトを使用できることがわかっているためです。次にプログラムを実行したときに、オブジェクトが変更/削除/ドロップされている可能性があります。例:誰かがテーブルを削除した可能性があり、ストアドプロシージャまたは関数の署名が変更された可能性があります。

そのため、一般的に PL/SQL はデータベース構造内のデータを操作するために使用されますが、それらの構造を操作するためには使用されません。

ただし、動的 ​​SQL および DBMS_SQL パッケージを使用して操作する方法はありますが、これらの方法論は慎重に使用する必要があります。たとえば、テーブルを作成する場合、このテーブルが既に存在するかどうか、またはデータ ディクショナリ ビューを使用していないかどうかを最初に確認する必要があります。

于 2013-03-05T20:58:33.797 に答える
3

おそらく、それ以外の場合、一部のコードは次のようになるためです。

  begin
    create table tmp (n number);
    insert into tmp values (1);
  end;

そして、挿入時にテーブルが存在することをコンパイラが認識していることを期待します。ブロックのコンパイルは、私にとってはるかに困難です。ここでは非常に単純なケースですが、いくつかの条件分岐や複雑な blabla を簡単に想像できます。

しかし、DDL をすぐに実行するブロックに配置する必要があるため、この制限は理解しやすいかもしれません。

ただのアイデア...

于 2013-03-05T19:41:54.960 に答える
0

実行/コンパイルの前に、オラクルは、pl/sql ブロッ​​ク内で参照されるテーブル、ビュー、ストアドプロシージャなどのすべてのスキーマ オブジェクトのすべてのアクセス許可、有効性、および依存関係をチェックします。しかし、DDL ステートメントの問題は、スキーマ オブジェクトを作成、変更、または削除できることです。その結果、オブジェクトの依存関係が変更される可能性があります。そのため、DDL を使用して削除された 1 つのオブジェクトを参照している可能性があります。このような状況を防ぐために、plsqlブロックは直接DDLステートメントを許可していないと思います。ただし、動的クエリを使用して PL/SQL ブロックに DDL を含めることはできます。この場合、実際のクエリは実行時までわからないため、基本的には DDL ステートメントを動的 SQL の形式で非表示にして、PL/SQL ブロック内に DDL を含めることができます。

私のブログを参照して、例を使用して概念を理解することができます: Why oracle does not allow direct DDL statement inside the procedure (PLSQL BLOCK)

于 2020-05-19T18:04:53.087 に答える