patternsqlMinor
Delete rule on view does not execute every statement
Viewed 0 times
deleterulestatementeveryviewdoesnotexecute
Problem
When I have more than one statements in a rule on a view, the second one is not executed in case the first one deletes the original entry. Even when the second statement does not have anything to do with the original entry at all.
Here is a simple example. Tables are
And there is a view on reach called
And on this view is a rule, deleting the reach and the referenced rp:
When we delete now an entry from the
The entry with id 2 from
When I have the same rule on the table with
So according the response here https://stackoverflow.com/questions/5534927/how-to-write-a-delete-rule-on-a-view the second statement is not executed becau
Here is a simple example. Tables are
reach and rp (reachpoint) and in reach we have an id that can be referenced to rp.CREATE TABLE test_delete_rule.reach
(
id integer NOT NULL,
rp integer
);
CREATE TABLE test_delete_rule.rp
(
id integer NOT NULL
);
INSERT INTO test_delete_rule.reach (id, rp) VALUES (1,10);
INSERT INTO test_delete_rule.reach (id, rp) VALUES (2,20);
INSERT INTO test_delete_rule.reach (id, rp) VALUES (3,30);
INSERT INTO test_delete_rule.reach (id, rp) VALUES (4,40);
INSERT INTO test_delete_rule.rp (id) VALUES (10);
INSERT INTO test_delete_rule.rp (id) VALUES (20);
INSERT INTO test_delete_rule.rp (id) VALUES (30);
INSERT INTO test_delete_rule.rp (id) VALUES (40);And there is a view on reach called
vw_reach:CREATE VIEW test_delete_rule.vw_reach AS
select * from test_delete_rule.reachAnd on this view is a rule, deleting the reach and the referenced rp:
CREATE OR REPLACE RULE reach_on_delete AS
ON DELETE TO test_delete_rule.vw_reach
DO INSTEAD
(
DELETE FROM test_delete_rule.reach
WHERE reach.id = old.id;
DELETE FROM test_delete_rule.rp
WHERE rp.id = old.rp;
);When we delete now an entry from the
vw_reach delete from test_delete_rule.vw_reach where id = 2The entry with id 2 from
reach is deleted, but not the entry with 20 from rp.When I have the same rule on the table with
DO ALSO ir works:CREATE OR REPLACE RULE reach_on_delete AS
ON DELETE TO test_delete_rule.reach
DO ALSO
(
DELETE FROM test_delete_rule.rp
WHERE rp.id = old.rp;
);So according the response here https://stackoverflow.com/questions/5534927/how-to-write-a-delete-rule-on-a-view the second statement is not executed becau
Solution
Quote from the manual
Caution
In many cases, tasks that could be performed by rules on INSERT/UPDATE/DELETE are better done with triggers. Triggers are notationally a bit more complicated, but their semantics are much simpler to understand.
(Emphasis mine)
I think this is one of the many cases where this is better done with a trigger:
Online example: https://rextester.com/KMEDTV61929
Caution
In many cases, tasks that could be performed by rules on INSERT/UPDATE/DELETE are better done with triggers. Triggers are notationally a bit more complicated, but their semantics are much simpler to understand.
(Emphasis mine)
I think this is one of the many cases where this is better done with a trigger:
create or replace function delete_reach()
returns trigger
as
$
begin
DELETE FROM reach
WHERE reach.id = old.id;
DELETE FROM rp
WHERE rp.id = old.rp;
return old;
end;
$
language plpgsql;
create trigger delete_reach_trigger
instead of delete
on vw_reach
for each row
execute procedure delete_reach();Online example: https://rextester.com/KMEDTV61929
Code Snippets
create or replace function delete_reach()
returns trigger
as
$$
begin
DELETE FROM reach
WHERE reach.id = old.id;
DELETE FROM rp
WHERE rp.id = old.rp;
return old;
end;
$$
language plpgsql;
create trigger delete_reach_trigger
instead of delete
on vw_reach
for each row
execute procedure delete_reach();Context
StackExchange Database Administrators Q#227360, answer score: 2
Revisions (0)
No revisions yet.