CURSOR_COMPARTIR
El ON CONVERSION ERROR
la función no funciona cuando el parámetro CURSOR_SHARING está establecido en FORCE. Para evitar este error, cambie el parámetro a nivel de sistema, sesión o declaración.
Idealmente, CURSOR_SHARING debe establecerse en EXACTO para todo el sistema. Pero si tenemos una aplicación que no usa variables de vinculación, probablemente no podamos ejecutar alter system set cursor_sharing=exact;
.
El parámetro se puede establecer a nivel de sesión con alter session set cursor_sharing=exact;
, pero no siempre es conveniente cambiar constantemente los parámetros de la sesión.
El parámetro se puede cambiar en el nivel de declaración con la sugerencia 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
Error del analizador/optimizador
Como descubrió @gouessej, existe otra posible razón para el error ORA-43918 que no está relacionado con el uso compartido del cursor. Parece que hay errores de análisis o optimización relacionados con la transformación de CASE
y TO_
funciona en algunas versiones de Oracle.
Por ejemplo, la siguiente instrucción SQL falla en Oracle 18c y 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
Creo que se trata de un error de análisis o optimización porque el error desaparece si detiene las transformaciones agregando un predicado como rownum >= 1
. (Cuando Oracle ve ROWNUM
, asume que los resultados deben mostrarse en un orden determinado y no aplicará tantas transformaciones a ese bloque de consulta).
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