Re: Implementation of a bag pattern using rules
От | Tom Lane |
---|---|
Тема | Re: Implementation of a bag pattern using rules |
Дата | |
Msg-id | 20111.1076342974@sss.pgh.pa.us обсуждение исходный текст |
Ответ на | Implementation of a bag pattern using rules (Mark Gibson <gibsonm@cromwell.co.uk>) |
Ответы |
Re: Implementation of a bag pattern using rules
|
Список | pgsql-sql |
Mark Gibson <gibsonm@cromwell.co.uk> writes: > Alternatively, for the relative option (increase 'apple' by 12), replace > the 'bag_abs' rule with: > CREATE RULE bag_rel AS ON INSERT TO bag_test > WHERE > EXISTS (SELECT 1 FROM bag_test WHERE item = NEW.item) > DO INSTEAD > UPDATE bag_test SET qty = qty + NEW.qty WHERE item = NEW.item; This can't work because an ON INSERT rule fires after the INSERT itself is executed. You have the equivalent of INSERT INTO ... WHERE NOT EXISTS(SELECT ...); UPDATE ... WHERE item = NEW.item AND EXISTS(SELECT ...); The INSERT will execute because there's no row matching the EXISTS(), and then the UPDATE will execute too because now there is a matching row. In some contexts this is a feature. However, you want a single test to control both actions. I think you need to use a BEFORE INSERT trigger instead. It could do something like -- see if there is an existing row, if so update itUPDATE bag_test SET qty = qty + NEW.qty WHERE item = NEW.item;-- if therewas one, suppress the INSERTIF found THEN RETURN NULL;END IF;-- else allow the INSERTRETURN NEW; You could also extend the trigger to handle the delete-upon-reaching-zero logic. regards, tom lane
В списке pgsql-sql по дате отправления: