在我的Postgres 9.4数据库中,我有以下触发器/函数,它实现了"软删除"功能性:
ALTER TABLE my_schema.my_table
ADD COLUMN delete_ind integer
CREATE OR REPLACE FUNCTION trigger_mytable_soft_delete()
RETURNS trigger AS $$
DECLARE
command text := ' SET delete_ind = 1 WHERE uuid_col = $1';
BEGIN
EXECUTE 'UPDATE "my_schema"."my_table"' || TG_TABLE_NAME || command USING OLD.uuid_col;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER my_table_soft_delete_trigger
BEFORE DELETE ON "my_schema"."my_table"
FOR EACH ROW EXECUTE PROCEDURE trigger_mytable_soft_delete();
上面的代码给了我" soft-delete"功能,但是,它也阻止我实际删除/清除那些已标记为已删除的行。
新的期望行为是使用此删除函数来检查delete_ind字段的值,如果已经设置为1,则实际清除该行。
正确的条件语法是什么,它可以设置delete_ind的值。或者实际上根据delete_ind列的当前值删除有问题的行?
答案 0 :(得分:2)
可以通过对您的功能进行相对较小的修改来完成:
CREATE OR REPLACE FUNCTION trigger_mytable_soft_delete()
RETURNS trigger AS
$$
BEGIN
if OLD.delete_ind = 1 then
/* Delete proceeds, you just needs to *do nothing*
except for returning the OLD row as it were */
RETURN OLD ;
else
/* instead of deleting, set a flag */
UPDATE my_schema.my_table
SET deleted_ind = 1
WHERE uuid_col = old.uuid_col ;
/* This will skip the process of this row.
It will also avoid subsequent triggers to be fired, and the row will
not be counted on the rows-affected count. If more triggers need
to be processed, make sure this is the last in the chain.
*/
RETURN NULL ;
end if ;
END;
$$
LANGUAGE plpgsql;
(如果你的功能逐个使用,你可以硬编码,不需要动态SQL)
旁注:如果列delete_ind
仅用作标记,则通过将其声明为{{1}来最好地传达其含义而不是boolean not null
。