Oracle
 sql >> база данни >  >> RDS >> Oracle

ГРЕШКА ПРИ ПРЕОБРАЗУВАНЕ се проваля с ORA-43918:Този аргумент трябва да е литерал

CURSOR_SHARING

ON CONVERSION ERROR функцията не работи, когато параметърът CURSOR_SHARING е зададен на FORCE. За да избегнете тази грешка, променете параметъра на ниво система, сесия или оператор.

В идеалния случай CURSOR_SHARING трябва да бъде настроен на ТОЧНО за цялата система. Но ако имаме приложение, което не използва свързващи променливи, вероятно не можем да изпълним alter system set cursor_sharing=exact; .

Параметърът може да бъде зададен на ниво сесия с alter session set cursor_sharing=exact; , но не винаги е удобно постоянно да променяте параметрите на сесията.

Параметърът може да бъде променен на ниво израз с подсказката 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

Грешка в анализатора/оптимизатора

Както откри @gouessej, има друга потенциална причина за грешката ORA-43918, която не е свързана със споделянето на курсора. Изглежда има грешки при анализиране или оптимизиране, свързани с трансформирането на CASE и TO_ функции на някои версии на Oracle.

Например, следният SQL оператор е неуспешен на Oracle 18c и 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

Вярвам, че това е грешка при синтактичен анализ или оптимизатор, защото грешката изчезва, ако спрете трансформациите чрез добавяне на предикат като rownum >= 1 . (Когато Oracle види ROWNUM , той предполага, че резултатите трябва да бъдат показани в определен ред и няма да приложи толкова много трансформации към този блок на заявката.)

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. Не може да се вмъкне Unicode с помощта на cx-Oracle

  2. cx_Oracle не разпознава местоположението на инсталацията на софтуера на Oracle за инсталиране на Linux

  3. Получете брой последователни дни, отговарящи на даден критерий

  4. Защо тази проверка за нулев асоциативен масив в PL/SQL е неуспешна?

  5. ClassCastException:org.jboss.jca.adapters.jdbc.jdk6.WrappedPreparedStatementJDK6 не може да бъде прехвърлен към OraclePreparedStatement