错误在Oracle中编译用户定义的函数PLS-00103

问题描述:

我正尝试在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写作技巧(和好参考)欢迎!谢谢。

在存储过程中指定参数时,我们不能限制数据类型。也就是说,只需使用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