Użyj zmiennych wiązania
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.
Problem z twoim kodem polega na tym, że aby zbudować twój łańcuch, Oracle musi przekonwertować DATE
do VARCHAR2
. Robi to za pomocą NLS_DATE_FORMAT
sesji . Ale NLS_DATE_FORMAT
sesji prawdopodobnie nie zawiera składnika czasu, więc czas jest tracony, gdy procedura jest faktycznie wywoływana. Używanie zmiennych wiązania oznacza, że nie musisz zajmować się tego rodzaju niejawną konwersją (jest to również bardziej wydajne i bezpieczniejsze).
Jeśli naprawdę chcesz uniknąć używania zmiennych bind, możesz jawnie rzutować sysdate
do ciągu znaków za pomocą to_char
a następnie umieść to_date
w dynamicznym wywołaniu procedury. Ale to dużo dodatkowego kodu i wiele niepotrzebnych konwersji.
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.