如何在 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
并且仍然是我手动执行的触发器。
如何制作将数据库中的所有触发器更改为 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
并且仍然是我手动执行的触发器。