Composable DML (Merge… Insert) with Foreign Key Issue and Solution
Posted: February 13, 2013 Filed under: SQL Server 2008, SQL Server 2012 Leave a commentYou can use Merge with INSERT (Composable DML) to log historic data. But you cannot insert into a table with a FOREIGN KEY defined. You will run into error like this:
” The target table ‘myTable’ of the INSERT statement cannot be on either side of a (primary key, foreign key)
relationship when the FROM clause contains a nested INSERT, UPDATE, DELETE, or MERGE statement.”
A workaround is to disable (or drop) these constraints before Insert and enable these constrains afterwards.
--mylog table has two foreign keys:[FK_myLog_a], [FK_myLog_s] -- --disable constraints ALTER TABLE [dbo].[myLog] NOCHECK CONSTRAINT ALL INSERT INTO [dbo].[myLog] SELECT Action, ISNULL(Newaccountid ,Oldaccountid) as accountid, ISNULL(Newserviceid,Oldserviceid) as serviceid, changedDate FROM ( MERGE asTable AS target USING ( SELECT b.accountid,t1.Serviceid FROM mytable) AS source (Newid, Newsid) ON (target.id = source.Newid ) WHEN NOT MATCHED BY TARGET --Insert new THEN INSERT (accountid, Serviceid) VALUES (Newaccountid, NewServiceid) WHEN NOT MATCHED BY SOURCE AND (target.id <>4) --Delete old THEN DELETE OUTPUT $action, Inserted.id, Inserted.sid, Deleted.id,Deleted.sid, GETDATE() ) AS Changes (Action, Newid, Newsid,Oldid, Oldsid, changedDate) WHERE Action = 'DELETE' Or Action = 'INSERT'; --Enable constraints after the operation ALTER TABLE [dbo].[accountserviceLog] CHECK CONSTRAINT ALL ALTER TABLE [dbo].[myLog] WITH CHECK CHECK CONSTRAINT [FK_myLog_a] ALTER TABLE [dbo].[myLog] WITH CHECK CHECK CONSTRAINT [FK_myLog_s] --http://msdn.microsoft.com/en-us/library/bb510625(v=sql.105).aspx --http://www.brentozar.com/blitz/foreign-key-trusted/