sql >> Base de Datos >  >> RDS >> Oracle

Parámetro de fecha PL/SQL dinámico con valor de tiempo retenido

Usar variables de vinculación

SQL> create or replace procedure proc( p_dt in date )
  2  as
  3  begin
  4    dbms_output.put_line( to_char( p_dt, 'yyyy-mm-dd hh24:mi:ss' ));
  5  end;
  6  /

Procedure created.

SQL> declare
  2    l_sql varchar2(1000);
  3  begin
  4    l_sql := 'begin proc(:dt); end;';
  5    execute immediate l_sql using sysdate;
  6  end;
  7  /
2013-08-26 22:14:26

PL/SQL procedure successfully completed.

El problema con su código es que para construir su cadena, Oracle tiene que convertir el DATE a un VARCHAR2 . Lo hace usando el NLS_DATE_FORMAT de su sesión . Pero el NLS_DATE_FORMAT de su sesión probablemente no incluya el componente de tiempo, por lo que el tiempo se pierde cuando se llama realmente a su procedimiento. El uso de variables de vinculación significa que no tiene que lidiar con ese tipo de conversión implícita (también es más eficiente y más seguro).

Si realmente quisiera evitar el uso de variables de vinculación, podría convertir explícitamente sysdate a una cadena usando un to_char y luego poner un to_date en la llamada de procedimiento dinámico. Pero eso es mucho código extra y un número de conversiones innecesarias.

SQL> ed
Wrote file afiedt.buf

  1  declare
  2    l_sql varchar2(1000);
  3  begin
  4    l_sql := q'{begin proc(to_date('}' ||
  5               to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') ||
  6               q'{', 'yyyy-mm-dd hh24:mi:ss')); end;}';
  7    execute immediate l_sql;
  8* end;
SQL> /
2013-08-26 22:19:52

PL/SQL procedure successfully completed.