Oracle
 sql >> Base de données >  >> RDS >> Oracle

Paramètre de date PL/SQL dynamique avec valeur de temps conservée

Utiliser des variables de liaison

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.

Le problème avec votre code est que pour créer votre chaîne, Oracle doit convertir le DATE à un VARCHAR2 . Il le fait en utilisant le NLS_DATE_FORMAT de votre session . Mais le NLS_DATE_FORMAT de votre session n'inclut probablement pas le composant de temps, de sorte que le temps est perdu lorsque votre procédure est réellement appelée. L'utilisation de variables liées signifie que vous n'avez pas à gérer ce type de conversion implicite (c'est aussi plus efficace et plus sûr).

Si vous vouliez vraiment éviter d'utiliser des variables de liaison, vous pourriez transtyper explicitement sysdate à une chaîne en utilisant un to_char puis mettre un to_date dans l'appel de procédure dynamique. Mais cela représente beaucoup de code supplémentaire et un certain nombre de conversions inutiles.

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.