I am working on a MSSQL Database (for a program called Sage 200). There are many tables in the database, however, I want to be notified of changes (new record inserted or existing record updated) via Trigger on a specific table.
I also want to support multiple rows on this table being updated at same time also.
When a record is inserted or updated, I want to take a specific field from the table and insert/update another table with that field's value.
So, to put it into perspective; the helper stored prodc & sql trigger looks like this:
/**
* New Stored Procedures
*/
IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id(N'[dbo].[SyncCustomerUpdateQueue]') AND OBJECTPROPERTY(id, N'IsProcedure') = 1)
BEGIN
DROP PROCEDURE [dbo].[SyncCustomerUpdateQueue]
END
GO
CREATE PROCEDURE [dbo].[SyncCustomerUpdateQueue]
@SLCustomerAccountID INT,
@TriggerSource VARCHAR(30)
AS
-- Init
SET NOCOUNT ON;
DECLARE @EventType VARCHAR(8);
-- Check If Customer Doesn't Already Exist In Queue Table
IF ((SELECT COUNT(*) FROM IC_CustomerUpdates WHERE SLCustomerAccountID = @SLCustomerAccountID) = 0)
BEGIN
-- Insert new record
SET @EventType = '[INSERT]';
INSERT INTO IC_CustomerUpdates (SLCustomerAccountID, Synced) VALUES
(@SLCustomerAccountID, 0);
END
ELSE
BEGIN
-- Update existing record
SET @EventType = '[UPDATE]';
UPDATE IC_CustomerUpdates SET Synced = 0
WHERE SLCustomerAccountID = @SLCustomerAccountID;
END
-- Debug
print @EventType + ' Customer Updates Queue Entry | SLCustomerAccountID : ' + CAST(@SLCustomerAccountID AS VARCHAR(255)) + ' | Trigger Source : ' + @TriggerSource;
GO
/*
* New SAGE DB Triggers
*/
IF ((SELECT COUNT(*) FROM sys.triggers WHERE name = 'IC_CustomerChanges') > 0)
DROP TRIGGER [dbo].[IC_CustomerChanges]
GO
CREATE TRIGGER [dbo].[IC_CustomerChanges] ON [dbo].[SLCustomerAccount]
AFTER INSERT, UPDATE
AS
BEGIN
DECLARE @TriggerSource VARCHAR(30) = 'IC_CustomerChanges';
SELECT RowNum = ROW_NUMBER() OVER(ORDER BY SLCustomerAccountID) , SLCustomerAccountID
INTO #CustomerUpdates
FROM INSERTED;
DECLARE @MaxRownum INT;
SET @MaxRownum = (SELECT MAX(RowNum) FROM #CustomerUpdates);
DECLARE @Iter INT;
SET @Iter = (SELECT MIN(RowNum) FROM #CustomerUpdates);
WHILE @Iter <= @MaxRownum
BEGIN
-- Sync Customer Update Queue Entry
DECLARE @SLCustomerAccountID INT = (SELECT SLCustomerAccountID FROM #CustomerUpdates WHERE RowNum = @Iter);
EXEC SyncCustomerUpdateQueue @SLCustomerAccountID, @TriggerSource;
-- Next Row
SET @Iter = @Iter + 1;
END
DROP TABLE #CustomerUpdates;
END
GO
IF ((SELECT COUNT(*) FROM sys.triggers WHERE name = 'IC_CustomerContactChanges') > 0)
DROP TRIGGER [dbo].[IC_CustomerContactChanges]
GO
CREATE TRIGGER [dbo].[IC_CustomerContactChanges] ON [dbo].[SLCustomerContactValue]
AFTER INSERT, UPDATE
AS
BEGIN
DECLARE @TriggerSource VARCHAR(30) = 'IC_CustomerContactChanges';
SELECT RowNum = ROW_NUMBER() OVER(ORDER BY SLCustomerContactID) , SLCustomerContactID
INTO #CustomerContactUpdates
FROM INSERTED;
DECLARE @MaxRownum INT;
SET @MaxRownum = (SELECT MAX(RowNum) FROM #CustomerContactUpdates);
DECLARE @Iter INT;
SET @Iter = (SELECT MIN(RowNum) FROM #CustomerContactUpdates);
WHILE @Iter <= @MaxRownum
BEGIN
-- Sync Customer Update Queue Entry
DECLARE @SLCustomerAccountID INT = (SELECT TOP 1 CC.SLCustomerAccountID
FROM SLCustomerContactValue AS CCV
INNER JOIN SLCustomerContact AS CC ON CC.SLCustomerContactID = CCV.SLCustomerContactID
WHERE CCV.SLCustomerContactID = (SELECT SLCustomerContactID FROM #CustomerContactUpdates WHERE RowNum = @Iter));
EXEC SyncCustomerUpdateQueue @SLCustomerAccountID, @TriggerSource;
-- Next Row
SET @Iter = @Iter + 1;
END
DROP TABLE #CustomerContactUpdates;
END
GO
IF ((SELECT COUNT(*) FROM sys.triggers WHERE name = 'IC_CustomerLocationChanges') > 0)
DROP TRIGGER [dbo].[IC_CustomerLocationChanges]
GO
CREATE TRIGGER [dbo].[IC_CustomerLocationChanges] ON [dbo].[SLCustomerLocation]
AFTER INSERT, UPDATE
AS
BEGIN
DECLARE @TriggerSource VARCHAR(30) = 'IC_CustomerLocationChanges';
SELECT RowNum = ROW_NUMBER() OVER(ORDER BY SLCustomerAccountID) , SLCustomerAccountID
INTO #CustomerLocationChanges
FROM INSERTED;
DECLARE @MaxRownum INT;
SET @MaxRownum = (SELECT MAX(RowNum) FROM #CustomerLocationChanges);
DECLARE @Iter INT;
SET @Iter = (SELECT MIN(RowNum) FROM #CustomerLocationChanges);
WHILE @Iter <= @MaxRownum
BEGIN
-- Sync Customer Update Queue Entry
DECLARE @SLCustomerAccountID INT = (SELECT SLCustomerAccountID FROM #CustomerLocationChanges WHERE RowNum = @Iter);
EXEC SyncCustomerUpdateQueue @SLCustomerAccountID, @TriggerSource;
-- Next Row
SET @Iter = @Iter + 1;
END
DROP TABLE #CustomerLocationChanges;
END
GO
This works as expected, however I have been informed that I am doing things incorrectly. How can I improve this?