Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Błąd ON CONVERSION ERROR z ORA-43918:ten argument musi być literałem

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. cx_Oracle przekroczenie limitu czasu

  2. Nie można wstawić znaków arabskich do bazy danych Oracle

  3. Oracle 12c IDENTYFIKOWANE WARTOŚCIAMI

  4. 9 najczęściej zadawanych zapytań dotyczących drukarek Oracle Apps

  5. Klient Oracle ORA-12541:TNS:no listener