2011年4月18日

[pgsql-jp: 40740] Re:トリガーファンクション?で実現可能でしょうか?

佐藤です。

From: yukihito miso <oira3ryu@xxxxx>
Date: Mon, 18 Apr 2011 21:36:30 +0900

> トリガーファンクション?というのでしょうか?
>
> id sec col cat

> -------------------
> 1 1 1c 1
> 2 2 2c 1
> 3 1 4c 11
> 4 2 8c 11
> 5 3 12c 11
>
> 上記のテーブルでcatが11の場合
>
> イメージですが
> merge_col := 1c, 2c, 3c
> ということをしたい。

上記の説明ではよく分からないのですが、cat 列の値が 11 の行の col 列の
値をカンマ区切りで連結した文字列を取得したいということでしょうか。

だとしたら、トリガはテーブルの更新をきっかけに関数を実行する仕組みなの
で、トリガではなく SELECT で実現できます。

=> TABLE tablea;
id | sec | col | cat
----+-----+-----+-----
1 | 1 | 1c | 1
2 | 2 | 2c | 1
3 | 1 | 4c | 11
4 | 2 | 8c | 11
5 | 3 | 12c | 11
(5 rows)

=> SELECT array_to_string(array_agg(col), ', ') AS merge_col
-> FROM tablea WHERE cat = '11';
merge_col
-------------
4c, 8c, 12c
(1 row)

ちなみに、

> ためしに、
>
> CREATE OR REPLACE FUNCTION merge_col()
> RETURNS trigger AS
> $BODY$
> DECLARE
> cnt int;
> BEGIN
> PERFORM COUNT(col) AS cnt FROM tableA WHERE cat = NEW.cat;
>
> FOR i IN 1..cnt LOOP
> SELECT col FROM tableA WHERE sec = i AND cat = NEW.cat;
> NEW.merge_col := col;
> RETURN NEW;
> END LOOP;
> NEW.merge_col := merge_col;
> RETURN NEW;
>
> END;
> $BODY$
> LANGUAGE plpgsql VOLATILE
> COST 100;
> ALTER FUNCTION merge_col() OWNER TO yu2admin;
>
> としてみましたが
> 「upper bound FOR of loop cannot be null」
> というエラーが出てしまいます。

これは、FOR ループの上限に指定している変数 cnt が NULL なのでエラーに
なっています。

PERFOM で変数 cnt に tablea の行数を代入しようとしているんだと思います
が、PERFORM は実行結果が不要で破棄してもいい場合に使用するコマンドです。
実行結果を変数に代入したいなら SELECT INTO を使用する必要があります。

SELECT count(col) INTO cnt FROM tablea WHERE cat = NEW.cat;


----
Tomoaki Sato <sato@xxxxx>
SRA OSS, Inc. Japan


投稿者 xml-rpc : 2011年4月18日 22:27
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/103087
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。