We have a database with a table called WarehouseItem where product\'s stock levels are kept. I need to know when ever this table get\'s updated, so I create
You could use a loop to iterate over INSERTED
but it may be better to change your scalar variables into a TABLE
and INSERT-SELECT
from INSERTED
where the IDs meet the criteria of the first two IFs
DECLARE @inserted TABLE (StockItemID INT, WarehouseID INT)
INSERT INTO @inserted (StockItemID, WarehouseID)
SELECT StockItemID, WarehouseID
FROM INSERTED i
WHERE dbo.IC_CanSyncProduct(i.StockItemID)=1
AND dbo.IC_CanSyncStock(i.WarehouseID)=1
then you can remove the if else upsert logic and use queries that further filter @inserted
for the various updates and inserts that are required
;WITH ResetQueueEntry
(
SELECT StockItemID
FROM @inserted i
WHERE EXISTS(SELECT 1 FROM IC_ProductCreateQueue q WHERE q.StockItemID = i.StockItemID)
AND EXISTS(SELECT 1 FROM IC_StockUpdateQueue q WHERE q.StockItemID = i.StockItemID))
)
-- Reset [StockUpdate] Queue Entry
UPDATE IC_StockUpdateQueue
SET Synced = 0
WHERE StockItemID IN (SELECT StockItemID FROM ResetStockUpdate);
WITH InsertQueueEntry
(
SELECT StockItemId, 0 Synced
FROM @inserted
WHERE EXISTS(SELECT 1 FROM IC_ProductCreateQueue q WHERE q.StockItemID = i.StockItemID)
AND NOT EXISTS(SELECT 1 FROM IC_StockUpdateQueue q WHERE q.StockItemID = i.StockItemID))
)
-- Insert [StockUpdate] Queue Entry
INSERT INTO IC_StockUpdateQueue (StockItemID, Synced)
SELECT StockItemID, Synced
FROM InsertQueueEntry
WITH CreateProductEntry
(
SELECT StockItemId, 0 Synced
FROM @inserted
WHERE NOT EXISTS(SELECT 1 FROM IC_ProductCreateQueue q WHERE q.StockItemID = i.StockItemID)
)
-- Insert [ProductCreate] Queue Entry
INSERT INTO IC_ProductCreateQueue (StockItemID, Synced)
SELECT StockItemId, Synced
FROM CreateProductEntry
WITH CreateStockEntry
(
SELECT StockItemId, 0 Synced
FROM @inserted
WHERE NOT EXISTS(SELECT 1 FROM IC_ProductCreateQueue q WHERE q.StockItemID = i.StockItemID)
)
-- Insert [StockUpdate] Queue Entry
INSERT INTO IC_StockUpdateQueue (StockItemID, Synced)
SELECT StockItemId, Synced
FROM CreateProductEntry
in case of the trigger is for INSERT, UPDATE this code will exit the trigger IF Records are being updated AND more than one record is being afftected:
IF (SELECT COUNT(*) FROM Deleted) > 1
BEGIN
Return
END
But if you wish to examin every record in the INSERTED recordset you can use this method:
DECLARE rstAST CURSOR FOR
SELECT ins.TaskActionId,
_Task.CustomerId,
_AST.ASTQRId,
ins.ExistingQRcode,
ins.NewQRcode
FROM Inserted ins INNER JOIN
dbo.cdn_AST _AST ON ins.ASTId = _AST.ASTId INNER JOIN
dbo.tsk_Task _Task ON ins.TaskId = _Task.TaskId
OPEN rstAST
FETCH NEXT FROM rstAST INTO @TaskActionId, @TaskCustomerId, @ASTQRId, @ExistingQRcode, @NewQRcode
WHILE @@FETCH_STATUS = 0
BEGIN
--use CONTINUE to skip next record or let it traverse the loop
FETCH NEXT FROM rstAST INTO @TaskActionId, @TaskCustomerId, @ASTQRId, @ExistingQRcode, @NewQRcode
END
CLOSE rstAST
DEALLOCATE rstAST
You use this:
-- Get Product Id
DECLARE @StockItemID INT = (SELECT ItemID FROM INSERTED);
DECLARE @WarehouseID INT = (SELECT WarehouseID FROM INSERTED);
But if you update multi rows (as your sample) you must use a different strategy.
For example, instead to declare a variable, use INSERTED table in JOIN in query where now you use your variable.
IF statement works on your variable but I think to move that condition in query.
Try to change you UPDATE query in this way (eventually add condition of IF):
-- Reset [StockUpdate] Queue Entry
UPDATE IC_StockUpdateQueue SET Synced = 0
FROM inserted
WHERE inserted.itemID = StockItemID;
And so on.
For further information please add comment.