2010-08-03 243 views
3

我正嘗試在Oracle中創建一個用戶定義的函數,該函數在給定包含日期子字符串的文本參數時將返回一個DATE。我試着寫這個的幾種方法,並且似乎都拋出了同樣的錯誤:錯誤在Oracle中編譯用戶定義的函數PLS-00103

CREATE OR REPLACE FUNCTION lm_date_convert (lm_date_in IN VARCHAR2(50)) 
    RETURN DATE DETERMINISTIC IS 
BEGIN 
    RETURN(TO_DATE(REGEXP_REPLACE(lm_date_in, '([[:digit:]]{2})[-/.]*([[:digit:]]{2})[-/.]*([[:digit:]]{4})','\3-\1-\2'), 'YYYY-MM-DD')); 
END; 

錯誤:

FUNCTION lm_date_convert Compiled. 1/46
PLS-00103: Encountered the symbol "(" when expecting one of the following:

:= .) , @ % default character The symbol ":=" was substituted for "(" to continue.

任何對此的思考,和一般的UDF寫作技巧(和好參考)歡迎!謝謝。

回答

12

在存儲過程中指定參數時,我們不能限制數據類型。也就是說,只需使用VARCHAR2而不是VARCHAR2(50)。

只是爲了證明我複製你的問題......

SQL> CREATE OR REPLACE FUNCTION lm_date_convert (lm_date_in IN VARCHAR2(50)) 
    2 RETURN DATE DETERMINISTIC IS 
    3 BEGIN 
    4 RETURN(TO_DATE(REGEXP_REPLACE(lm_date_in, '([[:digit:]]{2})[-/.]*([[:digit:]]{2})[-/.]*([[:digit:]]{4})','\3-\1-\2'), 'YYYY-MM-DD')); 
    5 END; 
    6/

Warning: Function created with compilation errors. 

SQL> sho err 
Errors for FUNCTION LM_DATE_CONVERT: 

LINE/COL ERROR 
-------- ----------------------------------------------------------------- 
1/49  PLS-00103: Encountered the symbol "(" when expecting one of the 
     following: 
     := .) , @ % default character 
     The symbol ":=" was substituted for "(" to continue. 

SQL> 

我們解決這個問題:

SQL> ed 
Wrote file afiedt.buf 

    1 CREATE OR REPLACE FUNCTION lm_date_convert (lm_date_in IN VARCHAR2) 
    2 RETURN DATE DETERMINISTIC IS 
    3 BEGIN 
    4 RETURN(TO_DATE(REGEXP_REPLACE(lm_date_in, '([[:digit:]]{2})[-/.]*([[:digit:]]{2})[-/.]*([[:digit:]]{4})','\3-\1-\2'), 'YYYY-MM-DD')); 
    5* END; 
SQL> r 
    1 CREATE OR REPLACE FUNCTION lm_date_convert (lm_date_in IN VARCHAR2) 
    2 RETURN DATE DETERMINISTIC IS 
    3 BEGIN 
    4 RETURN(TO_DATE(REGEXP_REPLACE(lm_date_in, '([[:digit:]]{2})[-/.]*([[:digit:]]{2})[-/.]*([[:digit:]]{4})','\3-\1-\2'), 'YYYY-MM-DD')); 
    5* END; 

Function created. 

SQL> 

"If you really do want a VARCHAR2(50) then declare a type of VARCHAR2(50) and use the type."

聲明一個SQL TYPE執行尺寸是一點點矯枉過正。我們可以在PL/SQL中聲明SUBTYPE,但是它們的大小實際上並未在存儲過程簽名中實施。但是有一些解決方法,如I discuss in this other thread


另外,爲什麼你使用正則表達式來解決這個問題?或者說,您嘗試解決哪些問題,TO_CHAR和TO_DATE無法解決? Oracle對格式掩碼非常寬容。

+0

感謝您的解決方案 - 我希望它會是這樣的。 我有不同形式的字符串,比如'2010-08-03 00:00:00.0',我需要處理成日期對象。我想我可以使用 'TO_DATE(SUBSTR('2010-08-03 00:00:00.0',1,10),'YYYY-MM-DD')' 我應該這樣做而不是使用Regex?什麼時候使用或避免正則表達式的指針,爲什麼? 感謝您的幫助! – Stew 2010-08-03 17:23:51

+0

如果你真的想要一個VARCHAR2(50),那麼聲明一個VARCHAR2(50)類型並使用該類型。 – darreljnz 2010-08-03 19:52:08

相關問題