在Oracle中编译用户定义函数时出错PLS-00103

在Oracle中编译用户定义函数时出错PLS-00103,oracle,function,plsql,user-defined-functions,pls-00103,Oracle,Function,Plsql,User Defined Functions,Pls 00103,我试图在Oracle中创建一个用户定义的函数,当给定一个包含日期子字符串的文本参数时,该函数将返回一个日期。我试过几种写这篇文章的方法,但似乎都犯了同样的错误: 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}

我试图在Oracle中创建一个用户定义的函数,当给定一个包含日期子字符串的文本参数时,该函数将返回一个日期。我试过几种写这篇文章的方法,但似乎都犯了同样的错误:

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:遇到 符号“(”应为 以下是:

:=),@%默认字符 符号“:”被替换为“(”至 继续


欢迎对此有任何想法和一般的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> 


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

声明SQL类型以强制调整大小有点过分。我们可以在PL/SQL中声明子类型,但它们的大小实际上不会在存储过程签名中强制执行。不过,也有一些变通方法



顺便说一句,你为什么要用正则表达式来解决这个问题?或者更确切地说,你想解决的问题是什么?用to_CHAR和to_DATE无法解决?Oracle对格式掩码非常宽容。

谢谢你的解决方案——我希望它是这样的。我有不同形式的字符串,比如我喜欢的“2010-08-03 00:00:00.0”需要处理成日期对象。我想我可以使用
来确定日期(SUBSTR('2010-08-03 00:00:00.0',1,10),'YYYY-MM-DD')
我应该这样做而不是使用Regex吗?关于何时使用或避免使用Regex的任何指针,以及为什么?谢谢你的帮助!如果你真的想要VARCHAR2(50),那么声明一种VARCHAR2(50)类型并使用该类型。