sql >> Databasteknik >  >> RDS >> Oracle

ON CONVERSION ERROR misslyckas med ORA-43918:Detta argument måste vara bokstavligt

CURSOR_SHARING

ON CONVERSION ERROR funktionen fungerar inte när parametern CURSOR_SHARING är inställd på FORCE. För att undvika detta fel, ändra parametern på system-, sessions- eller programsatsnivå.

Helst bör CURSOR_SHARING ställas in på EXAKT för hela systemet. Men om vi har ett program som inte använder bindningsvariabler kan vi förmodligen inte köra alter system set cursor_sharing=exact; .

Parametern kan ställas in på sessionsnivå med alter session set cursor_sharing=exact; , men det är inte alltid bekvämt att ständigt ändra sessionsparametrar.

Parametern kan ändras på satsnivå med tipset 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 bugg

Som @gouessej upptäckte finns det en annan potentiell orsak till ORA-43918-felet som inte är relaterat till markördelning. Det verkar finnas analys- eller optimeringsbuggar relaterade till att transformera CASE och TO_ fungerar på vissa versioner av Oracle.

Till exempel misslyckas nedanstående SQL-sats på Oracle 18c och 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

Jag tror att detta är en analys- eller optimeringsbugg eftersom felet försvinner om du stoppar transformationer genom att lägga till ett predikat som rownum >= 1 . (När Oracle ser ROWNUM , det antar att resultaten måste visas i en viss ordning och kommer inte att tillämpa lika många transformationer på det frågeblocket.)

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. Kolumnaliaset känns inte igen i WHERE-satsen

  2. Syntax för for-loop i SQL Server

  3. Oracle Install för SSIS-anslutning (och drivrutiner 32 64 bitar)

  4. mysql transaktionsfelhantering