在存储过程中指定参数时,我们不能限制数据类型。也就是说,只需使用 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,但它们的大小实际上并未在存储过程签名中强制执行。但是,正如我在另一个线程中讨论的那样,有一些解决方法。
顺便说一句,您为什么要使用正则表达式来解决这个问题?或者更确切地说,您要解决哪些问题无法用 TO_CHAR 和 TO_DATE 解决?Oracle 对格式掩码非常宽容。