Quantcast
Channel: Transact-SQL forum
Viewing all articles
Browse latest Browse all 23857

Trigger - The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.

$
0
0

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.


Viewing all articles
Browse latest Browse all 23857

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>