使用触发器实现参照完整性操作(SQL Server)

时间:2015-05-06 20:05:49

标签: sql sql-server triggers

我正在尝试为我的表实现一些触发器

其中2个表是ORDERS(有订单)和ORDERS_ITEMS(每个订单都有项目),我想删除ORDER时不再有{{1}在那个ITEMS

我希望我的触发器看起来像这样

ORDER

我不确定如何在SQL Server中编写这个,我从书中获得了算法,但我无法在SQL Server上运行它。

2 个答案:

答案 0 :(得分:2)

不要使用触发器。使用cascade delete.

的foriegn键

更新

对不起,我跳到了错误的结论。如果您想在没有连接项目时删除订单,级联删除将无济于事 在order_item表上使用triger删除后删除并在此处写下删除语句:(再次更新

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

细分:

  1. inner join deleted表将确保您只删除 OrderNumber 与已删除的记录相同的记录 来自 order_item 表的记录。
  2. left join order_item 表以及where子句确保您只删除订单表中的记录,如果它们没有 order_item 附加到他们的记录。

答案 1 :(得分:1)

您的语法看起来更像Oracle; SQL Server语法完全不同。例如,没有new:old:。相反,有表inserteddeleted

如果我理解正确,您想从delete语句中的订单中删除一个项目。然后,如果删除了最后一项,则要删除订单本身。我认为以下是这样的:

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;