(SQL Server 2014 Express)
Hi,
I reference this article: http://msdn.microsoft.com/en-gb/magazine/cc164047.aspx
I have this AFTER INSERT, UPDATE, DELETE trigger to set or update DateCreated, DateModified, and WhoUpdatedID columns in several tables (delete processing to be added later):
CREATE TRIGGER [dbo].[TR_dim_TypeOfClaim_Audit]
ON [dbo].[dim_TypeOfClaim]
AFTER INSERT, UPDATE, DELETE
AS
SET NOCOUNT ON
DECLARE @event_type [char]
--Get Event Type
IF EXISTS(SELECT * FROM inserted)
IF EXISTS(SELECT * FROM deleted)
SELECT @event_type = 'U'
ELSE
SELECT @event_type = 'I'
ELSE
IF EXISTS(SELECT * FROM deleted)
SELECT @event_type = 'D'
ELSE
--no rows affected - cannot determine event
SELECT @event_type = 'K'
IF @event_type = 'I' BEGIN
--Date Created
UPDATE t
SET DateCreated = GETDATE()
FROM INSERTED e
JOIN [dbo].[dim_TypeOfClaim] t ON e.[TypeOfClaimID] = t.[TypeOfClaimID]
;
SELECT @event_type = 'U' --also do UPDATE processing
END
IF @event_type = 'U' BEGIN
--Date Modified
UPDATE t
SET DateModified = GETDATE()
FROM INSERTED e
JOIN [dbo].[dim_TypeOfClaim] t ON e.[TypeOfClaimID] = t.[TypeOfClaimID]
--WhoModifiedID
UPDATE t
SET WhoModifiedID = u.UserID
FROM INSERTED e
JOIN [dbo].[dim_TypeOfClaim] t ON e.[TypeOfClaimID] = t.[TypeOfClaimID]
JOIN [dbo].[dim_Users] u ON u.[Username] = dbo.udfUserName()
END
IF @event_type = 'D' BEGIN
no_op: --Nothing for now
END
GO
The integrity rules for DateCreated, DateModified, and WhoUpdatedID is NOT NULL. Which is technically correct, but are never input by the end user. This causes errors when new records are added.
Should I just change these columns to NULL allowed, or to change the trigger to INSTEAD of? I'm not sure the best practice here.
If it matters, I intend to implement full auditing of all data changes later, either via triggers or change tracking (I need to read up on change tracking to see if it meets my needs).
Thanks for the help...
Update:
@Bogdan: Sorry, my comment wasn't clear. Based on everyone's feedback so far, this is what I currently have:
1) I've left DateCreated, DateModified, and WhoModifiedID as NOT NULL
2) I've created default values as getdate(), getdate(), and 0 respectively. All values are just to get past the NOT NULL constraints for a new record. I suppose one could argue that, with the trigger, the NOT NULL constraint is redundant - the trigger would ensure the values are NOT NULL anyway. I'm a bit unclear in this regard what is best practice. But I don't want these columns to ever be NULL, and the constraint makes this obvious.
3) My current trigger is now:
ALTER TRIGGER [dbo].[TR_dim_InjuryType_Audit]
ON [dbo].[dim_InjuryType]
AFTER INSERT, UPDATE
AS
SET NOCOUNT ON
DECLARE @CurrentUserID INT;
SELECT @CurrentUserID = u.UserID
FROM [dbo].[dim_Users] U
WHERE u.[Username] = dbo.udfUserName()
UPDATE T
SET DateModified = GETDATE(),
WhoModifiedID = @CurrentUserID
FROM INSERTED E
JOIN [dbo].[dim_InjuryType] T ON e.[InjuryTypeID] = t.[InjuryTypeID]
4) BTW, dbo.udfUserName() is merely:
-- =============================================
-- Author: Scott Bass
-- Create date: 04JUL2014
-- Description: Return userid without the domain
-- =============================================
ALTER FUNCTION [dbo].[udfUserName]
(
)
RETURNS varchar(20)
AS
BEGIN
-- Declare the return variable here
DECLARE @UserName varchar(20)
-- Add the T-SQL statements to compute the return value here
SELECT @UserName = substring(suser_sname(),charindex('\',suser_sname())+1,99)
-- Return the result of the function
RETURN @UserName
END
5) Thanks for the hint re: not using EDIT TOP 200 ROWS in SSMS
This is working as I desire. Further comments on improvements/best practice more than welcome, plus will help those that find this thread later.
I'm getting an annoyance in my Access front end that is perhaps related to the triggers but really is a separate subject for a separate post. However, I include this link for completeness, in the chance someone is interested: http://www.utteraccess.com/forum/User-Edited-Record-Sav-t2019558.html