Disallowing restatements and enabling idempotency should only be done in an environment where data are expected to arrive synchronously. In a situation where data may arrive out-of-changing time order you could otherwise end up with data loss. Consider the following:
> Message 1, with changing time 42 and value: A arrives.
> Message 2, with changing time 43 and value: B arrives.
> Message 3, with changing time 44 and value: A arrives.
Compared to the following:
> Message 1, with changing time 42 and value: A arrives.
> Message 2, with changing time 44 and value: A arrives.
> Message 3, with changing time 43 and value: B arrives.
Idempotency (with an optional restatement constraint) would in the latter case discard the second message, as its value is identical to the one already stored. That the decision to do so was incorrect can only be determined after the third message has arrived.
The proof of concept outlined above did not work out well enough with respect to existing functionality, and I had to change it. Following is how the insert trigger on the latest view may be altered for one specific example to enable idempotency:
ALTER TRIGGER [dbo].[itST_Stage] ON [dbo].[lST_Stage]INSTEAD OF INSERTASBEGIN SET NOCOUNT ON; DECLARE @now DATETIME2(7) = SYSDATETIME(); DECLARE @v INT, @maxV INT; -- don't do this for non-generators DECLARE @ST TABLE ( Row int identity(1,1) not null primary key, ST_ID int not null ); INSERT INTO [dbo].[ST_Stage]( ST_Dummy ) OUTPUT inserted.ST_ID INTO @ST SELECT null FROM inserted WHERE inserted.ST_ID is null; -- don't forget metadata if used DECLARE @inserted TABLE ( ST_ID int not null, ST_NAM_Stage_Name varchar(42) null, ST_NAM_ChangedAt date null, ST_LOC_Stage_Location varchar(42) null ); INSERT INTO @inserted SELECT ISNULL(i.ST_ID, a.ST_ID), i.ST_NAM_Stage_Name, ISNULL(i.ST_NAM_ChangedAt, @now), i.ST_LOC_Stage_Location FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY ST_ID ORDER BY ST_ID) AS Row FROM inserted ) i LEFT JOIN @ST a ON a.Row = i.Row; -- non-generator version: /* DECLARE @inserted TABLE ( ST_ID int not null, ST_NAM_Stage_Name varchar(42) null, ST_NAM_ChangedAt date null, ST_LOC_Stage_Location varchar(42) null ); INSERT INTO @inserted SELECT i.ST_ID, i.ST_NAM_Stage_Name, ISNULL(i.ST_NAM_ChangedAt, @now), i.ST_LOC_Stage_Location FROM inserted i WHERE i.ST_ID is not null; */ -- for every idempotent attribute DECLARE @versioned TABLE ( ST_ID int not null, ST_NAM_Stage_Name varchar(42) null, ST_NAM_ChangedAt date null, ST_NAM_Version int not null, PRIMARY KEY(ST_NAM_Version, ST_ID) ); INSERT INTO @versioned SELECT ST_ID, ST_NAM_Stage_Name, ST_NAM_ChangedAt, ROW_NUMBER() OVER (PARTITION BY ST_ID ORDER BY ST_NAM_ChangedAt) FROM @inserted WHERE ST_NAM_Stage_Name is not null; SELECT @maxV = MAX(ST_NAM_Version) FROM @versioned; SET @v = 0; WHILE(@v < @maxV) BEGIN SET @v = @v + 1; INSERT INTO [dbo].[ST_NAM_Stage_Name]( ST_ID, ST_NAM_Stage_Name, ST_NAM_ChangedAt ) SELECT v.ST_ID, v.ST_NAM_Stage_Name, v.ST_NAM_ChangedAt FROM @versioned v LEFT JOIN lST_Stage [ST] ON [ST].ST_ID = v.ST_ID WHERE v.ST_NAM_Version = @v AND ( [ST].ST_NAM_Stage_Name is null OR [ST].ST_NAM_Stage_Name <> v.ST_NAM_Stage_Name ) END INSERT INTO [dbo].[ST_LOC_Stage_Location]( ST_ID, ST_LOC_Stage_Location ) SELECT i.ST_ID, i.ST_LOC_Stage_Location FROM @inserted i WHERE i.ST_LOC_Stage_Location is not null;END