2

ステートメントとユーザー定義のテーブル タイプExecute Immediateを含むステートメントを使用しようとすると問題が発生します。Oracle 11g でCREATE TABLEエラーが発生します。 この問題を解決するための回避策はありますか?ORA-22905

CREATE TYPE MY_TABLE_TYPE AS TABLE OF VARCHAR2(30);  
/  
DECLARE  
    MT MY_TABLE_TYPE;  
BEGIN  
    SELECT * BULK COLLECT INTO MT FROM DUAL;  
    -- Two steps  
    EXECUTE IMMEDIATE 'CREATE TABLE MY_TABLE1 (A VARCHAR2(30))';  
    EXECUTE IMMEDIATE 'INSERT INTO  MY_TABLE1    SELECT * FROM TABLE(:T)' USING MT; -- OK  
    -- One step  
    EXECUTE IMMEDIATE 'CREATE TABLE MY_TABLE2 AS SELECT * FROM TABLE(:T)' USING MT; -- ERROR ORA-22905     
END;  

の実際のコードSELECT * FROM TABLE(:T)は動的 (メイン テーブル名は一時的なもの) であり、低速です。そのため、2 つのステップでテーブルを作成することは避けようとしています ( のようにMY_TABLE1)。また、2つのステップでは使用できませんSELECT *が、すべての列を指定する必要があります(可変量と100列以上)。

4

1 に答える 1

0

この問題を完全に回避する方法がある可能性があります。一括収集をスキップしてCREATE TABLE MY_TABLE AS SELECT * FROM DUAL; 、データを収集するための実際のロジックを単純化しすぎている可能性がある単純な方法を使用します。しかし、ほとんどの場合、一括収集をバイパスして、SQL のみを使用してデータをオブジェクトに直接格納する方法があります。

PL/SQL ソリューションが本当に必要な場合はORA-22905: cannot access rows from a non-nested table item、オブジェクト型を作成し、その型に基づいてテーブルを作成することでエラーを回避できます。これはパフォーマンスの問題を解決しない可能性がありますが、少なくともこれにより、テーブル DDL のすべての列を再指定する必要がなくなります。

CREATE TYPE MY_TABLE_OBJECT IS OBJECT
(
    A VARCHAR2(30)
);

CREATE TYPE MY_TABLE_TYPE2 AS TABLE OF VARCHAR2(30);

DECLARE  
    MT MY_TABLE_TYPE2;
BEGIN  
    SELECT * BULK COLLECT INTO MT FROM DUAL;  
    EXECUTE IMMEDIATE 'CREATE TABLE MY_TABLE2 OF MY_TABLE_OBJECT';
    EXECUTE IMMEDIATE 'INSERT INTO  MY_TABLE2 SELECT * FROM TABLE(:T)' USING MT;
END;
/
于 2014-03-13T06:07:37.120 に答える