CURSOR_SHARING
ON CONVERSION ERROR
fitur tidak bekerja ketika parameter CURSOR_SHARING diatur ke FORCE. Untuk menghindari kesalahan ini, ubah parameter di tingkat sistem, sesi, atau pernyataan.
Idealnya, CURSOR_SHARING harus disetel ke EXACT untuk seluruh sistem. Tetapi jika kita memiliki aplikasi yang tidak menggunakan variabel bind, kita mungkin tidak dapat menjalankan alter system set cursor_sharing=exact;
.
Parameter dapat diatur pada tingkat sesi dengan alter session set cursor_sharing=exact;
, tetapi tidak selalu nyaman untuk terus-menerus mengubah parameter sesi.
Parameter dapat diubah pada tingkat pernyataan dengan petunjuk CURSOR_SHARING_EXACT
:
SQL> select /*+ cursor_sharing_exact */ to_date(the_date default null on conversion error, 'MM/DD/YYYY') the_date
2 from
3 (
4 select '1/1/2021' the_date from dual union all
5 select 'bad date' the_date from dual
6 );
THE_DATE
---------
01-JAN-21
Bug pengurai/pengoptimal
Seperti yang ditemukan @gouessej, ada kemungkinan alasan lain untuk kesalahan ORA-43918 yang tidak terkait dengan berbagi kursor. Tampaknya ada bug pengurai atau pengoptimal terkait dengan transformasi CASE
dan TO_
fungsi pada beberapa versi Oracle.
Misalnya, pernyataan SQL di bawah ini gagal pada Oracle 18c dan 19c:
SQL> select case when v_num is null then 0 else v_num end
2 from
3 (
4 select to_number('120.3' default null on conversion error, '99999D99') as v_num
5 from dual
6 );
select to_number('120.3' default null on conversion error, '99999D99') as v_num
*
ERROR at line 4:
ORA-43918: This argument must be a literal
Saya percaya ini adalah bug pengurai atau pengoptimal karena kesalahan hilang jika Anda menghentikan transformasi dengan menambahkan predikat seperti rownum >= 1
. (Ketika Oracle melihat ROWNUM
, ini mengasumsikan hasil harus ditampilkan dalam urutan tertentu dan tidak akan menerapkan banyak transformasi ke blok kueri tersebut.)
SQL> select case when v_num is null then 0 else v_num end
2 from
3 (
4 select to_number('120.3' default null on conversion error, '99999D99') as v_num
5 from dual
6 where rownum >= 1
7 );
CASEWHENV_NUMISNULLTHEN0ELSEV_NUMEND
------------------------------------
120.3