Hi,
I have a DimProduct and StagingProduct tables.
I have a trigger that checks if the record (in staging) to be inserted/updated to DW overlaps with the record in DW.
The trigger works perfectly if i run using update statement. But couldn't run properly when I'm doing merge.
Please help.
/*create tables and records */ CREATE TABLE [dbo].[DimProduct]( [ProductKey] [int] IDENTITY(1,1) NOT NULL, [ProductID] [smallint] NOT NULL, [Description] [varchar](50) NOT NULL, [SubProductID] [int] NOT NULL, [ValidFrom] [date] NOT NULL, [ValidTo] [date] NOT NULL ) ON [PRIMARY] CREATE TABLE [dbo].[StagingProduct]( [ProductID] [smallint] NOT NULL, [Description] [varchar](50) NOT NULL, [SubProductID] [int] NOT NULL, [ValidFrom] [date] NOT NULL, [ValidTo] [date] NOT NULL ) ON [PRIMARY] insert into dbo.StagingProduct values (1, 'Pencil', 1, '2013-01-01', '2013-03-05') insert into dbo.StagingProduct values (1, 'Pencil', 1, '2013-03-06', '2013-06-10') insert into dbo.StagingProduct values (2, 'IPhone', 2, '2011-01-02', '2012-07-10') /*trigger for DimProduct*/ CREATE TRIGGER [dbo].[Trigger_ChannelCheck] ON [dbo].[DimProduct] INSTEAD OF INSERT, UPDATE AS IF NOT EXISTS( SELECT a.SubProductID FROM (SELECT aa.SubProductID, aa.ValidFrom, aa.ValidTo, aa.ProductID FROM dbo.DimProduct aa WHERE NOT EXISTS (select ProductKey FROM inserted WHERE SubProductID = aa.SubProductID AND ValidFrom = aa.ValidFrom AND ProductID = aa.ProductID) ) a INNER JOIN (SELECT SubProductID, ValidFrom, ValidTo, ProductID FROM inserted) b ON a.SubProductID = b.SubProductID WHERE b.ValidFrom <= a.ValidTo and b.ValidTo >= a.ValidFrom ) BEGIN UPDATE b SET b.Description = a.Description, b.ValidTo = a.ValidTo FROM inserted a INNER JOIN dbo.DimProduct b ON a.SubProductID = b.SubProductID AND a.ValidFrom = b.ValidFrom AND a.ProductID = b.ProductID INSERT INTO dbo.DimProduct ([ProductID] ,[Description] ,[SubProductID] ,[ValidFrom] ,[ValidTo] ) SELECT [ProductID] ,[Description] ,[SubProductID] ,[ValidFrom] ,[ValidTo] FROM inserted a WHERE NOT EXISTS (SELECT 1 FROM dbo.DimProduct WHERE SubProductID = a.SubProductID AND ProductID = a.ProductID AND ValidFrom = a.ValidFrom) END ELSE ROLLBACK /*execute merge to load staging to dw */ MERGE dbo.DimProduct AS trget USING (SELECT * FROM StagingProduct a ) as src ON (trget.[SubProductID] = src.[SubProductID] and trget.[ProductID] = src.[ProductID] and trget.ValidFrom = src.ValidFrom ) WHEN NOT MATCHED BY TARGET THEN INSERT ([ProductID] ,[Description] ,[SubProductID] ,[ValidFrom] ,[ValidTo] ) VALUES (src.[ProductID] ,src.[Description] ,src.[SubProductID] ,src.[ValidFrom] ,src.[ValidTo] ) WHEN MATCHED THEN UPDATE SET trget.Description = src.Description, trget.ValidTo = src.ValidTo; /* error triggers when this is executed. */ update dbo.DimProduct set validto = '2013-03-12' where validfrom = '2013-01-01' /*modify the validto of the record to create an overlap */ update dbo.StagingProduct set validto = '2013-03-12' where validfrom = '2013-01-01' /* if merge is run, the trigger does not behave as it should. no error is raised */ MERGE dbo.DimProduct AS trget USING (SELECT * FROM StagingProduct a ) as src ON (trget.[SubProductID] = src.[SubProductID] and trget.[ProductID] = src.[ProductID] and trget.ValidFrom = src.ValidFrom ) WHEN NOT MATCHED BY TARGET THEN INSERT ([ProductID] ,[Description] ,[SubProductID] ,[ValidFrom] ,[ValidTo] ) VALUES (src.[ProductID] ,src.[Description] ,src.[SubProductID] ,src.[ValidFrom] ,src.[ValidTo] ) WHEN MATCHED THEN UPDATE SET trget.Description = src.Description, trget.ValidTo = src.ValidTo;
cherriesh