触发很慢

时间:2019-05-10 00:48:25

标签: sql triggers

我创建了一个触发器来跟踪历史记录,但是触发器很慢。

我检查了所有内容,但不确定为什么它仍然很慢。

如果您可以给我一些加快操作的想法,我将不胜感激。

此触发器的通用性很强,因此适用于我所有的表。

它将所有更改记录在主记录和详细历史记录表中。

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

0 个答案:

没有答案