0

私は単純なテーブルを持っています:

CREATE TABLE aaa_has_bbb (
    aaa_id integer not null,
    bbb_id integer not null,
    rank  integer not null,

    primary key(aaa_id, bbb_id),
    uniq(aaa_id, rank)
)

関連するトリガーがアクティブになるため、DELETE と INSERT を行うルールを作成しようとしています。

CREATE OR REPLACE RULE pivot_key_updates AS
ON UPDATE TO aaa_has_bbb
WHERE OLD.aaa_id<>NEW.aaa_id OR OLD.bbb_id<>NEW.bbb_id
DO INSTEAD (
    --
    -- on update of keys in this pivot table, delete and insert instead
    --
    DELETE FROM aaa_has_bbb WHERE aaa_id = OLD.aaa_id 
      AND bbb_id = OLD.bbb_id;

    INSERT INTO aaa_has_bbb (aaa_id, bbb_id, rank)
    VALUES (NEW.aaa_id, NEW.bbb_id, NEW.rank);

);

これは決して挿入されませんが、正常に削除されます。

ただし、次のように順序を逆にすると:

CREATE OR REPLACE RULE pivot_key_updates AS
ON UPDATE TO aaa_has_bbb
WHERE OLD.aaa_id<>NEW.aaa_id OR OLD.bbb_id<>NEW.bbb_id
DO INSTEAD (
    --
    -- on update of keys in this pivot table, delete and insert instead
    --

    INSERT INTO aaa_has_bbb (aaa_id, bbb_id, rank)
    VALUES (NEW.aaa_id, NEW.bbb_id, NEW.rank+1);

    DELETE FROM aaa_has_bbb WHERE aaa_id = OLD.aaa_id 
      AND bbb_id = OLD.bbb_id;

);

順序の切り替えは機能しますか?なんで?

これを正しく機能させるには、キーの衝突を避けるためにランク + 1 する必要がありますが、実際にはそうしたくありません。

私は何が欠けていますか?

編集: トリガーを使用して生活を楽にすることができることに気づきました。おそらくそれが最終的にやることになるでしょうが、なぜ私のルールが期待どおりに機能しないのか非常に興味があります.

4

3 に答える 3

0

http://www.postgresql.org/docs/9.2/static/rules-update.htmlを見てください。特に「2 つの最終的なクエリ ツリーで終わる」で始まる例を見てください。

元の WHERE ステートメントの一部が、作成したステートメントに追加されるという点で、ルールはトリガーとは異なるように思えます。rules-triggers.html の例は同じことを言っているようです。

単一の行で処理したい場合は、代わりに「トリガー」を使用できます: http://www.postgresql.org/docs/9.2/static/sql-createtrigger.html

于 2013-06-05T01:27:55.370 に答える