假设我在 SQL Server 中有以下数据库:
CREATE TABLE [Order]
(
ID BIGINT IDENTITY(1,1)
CONSTRAINT PK_Order PRIMARY KEY CLUSTERED (ID)
);
CREATE TABLE OrderItem
(
ID BIGINT IDENTITY(1,1),
ORDER_ID BIGINT NOT NULL,
PRICE_ID BIGINT NOT NULL,
DISCOUNTED_PRICE_ID BIGINT NULL,
CONSTRAINT PK_OrderItem PRIMARY KEY CLUSTERED (ID)
);
CREATE TABLE Price
(
ID BIGINT IDENTITY(1,1),
AMOUNT FLOAT NOT NULL,
CURRENCY VARCHAR(3) NOT NULL,
CONSTRAINT PK_Price PRIMARY KEY CLUSTERED (ID)
);
ALTER TABLE OrderItem ADD CONSTRAINT FK_OrderItem_Order
FOREIGN KEY (ORDER_ID) REFERENCES [Order](ID) ON DELETE CASCADE;
ALTER TABLE OrderItem ADD CONSTRAINT FK_OrderItem_Price
FOREIGN KEY (PRICE_ID) REFERENCES Price(ID);
ALTER TABLE OrderItem ADD CONSTRAINT FK_OrderItem_DiscountedPrice
FOREIGN KEY (DISCOUNTED_PRICE_ID) REFERENCES Price(ID);
如果我删除订单,所有订单项目都将被删除(因为ON DELETE CASCADE
on FK_OrderItem_Order
约束),但相应的价格(正常价格和折扣价格)将永远保留在数据库中。
SQL Server(或通用 SQL)中是否有任何选项可以从中删除相应的价格Price
table?
我可以想到一个完美匹配的触发器,但对于这样简单(且常见)的任务来说太麻烦了。我更愿意在我的约束上指定一些内容(FK_OrderItem_Price
and FK_OrderItem_DiscountedPrice
)基本上说“这是一对一的关系”,删除父级(Price
在本例中是父表)如果删除了子表。
In a nutshell: no. Cascading works only from parent to child1, not the other way around.
有人可能会说,当一些父母失去最后一个孩子时,他们应该被移除,但这根本不是当前 DBMS 的实现方式。
您必须使用触发器来执行此类“特殊”参考操作,或者使用批处理作业(它不必立即发生)。或者将操作隐藏在某种明确执行此操作的 API(存储过程、中间层方法)后面。
也可以看看:订单稳定性 https://stackoverflow.com/a/11930467/533120.
1 In you case, Order and Price both act as parents to OrderItem.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)