1. 程式人生 > >SqlServer 使用腳本創建分發服務及事務復制的可更新訂閱

SqlServer 使用腳本創建分發服務及事務復制的可更新訂閱

ltrim mssq msdn initial nts schema 存儲 esc serve

原文:SqlServer 使用腳本創建分發服務及事務復制的可更新訂閱

【創建使用本地分發服務器】

/************************【使用本地分發服務器配置發布】***********************/  
--  SqlServer 2008 R2  
--  https://technet.microsoft.com/zh-cn/library/ms151860(v=sql.105).aspx  
use master  
go  
  
--  服務器上是否已安裝分發服務器  
--  https://msdn.microsoft.com/zh-cn/library/ms190339(v=sql.105).aspx  
exec master.dbo.sp_get_distributor  
go  
  
--  配置分發服務器  
--  https://msdn.microsoft.com/zh-cn/library/ms176028(v=sql.105).aspx  
exec master.dbo.sp_adddistributor   
 @distributor = 'KK-PC'    --分發服務器名稱  
,@heartbeat_interval = 10       --代理在不記錄進度消息的情況下可以運行的最長分鐘數  
,@password = N'123456'  --分發服務器密碼  
go  
  
--  配置分發數據庫  
--  https://msdn.microsoft.com/zh-cn/library/ms189755(v=sql.105).aspx  
exec master.dbo.sp_adddistributiondb   
 @database = N'distribution'    --要創建的分發數據庫的名稱  
,@data_folder = N'E:\TempFile\Distribution' --分發數據庫數據文件的目錄  
,@data_file = N'distribution'   --數據庫文件的名稱  
,@data_file_size = 5            --初始數據文件大小,以兆字節 (MB) 為單位  
,@log_folder = N'E:\TempFile\Distribution' ----分發數據庫日誌文件的目錄  
,@log_file = N'distribution_log'   
,@log_file_size =  5            --初始日誌文件大小,以兆字節 (MB) 為單位   
,@min_distretention = 0         --從分發數據庫中刪除事務前的最小保持期,以小時為單位  
,@max_distretention = 72        --刪除事務前的最大保持期,以小時為單位   
,@history_retention = 48        --歷史記錄的保留時間,以小時為單位   
,@security_mode = 1             --同步時連接到分發服務器的安全模式。默認值為1:Windows驗證,0: SQL驗證   
,@login = N'KK-PC\SqlReplicator'   
,@password = N'123456'   
,@createmode = 1                --1:創建或使用現有數據庫(instdist.sql)   
go  
  
--  配置發布服務器以使用指定的分發數據庫  
--  https://msdn.microsoft.com/zh-cn/library/ms173807(v=sql.105).aspx  
exec master.dbo.sp_adddistpublisher   
 @publisher = N'KK-PC'         --發布服務器的名稱  
,@distribution_db = N'distribution' --分發數據庫的名稱   
,@security_mode = 1                 --安全模式,默認1:Windows驗證,0: SQL驗證   
,@login = N'KK-PC\SqlReplicator'   
,@password = N'123456'   
,@working_directory = N'E:\TempFile\ReplData'--默認快照文件夾的UNC共享目錄  
,@thirdparty_flag  = 0              --發布服務器是否是SQLServer,默認0:是,1:否  
,@publisher_type  = N'MSSQLSERVER'  --發布服務器類型:MSSQLSERVER(默認)/ORACLE/ORACLE GATEWAY  
go  
  
/*****配置完成!!*****/  


/*****【查看分發屬性】******/

--	檢查分發數據庫目錄
exec master.dbo.xp_subdirs N'E:\TempFile\Distribution'

--	發布服務器的屬性(在分發服務器任何數據庫執行)
--	https://technet.microsoft.com/zh-cn/library/ms190323(v=sql.105).aspx
exec master.dbo.sp_helpdistpublisher N'KK-PC'

--	分發數據庫的屬性(在分發服務器的分發數據庫上執行)
--	https://msdn.microsoft.com/zh-cn/library/vstudio/aa238917.aspx
exec master.dbo.sp_helpdistributiondb N'distribution'

--	列出有關分發服務器相關信息(在分發服務器任何數據庫執行)
--	https://msdn.microsoft.com/zh-cn/library/ms177504(v=sql.105).aspx
exec master.dbo.sp_helpdistributor



/*****【刪除分發】******/
--這裏不必執行!


--	刪除分發發布服務器(在分發服務器任何數據庫執行)
--	https://technet.microsoft.com/zh-cn/library/ms188411(v=sql.105).aspx
exec master.dbo.sp_dropdistpublisher @publisher =  N'KK-PC',@no_checks = 0,@ignore_distributor = 0 --檢查對象;連接分發;

--	刪除分發數據庫(在分發服務器任何數據庫執行)
--	https://msdn.microsoft.com/zh-cn/library/ms188355(v=sql.105).aspx
exec master.dbo.sp_dropdistributiondb N'distribution';

--	卸載分發服務器(除分發數據庫之外的任何數據庫中執行)
--	https://technet.microsoft.com/zh-cn/library/ms173516(v=sql.105).aspx
exec master.dbo.sp_dropdistributor @no_checks = 0,@ignore_distributor = 0 --檢查對象;連接分發;


技術分享圖片



【創建可更新訂閱的事務發布】


/*************************************【創建發布】**************************************/
/*【實例:可更新訂閱】

* A 為發布數據庫,id為每個表的主鍵
* B,C 為訂閱數據庫
* A中符合條件 [id % 2 = 0] 的同步到B中
* A中符合條件 [id % 2 = 1] 的同步到C中
* 以下以 B 創建發布訂閱
	
  當前發布數據庫:[mytest]
  當前訂閱數據庫:[mytestA]
  
  
*/



--	作為發布的數據庫
use [mytest]

--	設置指定數據庫的復制數據庫選項(發布服務器或訂閱服務器執行)
--	http://msdn.microsoft.com/zh-cn/library/ms188769.aspx
exec sys.sp_replicationdboption @dbname = N'mytest', @optname = N'publish', @value = N'true'
go


--	為給定分發服務器添加隊列讀取器代理(在分發庫或發布庫執行)(每個實例默認只1個,已存在可不須再執行)
--	http://msdn.microsoft.com/ZH-CN/LIBRARY/ms189517
exec sys.sp_addqreader_agent @job_login = N'KK-PC\SqlReplicator', @job_password = N'123456', @job_name = null, @frompublisher = 1
go


--	為給定數據庫添加日誌讀取器代理(在發布數據庫執行)(每個數據庫默認只1個,已存在可不須再執行)
--	http://technet.microsoft.com/zh-cn/library/ms189516.aspx
exec sys.sp_helplogreader_agent @publisher = null --查看當前數據庫存在的日誌代理
exec sys.sp_addlogreader_agent @job_login = N'KK-PC\SqlReplicator', @job_password = N'123456', @publisher_security_mode = 1, @job_name = null
go


/***************************【創建發布:以下用於1庫多發布】******************************/

--	添加(可更新訂閱)事務發布(在發布數據庫執行)
--	http://msdn.microsoft.com/zh-cn/library/ms188738(v=sql.100).aspx
exec sys.sp_addpublication 
@publication = N'tran_repl',		--【指定發布名稱】
@description = N'來自發布服務器“”的數據庫“mytest”的具有可更新訂閱的事務發布。', 
@sync_method = N'concurrent',			--同步模式:本機模式大容量復制程序輸出
@retention = 0,							--訂閱活動的保持期(小時):默認值為336小時;0:訂閱永不過期
@allow_push = N'true',					--推送訂閱 
@allow_pull = N'true',					--允許創建請求訂閱
@allow_anonymous = N'false',			--不可創建匿名訂閱 
@enabled_for_internet = N'false',		--非Internet發布
@snapshot_in_defaultfolder = N'false',	--不指定快照默認文件夾,須設置@alt_snapshot_folder
@alt_snapshot_folder = N'E:\TempFile\ReplData',	--指定快照的備用文件夾的位置
@compress_snapshot = N'false',			--不壓縮快照
@ftp_port = 21,							--默認分發服務器的FTP服務的端口號:21
@ftp_login = N'anonymous',				--默認用於連接到 FTP 服務的用戶名:anonymous
@allow_subscription_copy = N'false',	--禁用復制訂閱此發布的訂閱數據庫
@add_to_active_directory = N'false',	--(已不推薦使用)
@repl_freq = N'continuous',				--復制頻率的類型:基於日誌的事務的輸出
@status = N'active',					--發布數據可立即用於訂閱服務器
@independent_agent = N'true',			--【獨立分發代理】
@immediate_sync = N'false',				--每次運行快照代理時不為發布創建同步文件
@allow_sync_tran = N'true',				--允許使用【立即更新訂閱】
@autogen_sync_procs = N'true',			--在發布服務器上生成更新訂閱的【同步存儲過程】
@allow_queued_tran = N'true',			--在訂閱服務器中啟用更改的隊列
@allow_dts = N'false',					--不允許數據轉換
@conflict_policy = N'sub wins',			--排隊更新訂閱服務器選項時所遵從的沖突解決策略:【訂閱入選】
@centralized_conflicts = N'true',		--在發布服務器上存儲沖突記錄
@conflict_retention = 14,				--沖突保持期(天)
@queue_type = N'sql',					--使用的隊列類型:默認SQL Server存儲事務
@replicate_ddl = 1,						--【支持架構復制】
@allow_initialize_from_backup = N'false', --不允許用備份初始化訂閱
@enabled_for_p2p = N'false',			--非對等復制
@enabled_for_het_sub = N'false'			--只支持SQL Server訂閱服務器
go


--	為指定的發布創建快照代理(在發布數據庫執行)
--	http://msdn.microsoft.com/zh-cn/library/ms174958(v=sql.100)
exec sys.sp_addpublication_snapshot 
@publication = N'tran_repl',
@frequency_type = 1,
@frequency_interval = 0,
@frequency_relative_interval = 0,
@frequency_recurrence_factor = 0,
@frequency_subday = 0, 
@frequency_subday_interval = 0, 
@active_start_time_of_day = 0, 
@active_end_time_of_day = 235959, 
@active_start_date = 0, 
@active_end_date = 0, 
@job_login = N'KK-PC\SqlReplicator', 
@job_password = N'123456', 
@publisher_security_mode = 1
go


--	更改發布屬性
--	https://msdn.microsoft.com/zh-cn/library/ms188413(v=sql.105).aspx
--	exec sys.sp_changepublication ……



技術分享圖片

--	創建項目並將其添加到發布中(在發布數據庫執行)
--	http://msdn.microsoft.com/zh-cn/library/ms173857

/*1. 添加可篩選的表(默認架構dbo)*/
declare @tableName			nvarchar(100)
declare @publName			nvarchar(100)
declare @mark				bit			-- 區分是否有sid的列,有則進行篩選
declare @filterNum			nvarchar(10)-- 一個數據庫多個發布加編號區別
declare @filterClause		nvarchar(100)
declare @SQLaddarticle		nvarchar(max)
declare @SQLarticlefilter	nvarchar(max)
declare @SQLarticleview		nvarchar(max)
set @publName = N'tran_repl' --	【指定發布名稱】
set @filterClause = N'dbo.f_SIDTOInt(SID) % 2 = 0' --	【指定行篩選】
select @filterNum = CONVERT(NVARCHAR(10),count(*)) from distribution.dbo.MSpublications
declare cur_addTable cursor local fast_forward
for 
	/*有主鍵 並且 有SID列(用於篩選)*/
	select name,1 mark from sys.tables t1(nolock) where is_ms_shipped = 0
	and exists(select 1 from sys.columns t2(nolock) where t1.object_id=t2.object_id and t2.name='SID')
	and name in(select table_name from information_schema.key_column_usage(nolock) 
		where objectproperty(object_id(constraint_name),'isprimarykey')=1 )
	union all
	/*有主鍵 並且 無SID列(不可篩選)*/
	select name,0 mark from sys.tables t1(nolock) where is_ms_shipped = 0
	and not exists(select 1 from sys.columns t2(nolock) where t1.object_id=t2.object_id and t2.name='SID')
	and name in(select table_name from information_schema.key_column_usage (nolock)
		where objectproperty(object_id(constraint_name),'isprimarykey')=1 )
open cur_addTable
fetch next from cur_addTable into @tableName,@mark
while @@fetch_status = 0
begin
	if ( @mark = 1 ) /*可篩選的表對象*/
	begin
		set @SQLaddarticle = N'
		exec sp_addarticle 
		@publication = N'''+@publName+''', 
		@article = N'''+@tableName+''', 
		@source_owner = N''dbo'', 
		@source_object = N'''+@tableName+''', 
		@type = N''logbased'', 
		@description = null, 
		@creation_script = null, 
		@pre_creation_cmd = N''drop'', 
		@schema_option = 0x0000000008035CDF, 
		@identityrangemanagementoption = N''none'', 
		@destination_table = N'''+@tableName+''', 
		@destination_owner = N''dbo'', 
		@status = 24,
		@vertical_partition = N''false'''
		exec(@SQLaddarticle)
		/*添加項目篩選器*/
		set @SQLarticlefilter = N' 
		exec sp_articlefilter 
		@publication = N'''+@publName+''', 
		@article = N'''+@tableName+''', 
		@filter_name = N''FLTR_'+@tableName+'_'+@filterNum+'__'+rtrim(ltrim(str(@@spid)))+''', 
		@filter_clause = N'''+@filterClause+''', 
		@force_invalidate_snapshot = 1, 
		@force_reinit_subscription = 1'
		exec(@SQLarticlefilter)
		/*添加項目同步對象*/
		set @SQLarticleview = N'
		exec sp_articleview 
		@publication = N'''+@publName+''', 
		@article = N'''+@tableName+''', 
		@view_name = N''SYNC_'+@tableName+'_'+@filterNum+'__'+rtrim(ltrim(str(@@spid)))+''', 
		@filter_clause = N'''+@filterClause+''', 
		@force_invalidate_snapshot = 1, 
		@force_reinit_subscription = 1'
		exec(@SQLarticleview)
		print '已篩選:'+@tableName
	end
	else if ( @mark = 0 )
	begin
		set @SQLaddarticle = N'
		exec sp_addarticle 
		@publication = N'''+@publName+''', 
		@article = N'''+@tableName+''', 
		@source_owner = N''dbo'', 
		@source_object = N'''+@tableName+''', 
		@type = N''logbased'', 
		@description = null, 
		@creation_script = null, 
		@pre_creation_cmd = N''drop'', 
		@schema_option = 0x0000000008035CDF, 
		@identityrangemanagementoption = N''none'', 
		@destination_table = N'''+@tableName+''', 
		@destination_owner = N''dbo'', 
		@status = 24,
		@vertical_partition = N''false'''
		exec(@SQLaddarticle)
		print '無篩選:'+@tableName
	end
	fetch next from cur_addTable into @tableName,@mark
end
close cur_addTable
deallocate cur_addTable



/*2. 添加視圖/存儲過程/函數對象(默認架構dbo)*/
declare @publName		nvarchar(100)
declare @ObjectName		nvarchar(100)
declare @Type			nvarchar(30)
declare @ObjectType		nvarchar(30)
declare @SQLaddObject	nvarchar(max)
set @publName = N'tran_repl' --	【指定發布名稱】
declare cur_addObject cursor local fast_forward
for select name,type from mytest.sys.objects where type in(N'P') and is_ms_shipped = 0
	union all
	select name,type from mytest.sys.objects a where type in(N'V') and is_ms_shipped = 0
	and exists(select 1 from mytest.sys.sql_modules b where a.object_id=b.object_id and is_schema_bound = 0)
	union all
	select name,N'B' as type from mytest.sys.objects a where type in(N'V') and is_ms_shipped = 0 
	and exists(select 1 from sys.sql_modules b where a.object_id=b.object_id and is_schema_bound = 1)/*架構綁定的索引視圖*/
	union all
	select name,type from mytest.sys.objects where type in(N'TF',N'FN') and is_ms_shipped = 0
	order by type,name
open cur_addObject
fetch next from cur_addObject into @ObjectName,@ObjectType
while @@fetch_status = 0
begin
	SET @Type = 
	(
		CASE 
		WHEN @ObjectType = N'V' THEN N'view schema only'
		WHEN @ObjectType = N'B' THEN N'indexed view schema only'
		WHEN @ObjectType = N'P' THEN N'proc schema only'
		WHEN @ObjectType in(N'TF',N'FN') THEN N'func schema only'
		END
	)
	set @SQLaddObject = N'
	exec sp_addarticle 
	@publication = N'''+@publName+''', 
	@article = N'''+@ObjectName+''', 
	@source_owner = N''dbo'', 
	@source_object = N'''+@ObjectName+''', 
	@type =  N'''+@Type+''', 
	@description = null, 
	@creation_script = null, 
	@pre_creation_cmd = N''drop'', 
	@schema_option = 0x0000000008000001, 
	@status = 16,
	@destination_owner = N''dbo'', 
	@destination_table = N'''+@ObjectName+''''
	exec(@SQLaddObject)
	print @ObjectType+ ':' + @ObjectName
	fetch next from cur_addObject into @ObjectName,@ObjectType
end
close cur_addObject
deallocate cur_addObject
技術分享圖片技術分享圖片


【創建訂閱】

		
/***********************************【創建訂閱】***************************************/
/*【要在發布服務器上運行的腳本】*/

use [mytest]

--	將訂閱添加到發布並設置訂閱服務器的狀態
--	(警告: distribution 代理作業隱式創建,並將在 SQL Server 代理服務帳戶下運行)
--	http://technet.microsoft.com/zh-cn/library/ms181702(v=sql.100).aspx
exec sys.sp_addsubscription 
@publication = N'tran_repl',	--指定發布名稱
@subscriber = N'KK-PC',		--訂閱服務器
@destination_db = N'mytestA',--訂閱數據庫
@subscription_type = N'Push',		--推送訂閱
@sync_type = N'automatic',			--默認,已發布表的架構和初始數據將首先傳輸到訂閱服務器
@article = N'all',					--發布所訂閱的項目
@update_mode = N'queued failover',	--將訂閱啟用為排隊更新訂閱,並允許更改為立即更新模式
@subscriber_type = 0				--訂閱服務器的類型:SQL Server訂閱服務器
go

--	添加新的預定分發代理作業,以使推送訂閱與事務發布同步
--	http://msdn.microsoft.com/zh-cn/library/ms175006(v=SQL.100)
exec sys.sp_addpushsubscription_agent 
@publication = N'tran_repl',	--指定發布名稱
@subscriber = N'KK-PC',			--訂閱服務器
@subscriber_db = N'mytestA',	--訂閱數據庫
@job_login = N'KK-PC\SqlReplicator', 
@job_password = N'123456', 
@subscriber_security_mode = 1,			--Windows 身份驗證
@frequency_type = 64,					--分發代理計劃的頻率:自動啟動(默認)
@frequency_interval = 1, 
@frequency_relative_interval = 1, 
@frequency_recurrence_factor = 0, 
@frequency_subday = 4, 
@frequency_subday_interval = 5, 
@active_start_time_of_day = 0, 
@active_end_time_of_day = 235959, 
@active_start_date = 0, 
@active_end_date = 0, 
@dts_package_location = N'Distributor'
go


/*【要在訂閱服務器上運行的腳本】*/

use mytestA

--	設置在連接到發布服務器時立即更新訂閱的同步觸發器所使用的配置和安全信息
--	http://msdn.microsoft.com/zh-cn/library/ms174991(v=sql.100).aspx
exec sys.sp_link_publication 
@publisher = N'KK-PC', 
@publisher_db = N'mytest', 
@publication = N'tran_repl', 
@distributor = N'KK-PC', 
@security_mode = 1,		--SQL Server 身份驗證或 Windows 身份驗證
@login = N'KK-PC\SqlReplicator', 
@password = N'123456'
go



【啟動快照並初始化】

/**********************************【啟動快照並初始化】**************************************/
--	發布服務器發布數據
use [mytest]

--	對其請求訂閱中的新項目的訂閱添加到發布中(在發布服務器的發布數據庫中執行)
--	https://technet.microsoft.com/zh-cn/library/ms181680(v=sql.100).aspx
--	exec sys.sp_refreshsubscriptions @publication = N'tran_repl'


--	將訂閱標記為要重新初始化
--	https://msdn.microsoft.com/zh-cn/library/ms189469(v=sql.100).aspx
exec sys.sp_reinitsubscription 
@publication = N'tran_repl', 
@subscriber = N'KK-PC', 
@destination_db = N'mytestA', 
@article = N'all'
go

--	啟動可為發布生成初始快照的快照代理作業(在發布服務器的發布數據庫中執行)
--	http://msdn.microsoft.com/zh-cn/library/ms176026(v=sql.105).aspx
exec sys.sp_startpublication_snapshot @publication = N'tran_repl'
go

--	為所有表項目編寫自定義 sp_MSins、sp_MSupd 和 sp_MSdel 過程的腳本
--	https://msdn.microsoft.com/zh-cn/library/ms187946(SQL.100).aspx
--exec sys.sp_scriptpublicationcustomprocs 'tran_repl'
--go


--	至此,完成發布訂閱!!!~ 初始化完成!!~



技術分享圖片技術分享圖片



之前測試了N遍!!!~~今晚有空終於成功處理了!~




SqlServer 使用腳本創建分發服務及事務復制的可更新訂閱