5

日付の部分文字列を含むテキスト引数を指定するとDATEを返すユーザー定義関数を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;

エラー:

FUNCTIONlm_date_convertコンパイルされました。1/46
PLS-00103:次のいずれかを予期しているときに、記号「(」が検出されました:

:=。)、@%デフォルト文字続行するには、「(」の代わりに記号「:=」を使用しました。

これについての考え、および一般的なUDF作成のヒント(および優れたリファレンス)は大歓迎です!ありがとう。

4

1 に答える 1

21

ストアドプロシージャでパラメータを指定するときに、データ型を制限することはできません。つまり、VARCHAR2(50)ではなくVARCHAR2を使用します。

私があなたの問題を再現していることを証明するためだけに...

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)の型を宣言し、その型を使用してください。」

サイズ設定を強制するためにSQLTYPEを宣言するのは、少しやり過ぎです。PL / SQLでSUBTYPEを宣言することはできますが、そのサイズは実際にはストアド・プロシージャのシグニチャに適用されません。ただし、この他のスレッドで説明しているように、回避策があります。


余談ですが、なぜこの問題を解決するために正規表現を使用しているのですか?むしろ、TO_CHARとTO_DATEでは解決できない問題を解決しようとしていますか?Oracleはフォーマットマスクにかなり寛容です。

于 2010-08-03T16:46:59.153 に答える