SQL中实现禁止删除关联数据的外键约束配置咨询
SQL中实现禁止删除关联数据的外键约束配置咨询
嘿,看你贴的SQL代码,应该是想配置外键约束来禁止删除存在关联子数据的父表记录对吧?先帮你把未完成的Placed表外键补全,再给你讲清楚怎么实现这个需求~
完整修正后的SQL定义
首先,我把你未写完的Placed表外键补全,同时调整外键的删除行为,满足“禁止删除关联数据”的要求:
CREATE TABLE Customer( cust_id INT NOT NULL PRIMARY KEY CHECK (cust_id > 0), full_name TEXT NOT NULL, phone TEXT NOT NULL, address TEXT NOT NULL CHECK (LENGTH(address) >= 3) ); CREATE TABLE "Order"( order_id INT NOT NULL PRIMARY KEY CHECK (order_id > 0), date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL ); CREATE TABLE Dish( dish_id INT NOT NULL PRIMARY KEY CHECK (dish_id > 0), name TEXT NOT NULL CHECK (LENGTH(name) >= 3), price NUMERIC NOT NULL CHECK (price > 0), is_active BOOLEAN NOT NULL ); CREATE TABLE Placed( order_id INT NOT NULL, cust_id INT NOT NULL, -- 这里建议改成复合主键:因为`Placed`是订单与客户的关联表,单`order_id`做主键的话,一个订单只能关联一个客户(虽然业务上可能合理,但复合主键更符合关联表的设计规范) PRIMARY KEY (order_id, cust_id), CHECK (order_id > 0), CHECK (cust_id > 0), -- 核心配置:禁止删除存在关联`Placed`记录的订单 FOREIGN KEY (order_id) REFERENCES "Order" (order_id) ON DELETE RESTRICT, -- 同样禁止删除存在关联`Placed`记录的客户 FOREIGN KEY (cust_id) REFERENCES Customer (cust_id) ON DELETE RESTRICT );
关键配置说明
你之前在Placed表的order_id外键用了ON DELETE CASCADE,这会导致删除订单时,关联的Placed记录也被级联删除,和你想要的“禁止删除”需求相反。这里换成ON DELETE RESTRICT就可以实现目标:
ON DELETE RESTRICT:当你尝试删除父表(比如Order或Customer)中存在子表(Placed)关联记录的行时,数据库会直接抛出错误,阻止删除操作,完美实现“禁止删除关联数据”的效果。- 另外提一下,PostgreSQL中
NO ACTION和RESTRICT的区别:NO ACTION是在语句执行结束时检查约束,RESTRICT是在执行删除操作时立即检查,大部分业务场景下两者效果一致,都能达到阻止删除的目的。
如果已经创建表,如何修改外键约束
如果你的表已经创建好了,想要修改现有外键的删除行为,可以用ALTER TABLE语句:
-- 修改Placed表的order_id外键为ON DELETE RESTRICT ALTER TABLE Placed DROP CONSTRAINT placed_order_id_fkey, ADD CONSTRAINT placed_order_id_fkey FOREIGN KEY (order_id) REFERENCES "Order" (order_id) ON DELETE RESTRICT; -- 修改cust_id的外键同理 ALTER TABLE Placed DROP CONSTRAINT placed_cust_id_fkey, ADD CONSTRAINT placed_cust_id_fkey FOREIGN KEY (cust_id) REFERENCES Customer (cust_id) ON DELETE RESTRICT;
备注:内容来源于stack exchange,提问作者Moran
相关产品推荐
相关产品推荐

