6

PL / SQLでテーブルを作成するために、以下のコードを試しています。

DECLARE
    V_NAME VARCHAR2(20);
BEGIN
    EXECUTE IMMEDIATE 'CREATE TABLE TEMP(NAME VARCHAR(20))';
    EXECUTE IMMEDIATE 'INSERT INTO TEMP VALUES(''XYZ'')';
    SELECT NAME INTO V_NAME FROM TEMP;
END;
/

ステートメントは次のSELECTエラーで失敗します。

PL/SQL: ORA-00942: table or view does not exist

CREATE, INSERT and SELECT1つのPL/SQLブロックで次々にすべてを実行することは可能ですか?

4

2 に答える 2

13

私はあなたが次のようなことをしていると思います:

declare
   v_temp varchar2(20);
begin
   execute immediate 'create table temp(name varchar(20))';
   execute immediate 'insert into temp values(''XYZ'')';

   select name into v_name from temp;
end;

コンパイル時に、テーブル、、TEMP存在しません。まだ作成されていません。存在しないため、そこから選択することはできません。したがって、SELECTも動的に実行する必要があります。構文を使用することはできますが、この特定の状況では実際にはSELECTを実行する必要はありません。returning into

declare
   v_temp varchar2(20)
begin
   execute immediate 'create table temp(name varchar2(20))';
   execute immediate 'insert into temp 
                      values(''XYZ'')
                      returning name into :1'
                returning into v_temp;
end;

ただし、テーブルを動的に作成する必要があるということは、通常、スキーマの設計が不適切であることを示しています。それは本当に必要ではないはずです。

RenéNyffeneggerの投稿「動的SQLが悪いのはなぜですか?」をお勧めします。パフォーマンスの観点から、可能な限り動的SQLを回避する必要がある理由。また、 SQLインジェクションに対してはるかにオープンであり、バインド変数を使用DBMS_ASSERTして、それを防ぐのに役立つ必要があることにも注意してください。

于 2012-06-30T10:16:24.470 に答える
2

プログラムを複数回実行すると、selectステートメントを動的SQLとして実行するようにプログラムを変更した後、またはreturning into句を使用した後でも、エラーが発生します。プログラムを最初に実行すると問題なくテーブルが作成されますが、次回実行すると、テーブルが最初に作成されており、dropステートメントがないため、エラーが発生します。「テーブルはすでに存在します。データベース」。したがって、pl / sqlプログラムで表を作成する前に、同じ名前の表がデータベースにすでに存在するかどうかを常に確認することをお勧めします。このチェックは、データベースタイプに応じてメタデータを格納するデータディクショナリビュー/システムテーブルを使用して実行できます。

たとえば、Oracleでは、次のビューを使用して、テーブルを作成する必要があるかどうかを判断できます。

DBA_TABLES、ALL_TABLES、USER_TABLES

于 2013-02-11T21:28:21.347 に答える