Hi,
I have trigger will do insert in to audit table if any DML like Insert,Update and Delete.
But Some times the audit table is missing data is nothing but trigger fails.
So I have added TRY/CATCH to trigger and sending email with errormessage() like this ..
GO /****** Object: Trigger [dbo].[tr_trigtest_t_TaskMaster] Script Date: 05/03/2014 15:35:46 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER TRIGGER [dbo].[tr_trigtest_t_TaskMaster] ON [dbo].[t_TaskMaster] FOR INSERT ,UPDATE ,DELETE AS DECLARE @bit INT ,@field INT ,@maxfield INT ,@char INT ,@fieldname VARCHAR(128) ,@TableName VARCHAR(128) ,@PKCols VARCHAR(1000) ,@sql VARCHAR(2000) ,@UpdateDate VARCHAR(21) ,@UserName VARCHAR(128) ,@Type CHAR(1) ,@PKSelect VARCHAR(1000) BEGIN TRY --You will need to change @TableName to match the table to be audited RAISERROR('Error', 16, 1) SELECT @TableName = 't_TaskMaster' -- date and user SELECT @UpdateDate = CONVERT(VARCHAR(8), GETDATE(), 112) + ' ' + CONVERT(VARCHAR(12), GETDATE(), 114) -- Action IF EXISTS ( SELECT * FROM INSERTED ) IF EXISTS ( SELECT * FROM DELETED ) SELECT @Type = 'U' ELSE SELECT @Type = 'I' ELSE SELECT @Type = 'D' -- get list of columns SELECT * INTO #ins FROM inserted SELECT * INTO #del FROM DELETED IF @Type = 'I' OR @Type = 'U' SELECT @UserName = ModifiedBy FROM #ins IF @Type = 'D' SELECT @UserName = updatedby FROM #del -- Get primary key columns for full outer join SELECT @PKCols = COALESCE(@PKCols + ' and', ' on') + ' i.' + c.COLUMN_NAME + ' = d.' + c.COLUMN_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,INFORMATION_SCHEMA.KEY_COLUMN_USAGE c WHERE pk.TABLE_NAME = @TableName AND CONSTRAINT_TYPE = 'PRIMARY KEY' AND c.TABLE_NAME = pk.TABLE_NAME AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME -- Get primary key select for insert SELECT @PKSelect = COALESCE(@PKSelect + '+', '') + '''<' + COLUMN_NAME + '=''+convert(varchar(100),coalesce(i.' + COLUMN_NAME + ',d.' + COLUMN_NAME + '))+''>''' FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,INFORMATION_SCHEMA.KEY_COLUMN_USAGE c WHERE pk.TABLE_NAME = @TableName AND CONSTRAINT_TYPE = 'PRIMARY KEY' AND c.TABLE_NAME = pk.TABLE_NAME AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME IF @PKCols IS NULL BEGIN RAISERROR ( 'no PK on table %s' ,16 ,- 1 ,@TableName ) RETURN END SELECT @field = 0 ,@maxfield = MAX(ORDINAL_POSITION) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TableName WHILE @field < @maxfield BEGIN BEGIN TRY SELECT @field = MIN(ORDINAL_POSITION) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TableName AND ORDINAL_POSITION > @field SELECT @bit = (@field - 1) % 8 + 1 SELECT @bit = POWER(2, @bit - 1) SELECT @char = ((@field - 1) / 8) + 1 IF SUBSTRING(COLUMNS_UPDATED(), @char, 1) & @bit > 0 OR @Type IN ( 'I' ,'D' ) BEGIN SELECT @fieldname = COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TableName AND ORDINAL_POSITION = @field SELECT @sql = 'insert t_Audit ( Type, TableName, PK, FieldName, OldValue, NewValue, UpdateDate, UserName)select ''' + @Type + ''',''' + @TableName + ''',' + @PKSelect + ',''' + @fieldname + '''' + ',convert(varchar(1000),d.' + @fieldname + ')' + ',convert(varchar(1000),i.' + @fieldname + ')' + ',''' + @UpdateDate + '''' + ',''' + @UserName + '''' + ' from #ins i full outer join #del d' + @PKCols + ' where i.' + @fieldname + ' <> d.' + @fieldname + ' or (i.' + @fieldname + ' is null and d.' + @fieldname + ' is not null)' + ' or (i.' + @fieldname + ' is not null and d.' + @fieldname + ' is null)' EXEC (@sql) END END TRY BEGIN CATCH DECLARE @Content1 AS VARCHAR(1000) = error_message() + @PKCols + @fieldname + @PKSelect EXEC sp_Email 'emailid@gmail.com' ,'' ,'Error at insertion of Audit ' ,@Content1 END CATCH END END TRY BEGIN CATCH DECLARE @Content AS VARCHAR(1000) = error_message() + @PKCols + @fieldname + @PKSelect EXEC sp_Email 'emailid@gmail.com' ,'' ,'Error at insertion of Audit ' ,@Content END CATCH
For the testing trigger , I have added a line at starting.
RAISERROR('Error', 16, 1)
But When I update a table "update t_TaskMaster SET Remarks='Test Remark' WHERE id='346882'" , it is giving an error.
Msg 3930, Level 16, State 1, Procedure sp_send_dbmail, Line 64
The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.
Please help me to send a email when catch the error.
Thank you.