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

时间:2010-08-03 16:32:28

标签: oracle function plsql user-defined-functions pls-00103

我正在尝试在Oracle中创建一个用户定义的函数,当给定包含日期子字符串的文本参数时,该函数将返回DATE。我已经尝试了几种方法来写这个,所有似乎都抛出同样的错误:

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;

错误:

  

功能lm_date_convert已编译。 1/46
  PLS-00103:遇到了   符号“(”当期待其中一个时   以下内容:

     

:=。 ),@%默认字符   符号“:=”代替“(”to   继续。

欢迎任何有关此问题的想法,以及一般的UDF写作技巧(以及好的参考资料)!感谢。

1 个答案:

答案 0 :(得分:14)

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

  

“如果你真的想要一个VARCHAR2(50)   然后声明一个VARCHAR2类型(50)   并使用类型。“

声明SQL TYPE以强制执行大小调整有点过分。我们可以在PL / SQL中声明SUBTYPE,但它们的大小实际上并未在存储过程签名中强制执行。但是有一些解决方法I discuss in this other thread


顺便说一句,为什么使用正则表达式解决这个问题?或者更确切地说,您尝试解决的问题是TO_CHAR和TO_DATE无法解决的问题? Oracle对格式掩码非常宽容。