2

この質問は、「作成」権限が許可されていない環境に関するものです。バージョンは次のとおりです。OracleDatabase10gおよびPL/SQL 8.0.0.1480

以下は、私が達成しようとしていることを示す小さなサンプルです。これは、コレクション内の「フィールド」のセットを循環し、それらにいくつかの値を入力することです。各「フィールド」には、同じルート名「MyCol_」の後に数字が続きます。

例:MyCol_1、MyCol_2、...、MyCol_n。

連結を構築することはできますが、EXECUTEIMMEDIATEを機能させることができません。

'MyCol_1'がハードコードされた値である場合、次の行を実行できます。

MyCol_1.EXTEND;        
MyCol_1(1) := 'abc';

しかし、これらのハードコードされた値を連結された文字列に置き換えると、失敗します

v_LoopCounter:=1;        
v_MyTestCode := 'MyCol_' || v_LoopCounter || '.EXTEND' ;
DBMS_OUTPUT.PUT_LINE('Present value of v_MyTestCode: '||v_MyTestCode);
execute immediate v_MyTestCode;     -- <<<-- ERRORS ON THIS LINE <<<--

表示されるエラーは次のとおりです。ORA-00900:無効なSQLステートメント

私はこのサイトから与えられたアドバイスに従おうとしました:http: //docs.oracle.com/cd/B10501_01/appdev.920/a97269/pc_13dyn.htm

...動的SQLステートメントを文字列に格納します。文字列はホスト変数または引用符付きリテラルである必要があります。SQLステートメントを文字列に格納するときは、キーワードEXECSQLと「;」を省略してください。ステートメントターミネーター。

また、 http ://www.databasejournal.com/features/oracle/article.php/2109681/EXECUTE-IMMEDIATE-option-for-Dynamic-SQL-and-PLSQL.htmからのアドバイスもあります。

EXEC、EXECUTEなど、EXECUTE IMMEDIATEのさまざまなバリエーションを試しましたが、成功しませんでした。

これが完全なコードサンプルです。これは、この問題をデバッグするためのベータコードです。これが、連結された文字列でEXECUTEIMMEDIATEを使用することについての質問の邪魔にならないことを願っています。私はサンプルコードをシンプルで十分に文書化するように努めました。うまくいけば、これは状況を説明するのに役立ちます。

DECLARE

   TYPE MyNestedTable IS TABLE of varchar2(100);       

   MyCol_1 MyNestedTable;
   MyCol_2 MyNestedTable;

   v_LoopCounter  NUMBER;

   v_MyTestCode   VARCHAR2(200);
   v_SomeValue    VARCHAR2(200);

BEGIN

    MyCol_1 := MyNestedTable();
    MyCol_2 := MyNestedTable(); 

    v_LoopCounter:=1;

    v_MyTestCode := 'MyCol_' || v_LoopCounter || '.EXTEND' ;
    DBMS_OUTPUT.PUT_LINE('Present value of v_MyTestCode: '||v_MyTestCode);
    EXECUTE IMMEDIATE v_MyTestCode;     -- <<<-- ERRORS ON THIS LINE <<<--

    v_SomeValue := 'abc';
    v_MyTestCode := 'MyCol_' || v_LoopCounter || ':= '||v_SomeValue;
    DBMS_OUTPUT.PUT_LINE('Present value of v_MyTestCode: '||v_MyTestCode);
    EXECUTE IMMEDIATE v_MyTestCode;     -- <<<-- ERRORS ON THIS LINE <<<--


        MyCol_2.EXTEND;
        MyCol_2(1) := 200;
        DBMS_OUTPUT.PUT_LINE('MyCol_2 '||MyCol_2(1));    
        DBMS_OUTPUT.PUT_LINE('MyCol_1 '|| ', '||'MyCol_2 ');            DBMS_OUTPUT.PUT_LINE(MyCol_1(1)|| ', '||MyCol_2(1));

END;
4

1 に答える 1

3

Collection.EXTEND全体がステートメントではなく、SQLコレクションを拡張するために使用されるPLSQLステートメントです。これを言っても、以下のコードは決して機能しません-

v_LoopCounter:=1;        
v_MyTestCode := 'MyCol_' || v_LoopCounter || '.EXTEND' ;
execute immediate v_MyTestCode;

ただし、動的SQLがPLSQLスタブ/匿名ブロック全体である場合は、それでEXECUTE IMMEDIATE機能します。好き

v_LoopCounter:=1;        
v_MyTestCode := 'begin MyCol_' || v_LoopCounter || '.EXTEND;end;' ;
execute immediate v_MyTestCode;

これは目的を果たす可能性がありますが、上記がストアドプロシージャ自体の内部から実行される場合、の範囲.EXTENDは疑わしいです(つまり、テストされていません)。あなたはそれがうまくいくかどうか試してみるかもしれません。

于 2012-09-15T03:39:58.597 に答える