Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Oracle - kursor menggunakan dbms_utility.exec_ddl_statement tidak berjalan dengan benar

DBMS_UTILITY.EXEC_DDL_STATEMENT hanya andal menjalankan DDL. Jika Anda mencoba menjalankannya dengan blok PL/SQL, itu akan gagal secara diam-diam dan tidak menjalankan apa pun.

Ini dapat ditunjukkan dengan menjalankan blok PL/SQL yang seharusnya gagal. Kode di bawah harus menghasilkan ORA-01476: divisor is equal to zero . Tapi malah tidak menghasilkan apa-apa.

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

Gunakan prosedur sementara untuk menjalankan blok PL/SQL dari jarak jauh. Buat prosedur dengan DBMS_UTILITY.EXEC_DDL_STATEMENT lalu panggil dengan SQL dinamis asli.

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

Saya pikir perilaku ini adalah bug. Oracle seharusnya membuat kesalahan daripada tidak melakukan apa-apa.

Selamat datang di neraka gabungan. String menjadi berantakan saat disematkan sedalam 4 level. Namun ada beberapa hal yang dapat Anda lakukan untuk membuat hidup lebih mudah:

  1. Gunakan mekanisme kutipan alternatif bersarang. Misalnya, q'[ ... ]' , di dalam q'< ... >' , dll.
  2. Gunakan string multi-baris. Tidak perlu menggabungkan beberapa baris, cukup gunakan satu string.
  3. Gunakan spasi ekstra untuk membantu mengidentifikasi awal dan akhir string. Saat semuanya menjadi gila, ada baiknya menempatkan pembatas string pada baris dengan sendirinya, sehingga semuanya mudah untuk disejajarkan.
  4. Gunakan REPLACE bukannya penggabungan.

Saya memformat ulang bagian dari kode Anda menggunakan kiat-kiat itu. Stackoverflow tidak memahami mekanisme kutipan alternatif, tetapi string akan terlihat lebih baik dalam editor SQL Oracle yang baik.

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara Mengaktifkan Output Server di DataGrip

  2. Kesalahan Keluaran Fiddle SQL

  3. Menggunakan `SELECT` untuk memanggil fungsi

  4. Pengembang SQL untuk mengimpor dari Excel

  5. Bagaimana saya bisa menulis SQL di Oracle dalam kasus saya?