sql >> Database teknologi >  >> RDS >> Oracle

ON CONVERSION ERROR mislykkes med ORA-43918:Dette argument skal være bogstaveligt

CURSOR_SHARING

ON CONVERSION ERROR funktionen virker ikke, når parameteren CURSOR_SHARING er sat til FORCE. For at undgå denne fejl skal du ændre parameteren på system-, sessions- eller sætningsniveau.

Ideelt set bør CURSOR_SHARING indstilles til EXACT for hele systemet. Men hvis vi har et program, der ikke bruger bindevariabler, kan vi sandsynligvis ikke køre alter system set cursor_sharing=exact; .

Parameteren kan indstilles på sessionsniveau med alter session set cursor_sharing=exact; , men det er ikke altid praktisk at ændre sessionsparametre konstant.

Parameteren kan ændres på sætningsniveauet med tippet 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

Parser/optimizer-fejl

Som @gouessej opdagede, er der en anden potentiel årsag til ORA-43918-fejlen, som ikke er relateret til markørdeling. Der ser ud til at være parsing- eller optimeringsfejl relateret til transformation af CASE og TO_ funktioner på nogle versioner af Oracle.

For eksempel fejler nedenstående SQL-sætning på Oracle 18c og 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

Jeg tror, ​​dette er en parsing- eller optimeringsfejl, fordi fejlen forsvinder, hvis du stopper transformationer ved at tilføje et prædikat som rownum >= 1 . (Når Oracle ser ROWNUM , det antager, at resultaterne skal vises i en bestemt rækkefølge og vil ikke anvende så mange transformationer til den pågældende forespørgselsblok.)

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. VÆLG Fra MySQL-visning med HAVING-klausul returnerer et tomt resultatsæt

  2. Sådan udføres og administreres MySQL-sikkerhedskopier til Oracle DBA'er

  3. placere flere resultater i en enkelt matrix

  4. Problemer med tabel-værdi parameter ydeevne