如何在 SQL 服务器的合并复制中将现有触发器更改为与 'not for replication' 一起使用?

How to change existing triggers to be with 'not for replication' in merge replication in SQL Server?

如何制作将数据库中的所有触发器更改为 NOT FOR REPLICATION 的脚本?是否有它的系统过程或者我们需要解析它的定义并注入 NOT FOR REPLICATION?

是的,手动,但首先我会尝试这种方式:

proc [dbo].[db_compare_make_trigger_NOT_FOR_REPLICATION_sp]
as

declare cur cursor fast_forward for
select st.name, definition, is_disabled, OBJECT_NAME(parent_id)
from sys.triggers st join
    sys.sql_modules sm on st.object_id = sm.object_id
where is_ms_shipped = 0 
    and is_not_for_replication = 0
    and parent_id > 0

declare @name nvarchar(127), @definition nvarchar(max), @is_disabled bit, @table nvarchar(127)

open cur

fetch next from cur into @name, @definition, @is_disabled, @table

while @@FETCH_STATUS = 0
begin
    declare @sql nvarchar(max) = null

    declare @name_bckp nvarchar(127) = '__' + @name + N'_' + replace(replace(replace(replace(CONVERT(nvarchar,getdate(), 126), '-', '_'), ':', '_'), '.', '_'), 'T', '_')
    PRINT @NAME + ' ON ' + @table
    set @sql = dbo.RegExReplace(@definition, 'AS\s+BEGIN', ' NOT FOR REPLICATION' + CHAR(13) + CHAR(10) + 'AS' + CHAR(13) + CHAR(10) + 'BEGIN')
    if charindex('NOT FOR REPLICATION', @sql) = 0
        set @sql = dbo.RegExReplace(@definition, 'AS\s+SET NOCOUNT ON', ' NOT FOR REPLICATION' + CHAR(13) + CHAR(10) + 'AS' + CHAR(13) + CHAR(10) + 'SET NOCOUNT ON')
    if charindex('NOT FOR REPLICATION', @sql) > 0
    begin try
        --BCKP it
        exec sys.sp_rename @NAME, @name_bckp
        set @definition = 'DISABLE TRIGGER [' + @name_bckp + '] ON [' + @table + ']'
        execute sp_executesql @definition
        --create it
        execute sp_executesql @sql
        --set previous state
        if @is_disabled = 1
            set @definition = 'DISABLE TRIGGER [' + @NAME + '] ON [' + @table + ']'
        else
            set @definition = 'ENABLE TRIGGER [' + @NAME + '] ON [' + @table + ']'
        execute sp_executesql @definition
        set @definition = 'DROP TRIGGER [' + @name_bckp + ']'
        execute sp_executesql @definition
        print 'DONE!'
    end try
    begin catch 
        declare @msg nvarchar(4000) = ERROR_MESSAGE()
        declare @esv int = error_severity()
        declare @est int = error_state()
        declare @lin int = error_line()

        insert into db_log (dateCreated, msg, Level, State, Line, additional)
        values(getdate(), @msg, @esv, @est, @lin, @NAME)
        print 'ERROR check db_log: ' + @msg
    end catch

    fetch next from cur into @name, @definition, @is_disabled, @table
end
close cur
deallocate cur

并且仍然是我手动执行的触发器。

为此,您需要: CLR Assembly RegEx Functions for SQL Server