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