sql >> データベース >  >> RDS >> Oracle

Oracle-dbms_utility.exec_ddl_statementを使用するカーソルが正しく実行されていません

    DBMS_UTILITY.EXEC_DDL_STATEMENT DDLのみを確実に実行します。 PL / SQLブロックを使用して実行しようとすると、サイレントに失敗し、何も実行されません。

    これは、明らかに失敗するはずのPL/SQLブロックを実行することで実証できます。以下のコードはすべき ORA-01476: divisor is equal to zero 。しかし、代わりに何もしません。

    begin
        [email protected](
            q'[declare v_test number; begin v_test := 1/0; end;]'
        );
    end;
    /
    

    一時的なプロシージャを使用して、PL/SQLブロックをリモートで実行します。 DBMS_UTILITY.EXEC_DDL_STATEMENTを使用してプロシージャを作成します 次に、ネイティブ動的SQLで呼び出します。

    begin
        [email protected](
            q'[
                create or replace procedure test_procedure
                is
                    v_test number;
                begin
                    v_test := 1/0;
                end;
            ]'
        );
        execute immediate 'begin [email protected]; end;';
    end;
    /
    
    RESULTS:
    
    ORA-01476: divisor is equal to zero
    ORA-06512: at "JHELLER.TEST_PROCEDURE", line 5
    ORA-06512: at line 1
    ORA-06512: at line 12
    

    この動作はバグだと思います。 Oracleは、単に何もしないのではなく、エラーをスローする必要があります。

    連結地獄へようこそ。文字列は、4レベルの深さで埋め込まれると、乱雑になります。しかし、生活を楽にするためにできることがいくつかあります:

    1. ネストされた代替引用メカニズムを使用します。たとえば、q'[ ... ]'q'< ... >'内 、など。
    2. 複数行の文字列を使用します。複数の行を連結する必要はなく、1つの文字列を使用するだけです。
    3. 余分な間隔を使用して、文字列の開始と終了を識別しやすくします。物事がこれほどおかしくなったときは、すべてを簡単に並べられるように、文字列区切り文字をすべて1行に配置する価値があります。
    4. REPLACEを使用する 連結の代わりに。

    これらのヒントを使用して、コードの一部を再フォーマットしました。 Stackoverflowは代替の引用メカニズムを理解していませんが、文字列は優れたOracleSQLエディターで見栄えが良くなるはずです。

    declare
        v_db_name varchar2(30) := 'myself';
        sql_update varchar2(32767);
    begin
        execute immediate replace(
        q'[
            begin
                [email protected]#DB_NAME#
                (
                    q'<
                        create or replace procedure cw_drop_table is
                            sql_drop varchar2(2000);
                        begin
                            sql_drop :=
                            q'{
                                BEGIN
                                    EXECUTE IMMEDIATE 'DROP TABLE iSecurity2_dupes_bak';
                                EXCEPTION WHEN OTHERS THEN
                                    IF SQLCODE != -942 THEN
                                        NULL;
                                    END IF;
                                END;
                            }';
                            execute immediate sql_drop;
                        end;
                    >'
                );
                execute immediate 'begin [email protected]#DB_NAME#; end;';
            end;
        ]', '#DB_NAME#', v_db_name);
    
        sql_update := 'create table iSecurity2_dupes_bak as select * from iSecurity2';
        execute immediate 'begin [email protected]'||v_db_name||
            '(:sql_update);  end;' using sql_update;
        commit;
    end;
    /
    



    1. 新しいDBシステムを学ぶことの利点

    2. Oracleを使用して区切り文字の位置で文字列を分割する

    3. MySQLUTCタイムスタンプ文字列からのActionScriptDateオブジェクトの作成

    4. MySQLからJSONデータを取得する方法は?