CURSOR_SHARING
ON CONVERSION ERROR
tính năng không hoạt động khi tham số CURSOR_SHARING được đặt thành FORCE. Để tránh lỗi này, hãy thay đổi tham số ở cấp hệ thống, phiên hoặc câu lệnh.
Tốt nhất, CURSOR_SHARING nên được đặt thành EXACT cho toàn bộ hệ thống. Nhưng nếu chúng tôi có một ứng dụng không sử dụng các biến liên kết, chúng tôi có thể không thể chạy alter system set cursor_sharing=exact;
.
Tham số có thể được đặt ở cấp phiên với alter session set cursor_sharing=exact;
, nhưng không phải lúc nào cũng thuận tiện khi liên tục thay đổi các thông số phiên.
Tham số có thể được thay đổi ở cấp câu lệnh với gợi ý 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
Lỗi trình phân tích cú pháp / trình tối ưu hóa
Như @gouessej đã phát hiện ra, có một lý do tiềm ẩn khác gây ra lỗi ORA-43918 không liên quan đến chia sẻ con trỏ. Có vẻ như có lỗi phân tích cú pháp hoặc trình tối ưu hóa liên quan đến việc chuyển đổi CASE
và TO_
các chức năng trên một số phiên bản của Oracle.
Ví dụ:câu lệnh SQL dưới đây không thành công trên Oracle 18c và 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
Tôi tin rằng đây là lỗi phân tích cú pháp hoặc trình tối ưu hóa vì lỗi sẽ biến mất nếu bạn dừng chuyển đổi bằng cách thêm một vị từ như rownum >= 1
. (Khi Oracle nhìn thấy ROWNUM
, nó giả định các kết quả phải được hiển thị theo một thứ tự nhất định và sẽ không áp dụng nhiều phép biến đổi cho khối truy vấn đó.)
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