Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Parâmetro de data PL/SQL dinâmico com valor de tempo retido


Usar variáveis ​​de vinculação
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.

O problema com seu código é que, para construir sua string, o Oracle precisa converter o DATE para um VARCHAR2 . Ele faz isso usando o NLS_DATE_FORMAT da sua sessão . Mas o NLS_DATE_FORMAT da sua sessão provavelmente não inclui o componente de tempo, então o tempo é perdido quando seu procedimento é realmente chamado. Usar variáveis ​​de ligação significa que você não precisa lidar com esse tipo de conversão implícita (também é mais eficiente e mais seguro).

Se você realmente deseja evitar o uso de variáveis ​​de ligação, pode converter explicitamente sysdate para uma string usando um to_char e, em seguida, coloque um to_date na chamada de procedimento dinâmico. Mas isso é muito código extra e várias conversões desnecessárias.
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.