[英]Using triggers to implement referential integrity actions (SQL Server)
I'm trying to implement some triggers for my tables 我正在尝试为我的桌子实施一些触发器
2 of the tables are ORDERS
(has orders) and ORDERS_ITEMS
(has items for each order), and I want to delete the ORDER
when there are no more ITEMS
in that ORDER
. 表中的2个是
ORDERS
(有订单)和ORDERS_ITEMS
(每个订单都有项目),并且当该ORDER
中没有更多ITEMS
时,我想删除该ORDER
。
I want my trigger to look something like this 我希望我的扳机看起来像这样
CREATE TRIGGER DELETE_ORDER_WHEN_NO_ITEMS
INSTEAD OF DELETE
ON ORDER
DECLARE rowcount int;
BEGIN
// First detemine if this is the last item in the ORDER
SELECT Count(*)
INTO rowcount
FROM ORDER_ITEM
WHERE ORDER_ITEM.ItemNumber = old:ItemNumber;
// Delete ITEM row
DELETE ORDER_ITEM
WHERE ORDER_ITEM.ItemNumber = old:ItemNumber;
// Last ITEM in ORDER delete the whole ORDER
IF (rowcount = 1) THEN
DELETE ORDER
WHERE ORDER.OrderNumber = old:OrderNumber;
END IF
END;
I'm not sure how to write this in SQL Server and I had the algorithm from a book but I couldn't run it on SQL Server. 我不确定如何在SQL Server中编写此代码,并且从书中获得了算法,但是无法在SQL Server上运行它。
Don't use a trigger for that. 不要为此使用触发器。 Use foriegn key with cascade delete.
将foriegn键与级联删除一起使用。
Sorry, I've jumped to the wrong conclution. 抱歉,我跳错了答案。 If you want to delete the orders when there are no items connected to it, cascade delete will not help.
如果要在没有任何项目连接时删除订单,则级联删除将无济于事。
Use a triger for after delete on the order_item table and write this delete statement there: ( updated again ) 在order_item表上删除后使用触发器进行触发,并在该表中写入以下delete语句:( 再次更新 )
CREATE TRIGGER order_item_delete ON order_item
FOR DELETE
AS
DELETE order
FROM order
INNER JOIN deleted ON (order.OrderNumber = deleted.OrderNumber) -- 1
LEFT JOIN order_Item ON(order.OrderNumber = order_item.OrderNumber)
WHERE order_Item.ItemNumber IS NULL -- 2
GO
Breakdown: 分解:
inner join
with deleted
table will ensures you only delete records where the OrderNumber is the same as the deleted records from order_item table. inner join
表与deleted
表的连接将确保您仅删除OrderNumber与order_item表中已删除记录相同的记录。 left join
with order_item table along with the where
clause ensures you only delete records from orders table if they have no order_item records attached to them. left join
以及where
子句可确保您仅在订单未附加order_item记录的情况下从订单表中删除记录。 Your syntax looks more like Oracle; 您的语法看起来更像Oracle。 SQL Server syntax is quite different.
SQL Server语法完全不同。 For instance, there is no
new:
and old:
. 例如,没有
new:
和old:
Instead, there are tables, inserted
and deleted
. 而是有
inserted
和deleted
表。
If I understand correctly, you want to remove one item from the orders in the delete statement. 如果我理解正确,则想从delete语句的订单中删除一项。 Then, if the last item has been removed, you want to delete the order itself.
然后,如果最后一个项目已被删除,则要删除订单本身。 I think the following does this:
我认为以下是这样做的:
CREATE TRIGGER trg_orders_delete_one_item ON orders
INSTEAD OF DELETE
AS
begin
with todelete as (
select oi.*, row_number() over (partition by OrderId order by ItemNumber desc) as seqnum
from Order_Items oi
where oi.OrderId in (select OrderId from deleted)
)
delete todelete
where seqnum = 1;
with todelete as (
select o.*
from orders o
where o.OrderId in (select OrderId from deleted)
)
delete todelete
where not exists (select 1
from order_item oi
where oi.OrderId = todelete.OrderId
)
end;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.