[pgsql-jp: 33455] Re: RULEにおけるNEW について

Jun Kitamura kitamura @ zoozee.jp
2004年 7月 1日 (木) 16:23:43 JST


北村です。

> そこでこんなRULEを作ってみました。
> CREATE RULE setNickname AS ON INSERT TO members
>      DO UPDATE members SET nickname =
>      CASE
>         WHEN NEW.nickname IS NULL THEN
>            NEW.name
>         ELSE
>            NEW.nickname
>      END
>      WHERE code = NEW.code;         --今INSERTされたレコードを検索しているつもり。
> 
> しかし、最後のWHERE句がまずいようで、やりたいことが実現できません。
> 代わりに"WHERE nickname IS NULL" にしてやると思った通りのUPDATEが実行されますが、
> これではちょっと乱暴な気がします。
> 上記のWHERE句のどこがいけないのでしょうか?

code が シーケンス(serial型)であることが原因です。
NEW.code は、ルールシステムによって置き換えられ(たぶん内部で 
SELECT されて)ます。

まったく新規の場合(つまり次の code は 1)、INSERT 時のデフォ
ルト値としての(serial型としての) nextval() (=1)が呼ばれます。
このとき、ルール内に書かれた NEW.code は同様に nextval() が
呼ばれ、値としては 2 となります。「where code = 2」となり今
しがた INSERT した行(code = 1)と条件に合わないので、アップデー
トされません。(たぶん、もう一度同じ INSERT文を実行すると、
code が 3 になると思います。これは、2回 nextval() が呼ばれて
いる事を意味します)。

serial型をやめるか、ルールではなくトリガにすれば問題は解決で
す。

でわ。

# 4年程前に同じところ(serial型+ルール)でハマって初投稿したの
# が懐かしい(笑




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