sql >> Database >  >> RDS >> Oracle

ON CONVERSION ERROR mislukt met ORA-43918:dit argument moet letterlijk zijn

CURSOR_SHARING

De ON CONVERSION ERROR functie werkt niet wanneer de parameter CURSOR_SHARING is ingesteld op FORCE. Om deze fout te voorkomen, wijzigt u de parameter op systeem-, sessie- of instructieniveau.

Idealiter zou CURSOR_SHARING voor het hele systeem op EXACT moeten worden ingesteld. Maar als we een toepassing hebben die geen bindvariabelen gebruikt, kunnen we waarschijnlijk niet alter system set cursor_sharing=exact; uitvoeren .

De parameter kan op sessieniveau worden ingesteld met alter session set cursor_sharing=exact; , maar het is niet altijd handig om sessieparameters voortdurend te wijzigen.

De parameter kan op instructieniveau worden gewijzigd met de hint 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-bug

Zoals @gouessej ontdekte, is er nog een andere mogelijke reden voor de ORA-43918-fout die geen verband houdt met het delen van de cursor. Er lijken parseer- of optimalisatiefouten te zijn met betrekking tot het transformeren van CASE en TO_ functies op sommige versies van Oracle.

De onderstaande SQL-instructie mislukt bijvoorbeeld op Oracle 18c en 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

Ik geloof dat dit een parseer- of optimalisatiefout is, omdat de fout verdwijnt als je transformaties stopt door een predikaat toe te voegen zoals rownum >= 1 . (Als Oracle ROWNUM ziet , het gaat ervan uit dat de resultaten in een bepaalde volgorde moeten worden weergegeven en zal niet zoveel transformaties toepassen op dat queryblok.)

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. Hoe u de meest relevante vermeldingen uit de database kunt krijgen en bestellen met meerdere trefwoorden Laravel 5

  2. mysqldump test vergrendelingstabellen

  3. Sorteer Multi-dimensional Array op gegeven indexen - PHP?

  4. Opgeslagen procedurefoutargument 1 voor routine ... is geen variabele of NIEUWE pseudo-variabele in BEFORE trigger