使用out游标的SQL Server触发器操作

时间:2016-12-07 23:04:26

标签: sql sql-server cursor

我有一个场景,我必须在每次DML操作后生成SQL脚本。我们有一个触发器,在每次插入,更新,删除后运行。

它主要从Inserted / Deleted表中获取数据,并为每一行生成一个SQL脚本,并执行插入另一个表的操作。

例如,如果我们插入

  1. 获取所有插入的值
  2. 打开游标
  3. 对于每个插入的行,生成一个SQL脚本,该脚本将插入到另一个表中以用于审计目的
  4. 关闭游标。
  5. 对于10,000行5列,此触发器需要大约4-5小时。列为intdatevarchar(100)

    我们正在尝试更换触发器。需要有相同的建议。

    Set @syncScript = 'Insert Into table('
    
                Declare insertCursor Cursor Local Forward_Only For
                Select a, b, c From Inserted
    
                Open insertCursor
    
                Fetch Next From insertCursor Into @a, @b, @c
    
                While (@@Fetch_Status = 0)
                Begin
                    Declare @valuesList varchar(max)
    
                    Set @columnList = ''
                    Set @paramsList = '['
                    Set @valuesList = ''
    
                    Select @columnList = @columnList + 'col6, ', @paramsList = @paramsList + '''' + COALESCE(dbo.ConvertFloatToVarchar(col6), 'NULL') + ''', ', @valuesList = @valuesList + '?, ' From Inserted I Where I.a= @a And I.b= @b And I.c= @c And 1 = 1
                    Select @columnList = @columnList + 'col5, ', @paramsList = @paramsList + '''' + COALESCE(Convert(varchar(max), col5), 'NULL') + ''', ', @valuesList = @valuesList + '?, ' From Inserted I Where I.a= @a And I.b= @b And I.c= @c And 1 = 1
                    Select @columnList = @columnList + 'col4, ', @paramsList = @paramsList + '''' + COALESCE(Convert(varchar(max), col4), 'NULL') + ''', ', @valuesList = @valuesList + '?, ' From Inserted I Where I.a= @a And I.b= @b And I.c= @c And 1 = 1
                    Select @columnList = @columnList + 'col3, ', @paramsList = @paramsList + '''' + COALESCE(Convert(varchar(max), col3), 'NULL') + ''', ', @valuesList = @valuesList + '?, ' From Inserted I Where I.a= @a And I.b= @b And I.c= @c And 1 = 1
                    Select @columnList = @columnList + 'col2, ', @paramsList = @paramsList + '''' + COALESCE(Convert(varchar(max), col2), 'NULL') + ''', ', @valuesList = @valuesList + '?, ' From Inserted I Where I.a= @a And I.b= @b And I.c= @c And 1 = 1
                    Select @columnList = @columnList + 'col1, ', @paramsList = @paramsList + '''' + COALESCE(Convert(varchar(max), col1), 'NULL') + ''', ', @valuesList = @valuesList + '?, ' From Inserted I Where I.TraitValueMemberId = @a And I.ValueSetId = @b And I.LanguageCulture = @c And 1 = 1
    
                    Set @columnList = SUBSTRING(@columnList, 1, Len(@columnList) - 1) + ') Values ('
                    Set @valuesList = SUBSTRING(@valuesList, 1, Len(@valuesList) - 1) + ')'
                    Set @paramsList = @paramsList + ']'
                    Set @bigScript = (COALESCE(@syncScript, '') + COALESCE(@columnList, '') + COALESCE(@valuesList, ''))
    
    
    
                                Insert Into Log (CreatedDate, [Message]) Select GetDate(), 'tablename INSERT syncScript = ' + @bigScript +'paramsList = ' + COALESCE(@paramsList, '')
    
                    Insert Into [dbo].[LogAudit] (GuidId, Query, Params, TableName, CreatedDate, Operation, UserId)
                    Values ('00000000-0000-0000-0000-000000000000', @bigScript, @paramsList, @table, GetDate(), @operation, @debugUser)
    
                    Fetch Next From insertCursor Into @a, @b, @c
                End
    
                Close insertCursor
                Deallocate insertCursor
    

    如果是更新,我们会在插入和删除的表中加入,以生成如上所示的更新脚本。

1 个答案:

答案 0 :(得分:0)

我使用SET Operation而不是Trigger

解决了这个问题
INSERT Into [dbo].[LogAudit] (GuidId, Query, Params, TableName, CreatedDate, Operation, UserId)
            SELECT '00000000-0000-0000-0000-000000000000',  
                 'INSERT INTO Table(col6, col5, col4, col3, col2, col1) VALUES (?, ?, ?, ?, ?, ?)', 
            '[' +   '''' + COALESCE(dbo.ConvertFloatToVarchar(col6), 'NULL') + ''','  + '''' + COALESCE(Convert(varchar(max), col5), 'NULL') + ''', ' +  '''' + COALESCE(Convert(varchar(max), col4), 'NULL') + ''', ' + '''' + COALESCE(Convert(varchar(max), col3), 'NULL') + ''', ' + '''' + COALESCE(Convert(varchar(max), col2), 'NULL') + ''', ' +  '''' + COALESCE(Convert(varchar(max), col1), 'NULL') + ''', ' + ']', @table, GetDate(), @operation, @debugUser FROM Inserted

            -- Insert into Log
            Insert Into Log (CreatedDate, [Message]) Select GetDate(), 'MTDE_TraitValueMemberByLanguage_Sync INSERT 
                    syncScript = INSERT Into [dbo].[LogAudit (GuidId, Query, Params, TableName, CreatedDate, Operation, UserId) VALUES VALUES (?, ?, ?, ?, ?, ?)' + 
                    'paramsList = '  +  '[' +   '''' + COALESCE(dbo.ConvertFloatToVarchar(col6), 'NULL') + ''','  + '''' + COALESCE(Convert(varchar(max), col5), 'NULL') + ''', ' +  '''' + COALESCE(Convert(varchar(max), col4), 'NULL') + ''', ' + '''' + COALESCE(Convert(varchar(max), col3), 'NULL') + ''', ' + '''' + COALESCE(Convert(varchar(max), col2), 'NULL') + ''', ' +  '''' + COALESCE(Convert(varchar(max), col1), 'NULL') + ''', ' + ']' FROM Inserted