CURSOR_SHARING
ON CONVERSION ERROR
funkcja nie działa, gdy parametr CURSOR_SHARING jest ustawiony na FORCE. Aby uniknąć tego błędu, zmień parametr na poziomie systemu, sesji lub instrukcji.
Idealnie, CURSOR_SHARING powinien być ustawiony na DOKŁADNIE dla całego systemu. Ale jeśli mamy aplikację, która nie używa zmiennych bind, prawdopodobnie nie możemy uruchomić alter system set cursor_sharing=exact;
.
Parametr można ustawić na poziomie sesji za pomocą alter session set cursor_sharing=exact;
, ale nie zawsze jest wygodne ciągłe zmienianie parametrów sesji.
Parametr można zmienić na poziomie instrukcji za pomocą podpowiedzi 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
Błąd parsera/optymalizatora
Jak odkrył @gouessej, istnieje inny potencjalny powód błędu ORA-43918, który nie jest związany z udostępnianiem kursora. Wygląda na to, że występują błędy parsowania lub optymalizacji związane z przekształcaniem CASE
i TO_
działa w niektórych wersjach Oracle.
Na przykład poniższa instrukcja SQL nie działa w Oracle 18c i 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
Uważam, że jest to błąd analizowania lub optymalizatora, ponieważ błąd znika, jeśli zatrzymasz transformacje, dodając predykat, taki jak rownum >= 1
. (Gdy Oracle widzi ROWNUM
, zakłada, że wyniki muszą być wyświetlane w określonej kolejności i nie zastosuje tylu przekształceń do tego bloku zapytania).
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