Ошибка PLS-00103 при компиляции пользовательской функции в Oracle
Я пытаюсь создать пользовательскую функцию в 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: Обнаружен символ "(" при ожидании одного из следующего:знак равно), @ % символ по умолчанию Символ ":=" был заменен на "(" для продолжения.
Любые мысли по этому поводу, а также общие советы по написанию UDF (и хорошие ссылки) приветствуются! Благодарю.
1 ответ
Мы не можем ограничить тип данных при указании параметров в хранимых процедурах. То есть просто используйте 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 для принудительного определения размеров - это немного излишне. Мы можем объявить SUBTYPE в PL/SQL, но их размеры фактически не применяются в сигнатурах хранимых процедур. Однако есть обходные пути, которые я обсуждаю в этой другой теме.
Кроме того, почему вы используете Regex для решения этой проблемы? Или, скорее, какую проблему вы пытаетесь решить, которая не может быть решена с помощью TO_CHAR и TO_DATE? Оракул довольно простителен с форматными масками.