2017-07-19 108 views
0

請幫我完成觸發器。我到目前爲止:SQL插入觸發條件語句和多行

CREATE TRIGGER [dbo].[atbl_Sales_OrdersLines_ITrigGG] 
ON [dbo].[atbl_Sales_OrdersLines] 
FOR INSERT 
AS 
BEGIN 

DECLARE @ID INT = (SELECT ProductID 
FROM INSERTED) 

DECLARE @OrderedQ INT = (SELECT SUM(Amount) 
FROM atbl_Sales_OrdersLines 
WHERE ProductID = @ID) 

DECLARE @CurrentQ INT = (SELECT Quantity 
FROM atbl_Sales_Products 
WHERE ProductID = @ID) 

DECLARE @PossibleQ INT = (SELECT Amount 
FROM INSERTED 
WHERE ProductID = @ID) 

IF (@CurrentQ - @OrderedQ >= @PossibleQ) 

ELSE 

END 

我需要完成代碼。無法弄清楚如何去做。我需要,如果條件滿足 - 觸發器將允許插入。否則,觸發器將停止插入/或回滾,並提示消息數量不足。

此外,如果插入是多行不同的產品ID,此代碼將工作嗎?

謝謝。

+0

最後一個問題的答案是** no **,如果插入是多行不同產品ID,則不起作用。設置「@ id」的前兩行只能從「插入」行中的所有productId中捕獲單個產品ID。所以,之後的所有事情都與真相的一部分有關。 – hatchet

+0

不,這是非常糟糕的代碼。如果插入多行,則只選擇一個ID(例如來自SELECT的最後一個)。它忽略了所有其他的。所有觸發器都需要以集合表示法編寫,假設插入(和/或刪除)集合中將存在多行。任何時候你在這裏聲明一個標量變量,它都是一個紅旗。這對於你正在嘗試做的事情將永遠不會起作用。 – pmbAustin

+0

有什麼建議嗎?我爲了學習的目的而進行鍛鍊並不是一個實際的項目。此外,如果整個訂單在一個或多個產品缺少數量時被拒絕,那麼很好。 – Benua

回答

1

這樣的事情可能會奏效。該觸發器檢查插入中的產品,將已訂購的總量(現在和過去)相加,並且如果它們中的任何一個超出可用數量,則整個事務將被回滾。無論何時編寫觸發器,都希望避免假設有一行被插入/更新/刪除,並避免使用遊標。你只想使用基本的基於集合的操作。

CREATE TRIGGER [dbo].[atbl_Sales_OrdersLines_ITrigGG] 
    ON [dbo].[atbl_Sales_OrdersLines] 
    FOR INSERT 
    AS 
    BEGIN 
     IF (exists (select 1 from (
      select x.ProductId, totalOrdersQty, ISNULL(asp.Quantity, 0) PossibleQty from (
       select i.ProductId, sum(aso.Amount) totalOrdersQty 
       from (select distinct ProductId from inserted) i 
       join atbl_Sales_OrdersLines aso on aso.ProductId = i.ProductId 
       group by productId) x 
      left join atbl_Sales_Product asp on asp.ProductId = x.ProductId 
      ) x 
      where PossibleQty < totalOrdersQty)) 
     BEGIN  
      RAISERROR ('Quantity is not sufficient' ,10,1) 
      ROLLBACK TRANSACTION 
     END 
    END 

我仍然認爲這是一個可怕的想法。

+0

謝謝,但我得到THEN和END使用的語法錯誤。 – Benua

+0

我在頭頂上敲了一下。我忘了BEGIN。請參閱編輯。 – hatchet

+0

仍然無法在SQL服務器上運行它,但感謝 - 現在我知道如何做到這一點的概念。 – Benua

0

試試這個,

CREATE TRIGGER [dbo].[atbl_Sales_OrdersLines_ITrigGG] 
ON [dbo].[atbl_Sales_OrdersLines] 
INSTEAD OF INSERT --FOR INSERT 
AS 
BEGIN 

DECLARE @ID INT = (SELECT ProductID 
FROM INSERTED) 

DECLARE @OrderedQ INT = (SELECT SUM(Amount) 
FROM atbl_Sales_OrdersLines 
WHERE ProductID = @ID) 

DECLARE @CurrentQ INT = (SELECT Quantity 
FROM atbl_Sales_Products 
WHERE ProductID = @ID) 

DECLARE @PossibleQ INT = (SELECT Amount 
FROM INSERTED 
WHERE ProductID = @ID) 

IF (@CurrentQ - @OrderedQ >= @PossibleQ) 
BEGIN 
     INSERT INTO YOURTABLE (COLUMN1, COLUMN2, COLUMN3, ..) 
     SELECT COLUMN1, COLUMN2, COLUMN3, .. 
     FROM inserted 
END 
ELSE 
BEGIN 
    RAISERROR ('Quantity is not sufficient' ,10,1) 
     ROLLBACK TRANSACTION 

END 
+0

如果'inserted'中有多行,這仍然是錯誤的。 – hatchet

+0

也許我們可以在這裏運行循環?檢查每一行(在每次檢查時重新聲明ID)如果任何行失敗 - 回滾。 – Benua

+0

比這更復雜。如果任何productId的總和超過可用金額,則需要按照productId對組插入的行進行分組,並對其進行回滾。 – hatchet