Ошибка PLS-00103 при компиляции пользовательской функции в Oracle - PullRequest
5 голосов
/ 03 августа 2010

Я пытаюсь создать пользовательскую функцию в 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;

ошибка:

FUNCTION lm_date_convert Скомпилировано. 1/46
PLS-00103: Обнаружено символ "(" при ожидании одного из следующее:

: =. ), символ @% по умолчанию символ ": =" был заменен на "(" для продолжить.

Любые мысли по этому поводу, а также общие советы по написанию UDF (и хорошие ссылки) приветствуются! Спасибо.

1 Ответ

14 голосов
/ 03 августа 2010

Мы не можем ограничить тип данных при указании параметров в хранимых процедурах.То есть, просто используйте 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 длянавязывание размеров - это немного излишне.Мы можем объявить SUBTYPE в PL / SQL, но их размеры фактически не применяются в сигнатурах хранимых процедур.Однако есть обходные пути, поскольку я обсуждаю в этой другой теме .


Кроме того, почему вы используете Regex для решения этой проблемы?Или, скорее, какую проблему вы пытаетесь решить, которая не может быть решена с помощью TO_CHAR и TO_DATE?Оракул довольно простителен с форматными масками.

...