[pgsql-jp: 38437] Re: 文字列が日付として有効かをチェックする SQL

Tamotsu Hasegawa tamotsu @ nippaku.co.jp
2007年 5月 23日 (水) 09:53:49 JST


長谷川@ニッパク です.

やっと試すことができましたので、結果をご報告します。
木村さんにご紹介いただいたストアドプロシージャで希望通りの
動作になりました。
やりたかったことが「ユーザが日付として入力した文字列が、
PostgreSQLの日付として利用できるかを検査したい」という
ことでしたので、「date関数の引数に使ってみてエラーになるかを
調べる」というのはシンプルでバッチリな方法だと思います。
非常に助かりました。ありがとうございました。

また、「OTHERSはQUERY_CANCELED以外の全てのエラーに合致」
ということで、今回の場合はエラーの分類をする必要はありませんので
まったく問題ありません。むしろ、WHEN行が必要ないんじゃないかと
思うくらいです。

#いや、ちゃんとsyntax errorがでましたけど・・・:-)

ちなみに、現状ではPostgreSQL 8.2.4へ移行済みで、8.2.4で
確認しましたが、8.1.2では試せませんでした。

/* 長谷川 保 @ (株)ニッパク */

 On 2007/04/03 0:10:13
 wrote: "KIMURA, Meiji" <kimura804 @ ybb.ne.jp>

> こんばんわ。木村明治@キムラデービーです。
> 
> --- Tamotsu Hasegawa <tamotsu @ nippaku.co.jp> wrote:
> 
> > 長谷川@ニッパク です.
> > 
> > PostgreSQL 8.1.2を利用しています。
> > ある文字列が日付として有効かどうかを調べるSQLを作りたいの
> > ですが、なかなかうまくいきません。
> > 
> > とりあえずキャストしてみたのですが、構文エラーになって
> > しまいます。
> > 
> > postgres=# select date( '20070331' );
> >     date
> > ------------
> >  2007-03-31
> > (1 row)
> > 
> > postgres=# select date( 'hoge' );
> > ERROR:  invalid input syntax for type date: "hoge"
> > postgres=#
> > 
> > エラーではなく結果として正しいかどうかを取得したいので、
> ということであれば、このキャスト自体を手続き型関数として
> CREATE FUNCTIONしてやればいいと思います。PostgreSQL 8.0から
> 例外処理がサポートされたので、キャストして何かエラーが出た
> ときには、FALSEを返すような感じです。
> 
> CREATE LANGUAGE plpgsqlしてから、以下のストアドプロシージャを作成します。
> 
> ->ここから
> CREATE FUNCTION IS_VALIDDATE(yyyymmdd text) RETURNS boolean as 
> $$
> DECLARE
> 	ret boolean;
> 	query text;
> 	validdate date;
> BEGIN
> 	query := 'SELECT date(''' || yyyymmdd || ''')';
> 	EXECUTE query INTO validdate;
> 	return TRUE;
> EXCEPTION
> 	WHEN OTHERS THEN
> 	return FALSE;
> END;
> $$
> LANGUAGE PLpgSQL;
> <-ここまで
> 
> 実行結果はこんな感じです。とりあえず、例外はOTHERSということで、全部つかんでしまっていますが。
> 
> postgres=# select is_validdate('2007-03-31');
>  is_validdate
> --------------
>  t
> (1 row)
> 
> postgres=# select is_validdate('2007.03.31');
>  is_validdate
> --------------
>  t
> (1 row)
> 
> postgres=# select is_validdate('20073h3.31');
>  is_validdate
> --------------
>  f
> (1 row)
> 
> postgres=# select is_validdate('hoge');
>  is_validdate
> --------------
>  f
> (1 row)
> 
> postgres=# select is_validdate('20070230');
>  is_validdate
> --------------
>  f
> (1 row)
> 
> postgres=# select is_validdate(' 20070331');
>  is_validdate
> --------------
>  t
> (1 row)
> 
> > 古いバージョンのPostgreSQLに対応する必要はありませんが、そもそも
> > やり方がスマートではない気がしますし、できれば日付型へのキャストが
> > 成功するパターンについて網羅したいのですが、良いアイデアはありませ
> > んか?
> > ご助言をお願いします。
> 
> とりあえずは、これで動作しているような感じなのですが、いかがですか?
> PostgreSQL 8.2.3 Windows版で確認しました。
> 
> See.
> http://www.postgresql.jp/document/pg823doc/html/plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING
> 
> 
> 
> --
> キムラデービー代表 木村明治(KIMURA, Meiji)
> http://kimuradb.com
> [News] 2007年1月よりDB・開発の低額&定額ミニコンサルやってます!
> http://kimuradb.com/miniconsul.html




pgsql-jp メーリングリストの案内