我创建了一个触发器来跟踪历史记录,但是触发器很慢。
我检查了所有内容,但不确定为什么它仍然很慢。
如果您可以给我一些加快操作的想法,我将不胜感激。
此触发器的通用性很强,因此适用于我所有的表。
它将所有更改记录在主记录和详细历史记录表中。
CREATE TRIGGER [dbo].[ADM_Gate_CT]
ON [dbo].[ADM_Gate]
FOR INSERT, UPDATE, DELETE
AS
DECLARE @field INT,
@mfield INT,
@fname VARCHAR(128),
@TName VARCHAR(128),
@PKC VARCHAR(MAX),
@sql NVARCHAR(MAX),
@Type NVARCHAR(1),
@PKV VARCHAR(MAX),
@MId NVARCHAR(MAX) = '0',
@TID NVARCHAR(MAX),
@C NVARCHAR(MAX) = '0'
SELECT
@TName = 'ADM_Gate', @TID = itemid
FROM
cnf_lookup
WHERE
lookuptableid = 35
AND description = 'ADM_Gate'
IF EXISTS (SELECT * FROM CNF_HIL_Tables
WHERE referencetable = @TID AND Active = 1)
BEGIN
IF EXISTS (SELECT * FROM inserted)
IF EXISTS (SELECT * FROM deleted)
SELECT @Type = '2'
ELSE
SELECT @Type = '3'
ELSE
SELECT @Type = '1'
SELECT *
INTO #ins
FROM inserted
SELECT *
INTO #del
FROM deleted
SELECT
@PKC = COALESCE(@PKC + ' and', ' on') + ' i.' + c.COLUMN_NAME + ' = d.' + c.COLUMN_NAME, @PKV = coalesce(@PKV+'+','') + 'convert(varchar(100), coalesce(i.' + COLUMN_NAME + ',d.' + COLUMN_NAME + '))'
FROM
INFORMATION_SCHEMA.TABLE_CONSTRAINTS p
INNER JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c ON c.CONSTRAINT_NAME = p.CONSTRAINT_NAME AND c.TABLE_NAME = p.TABLE_NAME
WHERE
p.TABLE_NAME = @TName AND CONSTRAINT_TYPE = 'PRIMARY KEY'
SELECT
@field = 0, @mfield = MAX(ORDINAL_POSITION)
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = @TName
WHILE @field < @mfield
BEGIN
SELECT @field = MIN(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TName AND ORDINAL_POSITION > @field
SELECT @fname = COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TName AND ORDINAL_POSITION = @field
IF EXISTS (SELECT * FROM CNF_Hil_Columns C
INNER JOIN CNF_HIL_Tables T ON T.TablesId = C.TablesId
WHERE T.referencetable = @TID
AND C.ColumnName = @fname AND C.Active = 1)
BEGIN
SELECT @sql = 'if exists(select * from #ins i full outer join #del d ' + @PKC
SELECT @sql = @sql + ' where i.' + @fname + ' is not null and i.' + @fname + ' <> d.' + @fname + ' or (i.' + @fname + ' is null and d.' + @fname + ' is not null) or (i.' + @fname + ' is not null and d.' + @fname + ' is null)) set @C=1'
EXECUTE sp_executesql @sql, N'@C nvarchar(max) OUTPUT', @C OUTPUT
IF @c = 1
BREAK
END
END
IF @c = 1
BEGIN
SET @field = 0
WHILE @field < @mfield
BEGIN
SELECT @field = MIN(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TName AND ORDINAL_POSITION > @field
SELECT @fname = COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TName AND ORDINAL_POSITION = @field
IF EXISTS (SELECT * FROM CNF_Hil_Columns C
INNER JOIN CNF_HIL_Tables T ON T.TablesId = C.TablesId
WHERE T.referencetable = @TID
AND C.ColumnName = @fname AND C.Active = 1)
BEGIN
IF @MId = 0
BEGIN
SELECT @sql = 'insert DATA_HIL_Master (OperationType, ReferenceTable, ReferenceId, UserId, WorkstationId, InsDateTime)'
SELECT @sql = @sql + ' select ''' + @Type + ''''
SELECT @sql = @sql + ', ''' + @TID + ''''
SELECT @sql = @sql + ',' + @PKV
SELECT @sql = @sql + ', CONVERT(VARCHAR(1000), i.Last_UserId_Log), CONVERT(VARCHAR(1000), i.Last_WorkstationId_Log), CONVERT(VARCHAR(1000),i.Last_DateTime_Log)'
SELECT @sql = @sql + ' from #ins i full outer join #del d'
SELECT @sql = @sql + @PKC
SELECT @sql = @sql + ' SELECT @MId = SCOPE_IDENTITY()'
EXECUTE sp_executesql @sql, N'@MId nvarchar(max) OUTPUT', @MId OUTPUT
END
IF @Type <> '1'
BEGIN
SELECT @sql = 'insert data_HIL_Detail (MasterId, OriginalValue, ModifiedValue, ColumnName)'
SELECT @sql = @sql + ' select convert(varchar(1000),' + @MId + '), convert(varchar(1000),d.' + @fname + '), convert(varchar(1000),i.' + @fname + ')'
SELECT @sql = @sql + ',''' + @fname + ''''
SELECT @sql = @sql + ' from #ins i full outer join #del d ' + @PKC
SELECT @sql = @sql + ' where i.' + @fname + ' is not null and i.' + @fname + ' <> d.' + @fname + ' or (i.' + @fname + ' is null and d.' + @fname + ' is not null) or (i.' + @fname + ' is not null and d.' + @fname + ' is null)'
EXECUTE sp_executesql @sql
END
END
END
END
END