Need Update Trigger with Version number in the History Table

Hello All,

I need a version(sequence) number in the history table, how can I do that ?

MyTable
ID
Value

MyTable_History
ID
MyTableID
Version
Value

how can I update the version number.

Its an update trigger only

please do the needful.

Many Thanks
Amjath

The update trigger is on value in MyTable?

Use the special rows INSERTED and DELETED within the update trigger
SELECT ID AS MyTableID, GETDATE() AS Version, Value INTO MyTable_History FROM DELETED

I used getdate as the version number.

Might not be unique? (if inserts are very frequent)

Just use an IDENTITY column. The versions won't be sequential but, for storage, it's not going to matter.

CREATE TRIGGER [dbo].[DI_M_AttestationSnapshotAction_Trigger] ON [dbo].[DI_M_AttestationSnapshotAction]
AFTER UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

INSERT INTO [dbo].[DI_M_AttestationSnapshotAction_History]
       (  [Version]
		  ,[AttestationSnapshotActionId]
		  ,[TaskId]
		  ,[Approve]
		  ,[Revoke]
		  ,[Comment]
		  ,[EffectiveDate]
		  ,[ReviewerId]
		  ,[LastModifiedBy]
		  ,[LastModifiedDate])

SELECT (select (ISNULL(Max([version]), 0) + 1) from DI_M_AttestationSnapshotAction_History where AttestationSnapshotActionid = d.[Id])
	  ,d.[Id]
	  ,d.[TaskId]
	  ,d.[Approve]
	  ,d.[Revoke]
	  ,d.[Comment]
	  ,d.[EffectiveDate]
	  ,d.[ReviewerId]
	  ,d.[LastModifiedBy]
	  ,d.[LastModifiedDate]
	FROM INSERTED i
	JOIN DELETED d ON i.[Id] = d.[Id]
	WHERE 
	i.[Approve] <> d.[Approve] OR
	i.[Revoke] <> d.[Revoke] OR
	i.[Comment] <> d.[Comment] OR
	i.[TaskId] <> d.[TaskId] OR
	i.[EffectiveDate] <> d.[EffectiveDate] OR
	i.[ReviewerId] <> d.[ReviewerId]

END

is this fine ? any performance issue ?

Looks OK to me. Note that

i.[Approve] <> d.[Approve] OR
...

will NOT detect if one/both of the columns are NULL, so this is only safe if those columns can never contain NULLs

I would add a [ChangedDate] DATETIME column to [DI_M_AttestationSnapshotAction_History] and just store GetDate() in it, which would tell you when the change had occurred. Also the UserID if you are able to store that too (we have an [UpdatedBy] column in all our tables, so that gets included in the list of columns stored in our History Tables.

(select (ISNULL(Max([version]), 0) + 1) from DI_M_AttestationSnapshotAction_History where AttestationSnapshotActionid = d.[Id])

That needs an index on [Id], [version], but would then be efficient. Do you absolutely need a version number, or just "chronological order" of changes?

We only use ChronologicalOrder, based on the [ChangedDate] column in our History Tables. We don't have a 1,2,3 ... version number, but it hasn't seemed to matter in our case, folk are just interested in WHAT changed and WHEN and sometimes also: WHO made the change? :slight_smile:

Much cheaper to just store GetDate() in a column than search for Max([version]

One thought, but I haven't tested it, but I think that

(select (ISNULL(Max([version]), 0) + 1) from DI_M_AttestationSnapshotAction_History where AttestationSnapshotActionid = d.[Id])

will give you NULL for the first record (i.e. when there are not rows in HISTORY for that ID), you might have to use:

ISNULL( (select Max([version]) from DI_M_AttestationSnapshotAction_History where AttestationSnapshotActionid = d.[Id]) , 0) + 1)

how to solve this any idea.... ??
i have a comments field, which might come as NULL...

please suggest

something like this will solve this issue
FROM INSERTED i
JOIN DELETED d ON i.[Id] = d.[Id]
WHERE
i.[Approve] <> d.[Approve] OR
i.[Revoke] <> d.[Revoke] OR
ISNULL(i.[Comment], '') <> ISNULL(d.[Comment], '') OR
--i.[TaskId] <> d.[TaskId] OR
ISNULL(i.[EffectiveDate], CONVERT(date, getdate())) <> ISNULL(d.[EffectiveDate], CONVERT(date, getdate()))

...
(
       i.[EffectiveDate] <> d.[EffectiveDate] 
    OR (i.[EffectiveDate] IS NULL AND d.[EffectiveDate] IS NULL) 
) OR
...

I suspect using IsNull() with a bogus value (GetDate() in your example) will be slower