Brug bindevariabler
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.
Problemet med din kode er, at Oracle skal konvertere DATE
for at kunne opbygge din streng. til en VARCHAR2
. Det gør den ved at bruge din sessions NLS_DATE_FORMAT
. Men din sessions NLS_DATE_FORMAT
indeholder sandsynligvis ikke tidskomponenten, så tiden er tabt, når din procedure faktisk kaldes. Brug af bindevariable betyder, at du ikke behøver at håndtere den slags implicit konvertering (det er også mere effektivt og mere sikkert).
Hvis du virkelig ville undgå at bruge bindevariabler, kunne du eksplicit caste sysdate
til en streng ved hjælp af en to_char
og indsæt derefter en to_date
i det dynamiske procedurekald. Men det er en masse ekstra kode og en række unødvendige konverteringer.
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.