Använd bindningsvariabler
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 kod är att för att bygga upp din sträng måste Oracle konvertera DATE
till en VARCHAR2
. Den gör det med sessionens NLS_DATE_FORMAT
. Men din sessions NLS_DATE_FORMAT
innehåller förmodligen inte tidskomponenten så tiden går förlorad när din procedur faktiskt anropas. Att använda bindningsvariabler innebär att du inte behöver hantera den typen av implicit konvertering (det är också effektivare och säkrare).
Om du verkligen ville undvika att använda bindningsvariabler, kunde du uttryckligen casta sysdate
till en sträng med en to_char
och lägg sedan en to_date
i det dynamiska proceduranropet. Men det är mycket extra kod och ett antal onödiga konverteringar.
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.