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