簡體   English   中英

使用觸發器來實現引用完整性操作(SQL Server)

[英]Using triggers to implement referential integrity actions (SQL Server)

我正在嘗試為我的桌子實施一些觸發器

表中的2個是ORDERS (有訂單)和ORDERS_ITEMS (每個訂單都有項目),並且當該ORDER中沒有更多ITEMS時,我想刪除該ORDER

我希望我的扳機看起來像這樣

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;

我不確定如何在SQL Server中編寫此代碼,並且從書中獲得了算法,但是無法在SQL Server上運行它。

不要為此使用觸發器。 將foriegn鍵與級聯刪除一起使用。

更新

抱歉,我跳錯了答案。 如果要在沒有任何項目連接時刪除訂單,則級聯刪除將無濟於事。
在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

分解:

  1. inner join表與deleted表的連接將確保您僅刪除OrderNumberorder_item表中已刪除記錄相同的記錄。
  2. order_item表的left join以及where子句可確保您僅在訂單未附加order_item記錄的情況下從訂單表中刪除記錄。

您的語法看起來更像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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM