2011-06-04 67 views
1

我想工作能夠執行我下面PROC像這樣:PL/SQL - TO_DATE不執行即時參數

exec procname('29-JAN-2011'); 

PROC代碼:

PROCEDURE procname(pardate VARCHAR2) IS 

    vardate DATE := to_date(pardate, 'DD-MON-YYYY'); 
    SQLS VARCHAR2(4000); 

BEGIN  

    SQLS := 'SELECT cola, colb 
      FROM tablea 
      WHERE TRUNC(coldate) = TRUNC(TO_DATE('''||pardate||''',''DD/MON/YYYY''))'; 

    EXECUTE IMMEDIATE SQLS; 

END; 

它不斷拋出的錯誤:

ORA-00904: "JAN": invalid identifier.

它編譯,但是當我運行此命令時,它拋出的錯誤:

EXEC procname('29-JAN-2011'); 
+0

在哪一行? – GolezTrol 2011-06-04 02:21:37

+0

這不是實際的代碼,對吧?它不會編譯。 – GolezTrol 2011-06-04 02:23:00

+0

任何想法的人? – poots 2011-06-04 02:29:01

回答

6

您聲明瞭一個變量,它將輸入參數轉換爲日期:爲什麼不使用它?

此外,應用於日期的TRUNC()刪除時間元素。你不需要這裏,因爲你傳遞的價值沒有時間。

所以,你的代碼應該是:

PROCEDURE procname(pardate VARCHAR2) IS 

    vardate DATE := to_date(pardate, 'DD-MON-YYYY'); 
    SQLS VARCHAR2(4000) := 'select cola, colb FROM tablea 
      WHERE TRUNC(coldate) = :1'; 

    l_a tablea.cola%type; 
    l_b tablea.colb%type; 
BEGIN  
    EXECUTE IMMEDIATE SQLS 
     into l_a, l_b 
     using vardate; 
END; 

指定用綁定變量的動態SQL語句,與使用語法執行它是很多更有效。請注意,我們仍然必須將SELECT選入一些變量。

+1

作爲一個方面說明,trunc()可以避免使用索引而不是冷凝。他可以考慮使用vardate,vardate這個技巧「......在1:和2 + 0.99999之間冷卻」。 – Samuel 2011-06-04 07:57:08

1

在兩個調用to_date中使用了兩種不同的表示法。我認爲其中的一個(第二個)是錯誤的。

+0

請提供正確的語法,因爲邏輯是正確的。 – poots 2011-06-04 02:46:49

+0

我的意思是,其中一個是DD-MON-YYYY,另一個是DD/MON/YYYY。輸入使用破折號,而不是斜槓,所以我認爲第二個是錯誤的。 – GolezTrol 2011-06-04 02:49:14

+0

也可能是語言設置問題。你住在一月沒有縮短到JAN的國家嗎? – GolezTrol 2011-06-04 02:50:30