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 menulisUSING '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 || '''';