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

Mengapa saya tidak dapat menggunakan variabel bind dalam pernyataan DDL/SCL dalam SQL dinamis?

Variabel ikatan tidak diperbolehkan dalam pernyataan DDL. Jadi pernyataan berikut akan menyebabkan kesalahan:

  • Contoh #1:Pernyataan DDL . Akan menyebabkan ORA-01027:variabel ikat tidak diizinkan untuk operasi definisi data

    EXECUTE IMMEDIATE
      'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT :def_val )'
      USING 42;
    
  • Contoh #2:Pernyataan DDL . Akan menyebabkan ORA-00904::pengenal tidak valid

    EXECUTE IMMEDIATE
      'CREATE TABLE dummy_table ( :col_name NUMBER )'
      USING var_col_name;
    
  • Contoh #3:Pernyataan SCL . Akan menyebabkan ORA-02248:opsi tidak valid untuk ALTER SESSION

    EXECUTE IMMEDIATE
      'ALTER SESSION SET NLS_CALENDAR = :cal'
      USING var_calendar_option;
    

Masalah

Untuk memahami mengapa ini terjadi, kita perlu melihat Bagaimana Pernyataan SQL Dinamis Diproses.

Biasanya, program aplikasi meminta pengguna untuk teks pernyataan SQL dan nilai variabel host yang digunakan dalam pernyataan. Kemudian Oracle mem-parsing pernyataan SQL. Artinya, Oracle memeriksa pernyataan SQL untuk memastikannya mengikuti aturan sintaks dan mengacu pada objek database yang valid. Parsing juga melibatkan pemeriksaan hak akses basis data , memesan sumber daya yang dibutuhkan, dan menemukan jalur akses yang optimal.

Penekanan ditambahkan oleh penjawab

Perhatikan bahwa langkah penguraian terjadi sebelum mengikat variabel apa pun ke pernyataan dinamis. Jika Anda memeriksa empat contoh di atas, Anda akan menyadari bahwa tidak ada cara bagi parser untuk menjamin validitas sintaksis dari pernyataan SQL dinamis ini tanpa mengetahui nilai untuk variabel bind.

  • Contoh #1 :Parser tidak dapat mengetahui apakah nilai pengikatan akan valid. Bagaimana jika alih-alih USING 42 , programmer menulis USING 'forty-two' ?
  • Contoh #2 :Parser tidak dapat mengetahui apakah :col_name akan menjadi nama kolom yang valid. Bagaimana jika nama kolom terikat adalah 'identifier_that_well_exceeds_thirty_character_identifier_limit' ?
  • Contoh #3 :Nilai untuk NLS_CALENDAR dibangun dalam konstanta (untuk versi Oracle yang diberikan?). Parser tidak dapat mengetahui apakah variabel terikat akan memiliki nilai yang valid.

Jadi jawabannya adalah Anda tidak dapat mengikat elemen skema seperti nama tabel, nama kolom dalam SQL dinamis. Anda juga tidak dapat mengikat konstanta bawaan .

Solusi

Satu-satunya cara untuk mencapai elemen/konstanta skema referensi secara dinamis adalah dengan menggunakan rangkaian string dalam pernyataan SQL dinamis.

  • Contoh #1:

    EXECUTE IMMEDIATE
      'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT ' || to_char(42) || ')';
    
  • Contoh #2:

    EXECUTE IMMEDIATE
      'CREATE TABLE dummy_table (' || var_col_name || ' NUMBER )';
    
  • Contoh #3:

    EXECUTE IMMEDIATE
      'ALTER SESSION SET NLS_CALENDAR = ''' || var_calendar_option || '''';
    



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Rata-rata tanggal di Oracle sql

  2. Bagaimana menemukan tabel di mana statistik dikunci

  3. Oracle masukkan jika tidak ada pernyataan

  4. Bagaimana cara mengekspor skema database di Oracle ke file dump

  5. Kesalahan memuat oci8.so dengan server Ubuntu 17.04 php 7 dan Apache2