在某些情况下用于抑制 'DELETE FROM table' 的 Postgresql 规则

标签 postgresql sql-delete rule

我的数据库中有两个表:orderdeliveries。创建订单时,我会根据订单的开始日期和结束日期同时生成多个交货。

交付有 bool 值 done 字段,在交付完成时检查。如果有任何已完成的交付,我必须禁止删除任何订单 - 否则交付者将丢失数据(例如交付重量),因为此类信息存储在 order 中。只有在没有完成交货的情况下,我才能将它们与订单一起删除。 在这种情况下,我可以使用规则(Disable DELETE on table in PostgreSQL?),但在我的情况下似乎不起作用:“接近 IF 的语法错误”。 这里的规则好吗?为什么我的 IF-THEN 语句无法正常工作?

CREATE RULE delete_order AS ON DELETE TO orders DO INSTEAD
(
    DELETE FROM deliveries WHERE (order = OLD.id AND done = false);
    IF (NOT EXISTS(SELECT 1 FROM deliveries WHERE order = OLD.id)) THEN
            DELETE FROM orders WHERE id = OLD.id;
    ELSE
            RAISE NOTICE 'Cannot delete order that is partially done.';
    END IF;
)

最佳答案

你最好在这里写一个触发函数。

CREATE FUNCTION delete_order () RETURNS trigger AS $$
BEGIN
  IF EXISTS(SELECT 1 FROM deliveries WHERE order = OLD.id AND done = TRUE) THEN
    RAISE NOTICE 'Cannot delete order that is partially or completely done.';
  ELSE
    RETURN OLD;
  END IF;
END;
$$ LANGUAGE PLPGSQL;

CREATE TRIGGER before_delete_order
  BEFORE DELETE ON order
  FOR EACH ROW EXECUTE PROCEDURE delete_order();

每次您要删除订单时,函数 delete_order() 都会在实际删除发生之前被调用。如果已经完成任何交付,则会引发错误,中止删除。否则返回OLD,系统执行删除操作。这假设 order 记录的删除级联到关联的 deliveries;如果不是,触发器函数可能应该首先删除这些送货记录,以免在删除订单记录时出现 FK 违规。

关于在某些情况下用于抑制 'DELETE FROM table' 的 Postgresql 规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23818509/

相关文章:

java - Eclipse/Hibernate 工具错误 : Archive classpath entry doesn't exist

javascript - PHP Ajax MySQL 表行删除

mysql - 使用 Doctrine 在 MySQL 数据库上删除多表的语法是什么?

core-data - 删除一对一关系的规则

64 位服务器上 PostgreSQL 中 int4 和 int8 的性能差异

postgresql - 在数据库上的每个api调用上,gorm范围都会继续添加到上一个

postgresql - 如何指定模式以在 Postgresql 命令行中针对运行 sql 文件

sql - 我如何知道何时根据 C# 列表插入、删除或更新?

export - 带描述的 Sonar 质量配置文件规则导出

makefile - 为什么 gnu make 忽略我的显式模式规则并改用内置的隐式规则?