sql >> Databasteknik >  >> RDS >> Oracle

Dynamisk PL/SQL-datumparameter med bibehållet tidsvärde

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.



  1. Hitta rader i A som inte har en tillhörande rad i B, där FK är på B?

  2. Ställ in alternativ 9 i SQL Server lagrad procedur med WinHttp.WinHttpRequest.5.1 för TLS 1.2

  3. SQLiteReadOnlyDatabaseException:försök att skriva en skrivskyddad databas (kod 1032)

  4. SQLite infogar inte data i den andra tabellen