[pgsql-jp: 26752] Error occurred while executing PL/pgSQL function
electricnude @ geocities.co.jp
electricnude @ geocities.co.jp
2002年 7月 18日 (木) 19:41:11 JST
はじめまして。池村と申します。いつもROMさせて頂いておりました。
pl/pgsql関数についてですが、PostgreSQLバージョンアップ後、
動作しない状況に陥りました。
何とか打破したく、皆様のお知恵を拝借させて頂きたく存じます。
長文になりますこと、お許しくださいませ。
サーバ環境:
Operating System ..... Red Hat Linux release 7.2 (Enigma)
Architecture ......... Intel Pentium III
PostgreSQL version ... 7.1.3 ==>> 7.2.1
Compiler used ........ 2.96
PostgreSQLは、Ver7.1.3、Ver7.2.1いずれも、
tarballからのインストールです。
問題の関数は、3つからなるものなのですが、
書き方に問題があるのか、ハタマタ別の問題なのか、
私なりに調べたのですが、原因を突き止められずにおります。
最下段にその関数群を記します。
(各関数群の先頭4文字の空白は、説明用にインデントしたものです。)
3番目の関数[ arwz_ext_down2day ]を動作させると、以下のような現象が起きます。
=== お題 ==> 今日の(月の)、第3日曜日の日付を求めたい。
a) Ver7.1.3の場合
# SELECT arwz_ext_down2day( date( now() ) , '3:sun' ) ;
arwz_ext_down2day
------------------------
2002-07-21 00:00:00+09
(1 row)
>>> 正常に意図したreturn値が取得できる。
b) Ver7.2.1の場合
# SELECT arwz_ext_down2day( date( now() ) , '3:sun' ) ;
NOTICE: Error occurred while executing PL/pgSQL function arwz_ext_down2day
NOTICE: line 25 at assignment
ERROR: parser: parse error at or near "("
>>> 正常に動作せず。文法エラーとも言われる・・・
Googleで、[ Error occurred while executing PL/pgSQL function ]をサーチすると、
こんなのが出ましたが、状況は異なる様に思えるのですが・・・
cf: [ http://archives.postgresql.org/pgsql-bugs/2002-05/msg00160.php ]
やはり、私が記述した関数の書式がイイカゲンなのでしょうか?
どなたかご存知の方、よろしくご教授ください。お願いいたします。
あぁぁ、英語力も無い私に 愛 を く だ さ い 。
>>>>> 以下、問題の関数群 <<<<<
1. 該当月の最終日を算出する(つもりの)関数
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CREATE OR REPLACE FUNCTION arwz_rtn_enddayofmonth( TIMESTAMP )
RETURNS INT4 AS '
DECLARE
my_input_date TIMESTAMP ;
my_temp_value VARCHAR ;
my_down_separator_pos INT4 ;
my_value_year INT4 ;
my_value_month INT4 ;
my_return_value INT4 ;
BEGIN
my_input_date := $1 ;
my_temp_value := to_char( my_input_date , ''YYYY-MM'' ) ;
my_down_separator_pos = strpos( my_temp_value , ''-'' ) ;
my_value_year := ( substr( my_temp_value , 1 , ( my_down_separator_pos - 1 ) ) )::INT4 ;
my_value_month := ( substr( my_temp_value , ( my_down_separator_pos + 1 ) ) )::INT4 ;
IF my_value_month = 2 THEN
IF ( my_value_year % 400 ) = 0 THEN
my_return_value := 29 ;
ELSE
IF ( my_value_year % 100 ) = 0 THEN
my_return_value := 28 ;
ELSE
IF ( my_value_year % 4 ) = 0 THEN
my_return_value := 29 ;
ELSE
my_return_value := 28 ;
END IF ;
END IF ;
END IF ;
ELSE
my_return_value := CASE my_value_month
WHEN 1 THEN 31
WHEN 3 THEN 31
WHEN 4 THEN 30
WHEN 5 THEN 31
WHEN 6 THEN 30
WHEN 7 THEN 31
WHEN 8 THEN 31
WHEN 9 THEN 30
WHEN 10 THEN 31
WHEN 11 THEN 30
WHEN 12 THEN 31
END ;
END IF ;
RETURN my_return_value ;
END ;'
LANGUAGE 'plpgsql' ;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2. 曜日 <--> 数値変換(のつもりの)関数
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CREATE OR REPLACE FUNCTION arwz_exp_dow2num( VARCHAR )
-- return ... input
-- 1 ... sun
-- 2 ... mon
-- 3 ... tue
-- 4 ... wed
-- 5 ... thu
-- 6 ... fri
-- 7 ... sat
-- 0 ... n/a
--
RETURNS INT4 AS '
DECLARE
my_input_value ALIAS FOR $1 ;
my_short_dow VARCHAR ;
my_return_value INT4 ;
BEGIN
my_short_dow := LOWER( SUBSTRING( my_input_value FROM 1 FOR 3 ) ) ;
my_return_value := CASE my_short_dow
WHEN ''sun'' THEN 1
WHEN ''mon'' THEN 2
WHEN ''tue'' THEN 3
WHEN ''wed'' THEN 4
WHEN ''thu'' THEN 5
WHEN ''fri'' THEN 6
WHEN ''sat'' THEN 7
ELSE 0
END ;
RETURN my_return_value ;
END ;'
LANGUAGE 'plpgsql' ;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
3. 外当月の第n m曜日を算出する(つもりの)関数
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CREATE OR REPLACE FUNCTION arwz_ext_down2day( TIMESTAMP , VARCHAR )
-- ----------------------------------------------------------------------------------
-- ----------------------------------------------------------------------------------
-- NAME:
-- down : Day Of the Week ( and week Number )
--
-- SYNOPSIS
-- this.function( '2002-02-02' , '3:sun' )
--
-- DESCRIPTION
-- this.function( timestamp , varchar )
-- $1 : timestamp ... target date( which use only year and month ).
-- $2 : varchar ..... certain format as [ weeknumber each month + separator < : > + <the day of the week> ]
-- examples::'3:sun' <<== it means 3rd sunday of the weeks in that month.
--
-- AUTHOR NOTE
-- -----
-- -----
--
-- ----------------------------------------------------------------------------------
-- ----------------------------------------------------------------------------------
RETURNS TIMESTAMP AS '
DECLARE
my_input_date TIMESTAMP ;
my_input_down VARCHAR ;
my_return_value TIMESTAMP ;
my_date_bad_request TIMESTAMP ;
my_date_diff_day INT4 ;
my_date_bom TIMESTAMP ; -- Beginning Of Month
my_date_diff_dow INT4 ;
my_down_separator_pos INT4 ;
my_down_week INT4 ;
my_down_dow VARCHAR ;
my_temp_timestamp TIMESTAMP ;
my_temp_varchar VARCHAR ;
my_temp_intger INT4 ;
-- ret TIMESTAMP ;
BEGIN
-- ----------------------------------------------------------------------------------
-- -- SET::initialize parameters value
my_input_date := $1 ;
my_input_down := trim( $2 ) ;
-- ----------------------------------------------------------------------------------
-- -- CHK::input values
IF ISFINITE( my_input_date ) = ''false''
THEN
RAISE EXCEPTION ''Invalid Argument $1[ % ] >> unjust timestamp'' , $1 ;
END IF ;
-- IF my_input_down !~ ''^[1-5]\:[A-Za-z]\{3\}$''
IF my_input_down !~ ''^[0-9]*\:[A-Za-z]*$''
THEN
RAISE EXCEPTION ''Invalid Argument $2[ % ] SYNOPSIS::''''3:sun'''''' , $2 ;
END IF ;
-- ----------------------------------------------------------------------------------
-- -- ALYZ::date
my_temp_varchar := to_char( timestamp ( ( my_input_date )::varchar ) , ''YYYY-MM-DD'' ) ;
my_temp_timestamp := to_timestamp( my_temp_varchar , ''YYYY-MM-DD'' ) ;
my_date_diff_day := ( EXTRACT( DAY FROM my_temp_timestamp ) - 1 )::INT4 ;
my_date_bom := DATE( my_temp_timestamp ) - my_date_diff_day ;
my_date_diff_dow := arwz_exp_dow2num( to_char( my_date_bom , ''dy'' ) ) ;
-- ----------------------------------------------------------------------------------
-- -- ALYZ::down
my_down_separator_pos = strpos( my_input_down , '':'' ) ;
my_down_week := ( substr( my_input_down , 1 , ( my_down_separator_pos - 1 ) ) )::INT4 - 1 ;
my_down_dow := substr( my_input_down , ( my_down_separator_pos + 1 ) ) ;
my_temp_intger := arwz_exp_dow2num( my_down_dow ) ;
IF my_temp_intger = 0
THEN
RAISE EXCEPTION ''Invalid Argument $2[ % ] >> no exist day of the week like ''''%'''''' , $2 , my_down_dow ;
END IF ;
my_temp_intger := 1 + my_temp_intger - my_date_diff_dow ;
IF my_temp_intger <= 0
THEN
my_temp_intger := my_temp_intger + 7 ;
END IF ;
my_temp_intger := my_temp_intger + my_down_week * 7 ;
IF my_temp_intger > arwz_rtn_enddayofmonth( my_temp_timestamp ) THEN
RAISE EXCEPTION ''Invalid Argument $2[ % ] >> no exist day in the month such as day of the week'' , $2 ;
END IF ;
RETURN to_timestamp( ( substr( my_temp_varchar , 1 , 8 ) || ( my_temp_intger )::VARCHAR || substr( my_temp_varchar , 11 ) ) , ''YYYY-MM-DD'' ) ;
END ;'
LANGUAGE 'plpgsql' ;
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
EOM
pgsql-jp メーリングリストの案内