我根据另一个 SE 问题(Hash Rings On PostgreSql)得出以下内容
CREATE TABLE sms.tablename
(
id uuid,
mdate date
)
还有分区。
CREATE TABLE sms.tablename_partition_1 ( CHECK ( sms.hash(id) = '1' ) ) INHERITS (sms.tablename);
...
CREATE TABLE sms.tablename_partition_f ( CHECK ( sms.hash(id) = 'f' ) ) INHERITS (sms.tablename);
现在问题来了。
当我添加此触发器时。
CREATE TRIGGER "delete_me"
BEFORE DELETE
ON sms.tablename
FOR EACH ROW
EXECUTE PROCEDURE sms.delete_me(E'\\x');
CREATE OR REPLACE FUNCTION sms.delete_me()
RETURNS trigger AS
$BODY$
begin
RAISE NOTICE 'HERE !!!';
return OLD;
end;
$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER
COST 100;
此触发器永远不会运行... 我看不到“通知”消息。 现在,如果我将相同的触发器应用于另一个表(非分区),它可以正常工作,该行将被删除并弹出通知消息。
More Info : "PostgreSQL 9.1.6 on i686-pc-linux-gnu, compiled by gcc-4.4.real (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3, 32-bit"
我只是想避免在表上使用存储过程并保持 ORM 干净。
已编辑:
1) 表或任何继承的表上不存在规则,这同样适用于索引或 PK。
2) 运行以下命令。
DELETE FROM sms.tablename WHERE id = 'a5e52a04-282f-4cf4-8347-a43d68725e6b';
3) 显示此问题的完整 SQL。
http://pastebin.com/mZBFEtaY
最佳答案
删除触发器在包含该行的子表上触发,而不是在父表上触发。您必须将触发器添加到每个子表。
DO
$$
DECLARE
h text;
BEGIN
FOR h IN SELECT to_hex(x) FROM generate_series(0,15) x LOOP
EXECUTE format('CREATE TRIGGER "DeleteRedirector" BEFORE DELETE ON pproblem.%I FOR EACH ROW EXECUTE PROCEDURE pproblem.delete_me('''');',
'tablename_partition_'||h);
END LOOP;
END;
$$;
演示:
regress=# begin;
BEGIN
regress=# DELETE FROM pproblem.tablename;
NOTICE: HERE !!!
NOTICE: HERE !!!
NOTICE: HERE !!!
DELETE 3
regress=# rollback;
ROLLBACK
关于Postgresql 分区表删除触发器失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13119238/