[pgsql-jp: 34626] FORのネストとEXECUTE
CM
illuminate33 @ hotmail.com
2005年 1月 12日 (水) 22:32:04 JST
またもやplpgsqlストアドで詰まっています。
Windows 2000 Server の Postgresql-7.2.1でcygwin-1.3.12-4です。
顧客情報のテーブルccallinoneuから、適宜期間をエンドユーザーに
入力させて数値項目を集計し、自動的にsumminguptテーブルに
集積する形にしたいのですが、無理でしょうか?
テーブルgstattableにupdate, insertトリガでstat_contentファンクションを
呼び出す仕組みなのですが・・・・。
Table "ccallinoneu"はこんな感じです。(集積された顧客デー
タがすでに入っています。)
Column | Type | Modifiers
-------------------------+-------------------+-----------
receipt_no | integer | not null
reception_date | date | not null
technologicalmethod | integer | default 0
commission | integer | default 0
department | integer | default 0
<snip> 他にも列はありますが、今回のストアドには関係ない項目です。
departmentは部署、technologicalmethodは顧客情報の入ってきた経路、commission
は問い合わせの内容です。
Primary key: ccallinoneu_pkeyで、主キーはreceipt_noとreception_dateの二列で
す。
集計結果を出すテーブルは、
配列は認識してくれないJDBCアプリケーションを使用し、
内部的にストアドを張らざるを得ない仕組みになっているのですが、
(それに、配列は難しいんでまだ使ったことないんです。)
c_c_sheet_a=# \d summingupt
Table "summingupt"
Column | Type | Modifiers
----------+---------+-----------
code | integer | not null
dep1_1 | integer |
dep2_1 | integer |
dep3_1 | integer |
dep4_1 | integer |
dep5_1 | integer |
dep6_1 | integer |
dep7_1 | integer |
dep8_1 | integer |
<snip>という感じで、dep1_1からdep13_1、dep1_2からdep13_2、・・・・・・
dep13_12というふうに13*12=156の集計結果を記録するセルがあります。
Primary key: summingupt_pkey
(主キーはcodeのみです。単一行にする必要はないのかもしれませんが・・・・
・。)
トリガ、stat_content_tをかけるテーブルは以下のとおり。
集計期間に応じて、変更がかけられるようにしたいんですが・・・。
c_c_sheet_a=# \d gstattable;
Table "gstattable"
Column | Type | Modifiers
------------------+---------+-----------
queryfirstdate | date |
querylastdate | date |
commissionpraise | integer |
code | integer | not null
Primary key: gstattable_pkey
commissionpraiseは問い合わせの内容が特定のコードであった場合、別枠で問い合わ
せる仕組みにするために入力させる数です。
CREATE TABLE gstattable (code integer, queryfirstdate date, querylastdate
date, commissionpraise integer, PRIMARY KEY (code));
関数は物理的に顧客情報が紙に印刷できるような二次元的な集計結果をsumminguptに
出せるようにするもので、
i=columnで表の行、j=rowで表の列がFOR文のネストで出てくる仕組みにしたいのです
が・・・・。
dep*_*のアステリスクがそれぞれ行列番号が入るようになっています。
一番下側と右側の二番目に総計と、昨年の比較集計が表示されるように、したのです
が・・・・。
CREATE OR REPLACE FUNCTION stat_content ()
RETURNS opaque AS '
DECLARE
column integer;
row integer;
result integer;
i integer;
j integer;
k integer;
BEGIN
column:=12;
row:=13;
DELETE FROM summingupt WHERE code=2;
FOR j IN 1..13 LOOP
FOR i IN 1..12 LOOP
IF (i%2=0) THEN
k:=i/2;
ELSIF (i%2=1) THEN
k:=(i+1)/2;
END IF;
SELECT COUNT(*) INTO result FROM ccallinoneu
WHERE CASE WHEN (j<=10) THEN (j=ccallinoneu.department)
WHEN (j=11) THEN (ccallinoneu.department>=11 OR
ccallinoneu.department=0)
ELSE TRUE END
AND CASE WHEN (k<=4) THEN (k=ccallinoneu.technologicalmethod)
WHEN (k=5) THEN (ccallinoneu.technologicalmethod>=5 OR
ccallinoneu.technologicalmethod=0)
ELSE TRUE END
AND CASE WHEN (j<>13) THEN
(NEW.queryfirstdate<=ccallinoneu.reception_date
AND NEW.querylastdate>=ccallinoneu.reception_date)
WHEN (j=13) THEN ((NEW.queryfirstdate-INTERVAL ''1 year'')
<=ccallinoneu.reception_date
AND (NEW.querylastdate-INTERVAL ''1 year'')
>=ccallinoneu.reception_date) END
AND CASE WHEN (i%2=0) THEN (ccallinoneu.commission=NEW.commissionpraise)
ELSE TRUE END;
EXECUTE ''UPDATE summingupt SET (dep''||i||''_''||j||'')=result WHERE
code=2'';
END LOOP;
END LOOP;
RETURN NEW;
END; 'LANGUAGE 'plpgsql';
CREATE TRIGGER stat_content_t AFTER INSERT OR UPDATE
ON gstattable FOR EACH ROW
EXECUTE PROCEDURE stat_content();
どうしても22行目のLOOPの近くにおかしいところがあるよ、でERRORが出てしまいま
す。(素人の疑問なのですが、この行数ってどこから出てくるんでしょうか?
pg_procのprosrcで見てもよくわからないし。;(セミコロン)の位置か、それとも単
純に改行コードの位置なんでしょうか?)
動的問い合わせがまずいのか、SELECT INTOの使い方がまずいのか、いろいろやって
みましたが、
どうしてもうまくいきません。
どなたかお時間があれば、お知恵を拝借できないでしょうか?(やっぱり初心者がこ
こまでplpgsqlで作るのは無謀だったか・・・・。)
CM
PS:全然関係ないですが、自宅のXP Homeに8.0.0を入れました。cygwinで難しくやっ
てたときのことを思えば感無量です。(仕事では相変わらずcygwinですが。)
でもなぜか、cygwinのbinディレクトリに通したシステム環境変数のPATHをつけてい
るとインストール時に警告が出てしまいます?
pgsql-jp メーリングリストの案内