/* ** replsys.sql 1997/02/12 22:03 ** ** ** Copyright Microsoft, Inc. 1998, 1999 ** All Rights Reserved. ** Use, duplication, or disclosure by the United States Government ** is subject to restrictions as set forth in subdivision (c) (1) (ii) ** of the Rights in Technical Data and Computer Software clause ** at CFR 252.227-7013. Microsoft, Inc. One Microsoft Way, Redmond WA ** 98052. SQL Server 7.0 */ dump tran master with no_log go exec dbo.sp_configure 'update',1 go reconfigure with override go set ANSI_NULLS off go use master go exec dbo.sp_MS_upd_sysobj_category 1 --Capture time for use at the end go if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSreplcheck_name') drop procedure sp_MSreplcheck_name go if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSreplcheck_publish') drop procedure sp_MSreplcheck_publish go if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSsetaccesslist') drop procedure sp_MSsetaccesslist go if exists (select * from sysobjects where type = 'P ' and name = 'sp_MScheck_subscription') drop procedure sp_MScheck_subscription go if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSenumcolumns') drop procedure sp_MSenumcolumns go if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSlocktable') drop procedure sp_MSlocktable go if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSreplcheck_connection') drop procedure sp_MSreplcheck_connection go if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSreplcheck_pull') drop procedure sp_MSreplcheck_pull go if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSreplcheck_qv') drop procedure sp_MSreplcheck_qv go if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSpublicationcleanup') drop procedure sp_MSpublicationcleanup if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSaddanonymousreplica') drop procedure sp_MSaddanonymousreplica if exists (select * from sysobjects where type = 'P' and name = 'sp_reinitmergepullsubscription') drop procedure sp_reinitmergepullsubscription if exists (select * from sysobjects where type = 'P ' and name = 'sp_expired_subscription_cleanup') drop procedure sp_expired_subscription_cleanup if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSarticlecleanup') drop procedure sp_MSarticlecleanup if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSdroparticleprocs') drop procedure sp_MSdroparticleprocs if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSdroparticletriggers') drop procedure sp_MSdroparticletriggers if exists (select * from sysobjects where type = 'P ' and name = 'sp_MScheckvalidsystables') drop procedure sp_MScheckvalidsystables if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSreplcheck_subscribe') drop procedure sp_MSreplcheck_subscribe go if exists (select * from sysobjects where type = 'P ' and name = 'sp_replicationoption') drop procedure sp_replicationoption go if exists (select * from sysobjects where type = 'P ' and name = 'sp_helpreplicationoption') drop procedure sp_helpreplicationoption go if exists (select * from sysobjects where type in ('P ') and name = 'sp_MSmergesubscribedb') drop procedure sp_MSmergesubscribedb if exists (select * from sysobjects where type in ('P ') and name = 'sp_MSremovedbreplication') drop procedure sp_MSremovedbreplication if exists (select * from sysobjects where type = 'P ' and name = 'sp_addpullsubscription') drop procedure sp_addpullsubscription if exists (select * from sysobjects where type = 'P ' and name = 'sp_reinitpullsubscription') drop procedure sp_reinitpullsubscription if exists (select * from sysobjects where type = 'P ' and name = 'sp_addmergepullsubscription') drop procedure sp_addmergepullsubscription if exists (select * from sysobjects where type = 'P ' and name = 'sp_dropmergepullsubscription') drop procedure sp_dropmergepullsubscription if exists (select * from sysobjects where type = 'P ' and name = 'sp_changemergepullsubscription') drop procedure sp_changemergepullsubscription if exists (select * from sysobjects where type = 'P ' and name = 'sp_helpmergepullsubscription') drop procedure sp_helpmergepullsubscription if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSchange_priority') drop procedure sp_MSchange_priority if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSdrop_mergesystables') drop procedure sp_MSdrop_mergesystables if exists (select * from sysobjects where type = 'P ' and name = 'sp_MScreate_mergesystables') drop procedure sp_MScreate_mergesystables if exists (select * from sysobjects where type = 'P ' and name = 'sp_addpullsubscription_agent') drop procedure sp_addpullsubscription_agent if exists (select * from sysobjects where type = 'P ' and name = 'sp_helpsubscription_properties') drop procedure sp_helpsubscription_properties if exists (select * from sysobjects where type = 'P ' and name = 'sp_change_subscription_properties') drop procedure sp_change_subscription_properties if exists (select * from sysobjects where type = 'P' and name = 'sp_MSget_pullsubsagent_owner') drop procedure sp_MSget_pullsubsagent_owner if exists (select * from sysobjects where type = 'P' and name = 'sp_MSget_mergepullsubsagent_owner') drop procedure sp_MSget_mergepullsubsagent_owner if exists (select * from sysobjects where type = 'P ' and name = 'sp_addmergepullsubscription_agent') drop procedure sp_addmergepullsubscription_agent if exists (select * from sysobjects where type = 'P ' and name = 'sp_droppullsubscription') drop procedure sp_droppullsubscription if exists (select * from sysobjects where type = 'P ' and name = 'sp_vupgrade_publisherdb') drop procedure sp_vupgrade_publisherdb if exists (select * from sysobjects where type = 'P ' and name = 'sp_vupgrade_publisher') drop procedure sp_vupgrade_publisher if exists (select * from sysobjects where type = 'P ' and name = 'sp_helppullsubscription') drop procedure sp_helppullsubscription if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSunmarkreplinfo') drop procedure sp_MSunmarkreplinfo if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSunmarkifneeded') drop procedure sp_MSunmarkifneeded if exists (select * from sysobjects where type = 'P ' and name = 'sp_MStable_has_unique_index') drop procedure sp_MStable_has_unique_index if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSreplraiserror') drop procedure sp_MSreplraiserror if exists (select * from sysobjects where type = 'P ' and name = 'sp_check_sync_trigger') drop procedure sp_check_sync_trigger if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSreplicationcompatlevel') drop proc sp_MSreplicationcompatlevel if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSgenreplnickname') drop proc sp_MSgenreplnickname if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSenumallpublications') drop proc sp_MSenumallpublications if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSenumtranpublications') drop proc sp_MSenumtranpublications if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSenummergepublications') drop proc sp_MSenummergepublications if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSenum3rdpartypublications') drop proc sp_MSenum3rdpartypublications if exists (select * from sysobjects where type = 'P' and name = 'sp_MSgetreplicainfo') drop procedure sp_MSgetreplicainfo if exists (select * from sysobjects where type = 'P ' and name = 'sp_subscription_cleanup') drop procedure sp_subscription_cleanup if exists (select * from sysobjects where type = 'P ' and name = 'sp_mergesubscription_cleanup') drop procedure sp_mergesubscription_cleanup if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSpad_command') drop procedure sp_MSpad_command if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSflush_command') drop procedure sp_MSflush_command if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSget_colinfo') drop procedure sp_MSget_colinfo if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSget_type') drop procedure sp_MSget_type if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSget_col_position') drop procedure sp_MSget_col_position if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_where_clause') drop procedure sp_MSscript_where_clause if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_params') drop procedure sp_MSscript_params if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_begintrig1') drop procedure sp_MSscript_begintrig1 if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_begintrig2') drop procedure sp_MSscript_begintrig2 if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_endtrig') drop procedure sp_MSscript_endtrig if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_trigger_variables') drop procedure sp_MSscript_trigger_variables if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_trigger_assignment') drop procedure sp_MSscript_trigger_assignment if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_trigger_fetch_statement') drop procedure sp_MSscript_trigger_fetch_statement if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_trigger_exec_rpc') drop procedure sp_MSscript_trigger_exec_rpc if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_trigger_update_checks') drop procedure sp_MSscript_trigger_update_checks if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_trigger_updates') drop procedure sp_MSscript_trigger_updates if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_singlerow_trigger') drop procedure sp_MSscript_singlerow_trigger if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_multirow_trigger') drop procedure sp_MSscript_multirow_trigger if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_sync_ins_trig') drop procedure sp_MSscript_sync_ins_trig if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_sync_upd_trig') drop procedure sp_MSscript_sync_upd_trig if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSscript_sync_del_trig') drop procedure sp_MSscript_sync_del_trig if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSget_synctran_column') drop procedure sp_MSget_synctran_column if exists (select * from sysobjects where type = 'P ' and name = 'sp_check_for_sync_trigger') drop procedure sp_check_for_sync_trigger if exists (select * from sysobjects where type = 'P ' and name = 'sp_addsynctriggers') drop procedure sp_addsynctriggers if exists (select * from sysobjects where type = 'P ' and name = 'sp_helpreplicationdboption') drop procedure sp_helpreplicationdboption if exists (select * from sysobjects where type = 'P' and name = 'sp_MSgetreplnick') drop procedure sp_MSgetreplnick if exists (select * from sysobjects where type = 'P' and name = 'sp_MStestbit') drop procedure sp_MStestbit if exists (select * from sysobjects where type = 'P' and name = 'sp_MSsetbit') drop procedure sp_MSsetbit if exists (select * from sysobjects where type = 'P' and name = 'sp_MSinsertcontents') drop procedure sp_MSinsertcontents if exists (select * from sysobjects where type = 'P' and name = 'sp_MSupdatecontents') drop procedure sp_MSupdatecontents if exists (select * from sysobjects where type = 'P' and name = 'sp_MSdeletecontents') drop procedure sp_MSdeletecontents if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSadd_repl_job') drop procedure sp_MSadd_repl_job IF EXISTS (select * from sysobjects where name = 'sp_MScheck_agent_instance' and type = 'P') DROP PROCEDURE sp_MScheck_agent_instance if exists (select * from sysobjects where name = 'xp_mergexpusage') execute dbo.sp_dropextendedproc 'xp_mergexpusage' if exists (select * from sysobjects where name = 'sp_get_distributor' and type = 'P') drop procedure sp_get_distributor if exists (select * from sysobjects where name = 'sp_MSrepl_addrolemember' and type = 'P') drop procedure sp_MSrepl_addrolemember if exists (select * from sysobjects where name = 'sp_MSrepl_droprolemember' and type = 'P') drop procedure sp_MSrepl_droprolemember if exists (select * from sysobjects where name = 'sp_table_validation' and type = 'P') drop procedure sp_table_validation if exists (select * from sysobjects where name = 'sp_MScreate_sub_tables' and type = 'P') drop procedure sp_MScreate_sub_tables go if exists (select * from sysobjects where name = 'sp_removedbreplication' and type = 'P') drop procedure sp_removedbreplication if exists (select * from sysobjects where name = 'sp_removesrvreplication' and type = 'P') drop procedure sp_removesrvreplication if exists (select * from sysobjects where name = 'sp_vupgrade_subscription_databases' and type = 'P') drop procedure sp_vupgrade_subscription_databases if exists (select * from sysobjects where name = 'sp_vupgrade_MSsubscription_properties' and type = 'P') drop procedure sp_vupgrade_MSsubscription_properties if exists (select * from sysobjects where name = 'sp_vupgrade_mergetables' and type = 'P') drop procedure sp_vupgrade_mergetables if exists (select * from sysobjects where name = 'sp_vupgrade_replication' and type = 'P') drop procedure sp_vupgrade_replication if exists (select * from sysobjects where name = 'sp_vupgrade_replmsdb' and type = 'P') drop procedure sp_vupgrade_replmsdb if exists (select * from sysobjects where name = 'sp_restoredbreplication' and type = 'P') drop procedure sp_restoredbreplication if exists (select * from sysobjects where name = 'sp_MSget_publisher_rpc' and type = 'P') drop procedure sp_MSget_publisher_rpc if exists (select * from sysobjects where name = 'sp_link_publication' and type = 'P') drop procedure sp_link_publication if exists (select * from sysobjects where name = 'sp_MS_replication_installed' and type = 'P') drop procedure sp_MS_replication_installed if exists (select * from sysobjects where name = 'sp_MSunc_to_drive' and type = 'P') drop procedure sp_MSunc_to_drive if exists (select * from sysobjects where name = 'sp_MSdrop_object' and type = 'P') drop procedure sp_MSdrop_object if exists (select * from sysobjects where name = 'sp_MSregistersubscription' and type = 'P') drop procedure sp_MSregistersubscription if exists (select * from sysobjects where name = 'sp_MSunregistersubscription' and type = 'P') drop procedure sp_MSunregistersubscription if exists (select * from sysobjects where name = 'sp_MSrepl_linkedservers_rowset' and type = 'P') drop procedure sp_MSrepl_linkedservers_rowset if exists (select * from sysobjects where name = 'sp_MSrepl_isdbowner' and type = 'P') drop procedure sp_MSrepl_isdbowner if exists (select * from sysobjects where name = 'sp_MSget_qualified_name' and type = 'P') drop procedure sp_MSget_qualified_name if exists (select * from sysobjects where name = 'sp_MSscript_pkvar_assignment' and type = 'P') drop procedure sp_MSscript_pkvar_assignment go if exists (select * from sysobjects where name = 'sp_MSget_jobstate' and type = 'P') drop procedure sp_MSget_jobstate go if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSget_publication_from_taskname') drop procedure sp_MSget_publication_from_taskname go if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSrepl_check_server') drop procedure sp_MSrepl_check_server go if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSreset_synctran_bit') drop procedure sp_MSreset_synctran_bit go sp_addextendedproc 'xp_mergexpusage', 'xprepl.dll' go grant exec on xp_mergexpusage to public go if exists (select * from sysobjects where name = 'xp_showlineage') execute dbo.sp_dropextendedproc 'xp_showlineage' go sp_addextendedproc 'xp_showlineage', 'xprepl.dll' go grant exec on xp_showlineage to public go if exists (select * from sysobjects where name = 'xp_updatelineage') execute dbo.sp_dropextendedproc 'xp_updatelineage' go sp_addextendedproc 'xp_updatelineage', 'xprepl.dll' go grant exec on xp_updatelineage to public go if exists (select * from sysobjects where name = 'xp_proxiedmetadata') execute dbo.sp_dropextendedproc 'xp_proxiedmetadata' go sp_addextendedproc 'xp_proxiedmetadata', 'xprepl.dll' go grant exec on xp_proxiedmetadata to public go if exists (select * from sysobjects where name = 'xp_initcolvs') execute dbo.sp_dropextendedproc 'xp_initcolvs' go sp_addextendedproc 'xp_initcolvs', 'xprepl.dll' go grant exec on xp_initcolvs to public go if exists (select * from sysobjects where name = 'xp_updatecolvbm') execute dbo.sp_dropextendedproc 'xp_updatecolvbm' go sp_addextendedproc 'xp_updatecolvbm', 'xprepl.dll' go grant exec on xp_updatecolvbm to public go if exists (select * from sysobjects where name = 'xp_showcolv') execute dbo.sp_dropextendedproc 'xp_showcolv' go sp_addextendedproc 'xp_showcolv', 'xprepl.dll' go grant exec on xp_showcolv to public go if exists (select * from sysobjects where name = 'xp_execresultset') execute dbo.sp_dropextendedproc 'xp_execresultset' go sp_addextendedproc 'xp_execresultset', 'xprepl.dll' go grant exec on xp_execresultset to public go if exists (select * from sysobjects where name = 'xp_varbintohexstr') execute dbo.sp_dropextendedproc 'xp_varbintohexstr' go sp_addextendedproc 'xp_varbintohexstr', 'xprepl.dll' go grant exec on xp_varbintohexstr to public go if exists (select * from sysobjects where name = 'xp_intersectbitmaps') execute dbo.sp_dropextendedproc 'xp_intersectbitmaps' go sp_addextendedproc 'xp_intersectbitmaps', 'xprepl.dll' go grant exec on xp_intersectbitmaps to public go if exists (select * from sysobjects where name = 'xp_displayparamstmt') execute dbo.sp_dropextendedproc 'xp_displayparamstmt' go sp_addextendedproc 'xp_displayparamstmt', 'xprepl.dll' go grant exec on xp_displayparamstmt to public go if exists (select * from sysobjects where name = 'xp_printstatements') execute dbo.sp_dropextendedproc 'xp_printstatements' go sp_addextendedproc 'xp_printstatements', 'xprepl.dll' go grant exec on xp_printstatements to public go /* Create table dbo.MSreplication_options */ IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSreplication_options' and type = 'U') BEGIN raiserror('Creating procedure Creating table MSreplication_options',0,1) CREATE TABLE dbo.MSreplication_options ( optname sysname NOT NULL, value bit NOT NULL, major_version int NOT NULL, minor_version int NOT NULL, revision int NOT NULL, install_failures int NOT NULL ) END GO IF NOT EXISTS (SELECT * FROM MSreplication_options WHERE optname = 'transactional') INSERT INTO MSreplication_options VALUES ('transactional',0,0,0,0,0) IF NOT EXISTS (SELECT * FROM MSreplication_options WHERE optname = 'merge') INSERT INTO MSreplication_options VALUES ('merge',0,0,0,0,0) GO raiserror('Creating procedure sp_MSreplcheck_name', 0,1) GO CREATE PROCEDURE sp_MSreplcheck_name @name sysname, @raise_error bit = 1 AS declare @index int Set nocount on -- Name cannot be NULL or empty ("") -- Blank identifiers (" ") are allowed IF (@name is null OR datalength(@name) = 0) begin if @raise_error = 1 raiserror (15004,16,-1) return (1) end -- Check for proscribed characters declare @length int select @length = datalength( @name ) / 2 select @index = 1 while @index < @length begin if( 0 = unicode( substring( @name, @index, 1 ) ) ) begin if @raise_error = 1 raiserror(15006,16,-1,@name) return (1) end select @index = @index + 1 end --check for other proscribed characters select @index = charindex( N'%', @name) if (@index <> 0) begin if @raise_error = 1 raiserror(15006,16,-1,@name) return (1) end select @index = charindex(N'*', @name) if (@index <> 0) begin if @raise_error = 1 raiserror(15006,16,-1,@name) return (1) end select @index = charindex(N'[', @name) if (@index <> 0) begin if @raise_error = 1 raiserror(15006,16,-1,@name) return (1) end select @index = charindex(N']', @name) if (@index <> 0) begin if @raise_error = 1 raiserror(15006,16,-1,@name) return (1) end select @index = charindex(N'|', @name) if (@index <> 0) begin if @raise_error = 1 raiserror(15006,16,-1,@name) return (1) end select @index = charindex(N':', @name) if (@index <> 0) begin if @raise_error = 1 raiserror(15006,16,-1,@name) return (1) end select @index = charindex(N'"', @name) if (@index <> 0) begin if @raise_error = 1 raiserror(15006,16,-1,@name) return (1) end select @index = charindex(N'?', @name) if (@index <> 0) begin if @raise_error = 1 raiserror(15006,16,-1,@name) return (1) end select @index = charindex(N'''', @name) if (@index <> 0) begin if @raise_error = 1 raiserror(15006,16,-1,@name) return (1) end select @index = charindex(N'\', @name) if (@index <> 0) begin if @raise_error = 1 raiserror(15006,16,-1,@name) return (1) end select @index = charindex(N'/', @name) if (@index <> 0) begin if @raise_error = 1 raiserror(15006,16,-1,@name) return (1) end select @index = charindex(N'<', @name) if (@index <> 0) begin if @raise_error = 1 raiserror(15006,16,-1,@name) return (1) end select @index = charindex(N'>', @name) if (@index <> 0) begin if @raise_error = 1 raiserror(15006,16,-1,@name) return (1) end -- return success return (0) GO exec dbo.sp_MS_marksystemobject sp_MSreplcheck_name go raiserror('Creating procedure sp_MScheckvalidsystables', 0,1) GO create procedure sp_MScheckvalidsystables @validsubs int output AS if not exists (select name from sysobjects where name='sysmergesubscriptions') begin set @validsubs = 0 return end /* Is there a valid non-loopback subscription? */ if exists (select * from sysmergesubscriptions where db_name=db_name() and srvid = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@@servername)) and subid <> partnerid) begin set @validsubs = 1 return end /* Only possible subscriptions are loopbacks. If database not enabled for publishing, ** then they don't indicate a valid publication/subscription. */ if not exists (select name from master..sysdatabases where (category & 4) = 4 and name = db_name()) begin set @validsubs = 0 return end /* Database has merge publishing turned on, is probably a publisher. Look for loopback ** subscription just to be sure... */ if exists (select * from sysmergesubscriptions where db_name=db_name() and srvid = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@@servername))) begin set @validsubs = 1 return end /* Must not be valid... */ set @validsubs = 0 return GO raiserror('Creating procedure sp_MSdrop_mergesystables', 0,1) GO create procedure sp_MSdrop_mergesystables as begin tran save transaction drop_mergesystables if exists (select * from sysobjects where name = 'sysmergearticles') begin drop table sysmergearticles end if @@error<>0 goto Error if exists (select * from sysobjects where name = 'sysmergepublications') begin drop table sysmergepublications end if @@error<>0 goto Error if exists (select * from sysobjects where name = 'sysmergesubscriptions') begin drop table sysmergesubscriptions end if @@error<>0 goto Error if exists (select * from sysobjects where name = 'MSmerge_contents') begin drop table MSmerge_contents end if @@error<>0 goto Error if exists (select * from sysobjects where name = 'MSmerge_replinfo') begin drop table MSmerge_replinfo end if @@error<>0 goto Error if exists (select * from sysobjects where name = 'MSmerge_tombstone') begin drop table MSmerge_tombstone end if @@error<>0 goto Error if exists (select * from sysobjects where name = 'MSmerge_genhistory') begin drop table MSmerge_genhistory end if @@error<>0 goto Error if exists (select * from sysobjects where name = 'MSmerge_delete_conflicts') begin drop table MSmerge_delete_conflicts end if @@error<>0 goto Error if exists (select * from sysobjects where name = 'sysmergeschemachange') begin drop table sysmergeschemachange end if @@error<>0 goto Error if exists (select * from sysobjects where name = 'sysmergesubsetfilters') begin drop table sysmergesubsetfilters end if @@error<>0 goto Error commit transaction return 0 Error: RAISERROR (20007, 16, -1) if @@trancount > 0 begin ROLLBACK TRANSACTION drop_mergesystables COMMIT TRANSACTION end return 1 go exec dbo.sp_MS_marksystemobject sp_MSdrop_mergesystables go raiserror ('Executing procedure dbo.sp_MSdrop_mergesystables.',0,1) go exec dbo.sp_MSdrop_mergesystables go dump tran master with no_log go raiserror('Creating procedure sp_MScreate_mergesystables',0,1) GO create procedure sp_MScreate_mergesystables as /* This is to make sure that the varbinary columns do not get padded */ set ANSI_PADDING off DECLARE @exist bit DECLARE @validsubs int select @exist = 1 begin tran save transaction MScreate_mergesystables exec dbo.sp_MScheckvalidsystables @validsubs output if @validsubs = 0 exec dbo.sp_MSdrop_mergesystables if not exists (select * from sysobjects where name = 'sysmergepublications') begin raiserror('Creating table sysmergepublications',0,1) create table dbo.sysmergepublications ( publisher sysname NOT NULL default @@servername, publisher_db sysname NOT NULL default db_name(), name sysname NOT NULL, description nvarchar(255) NULL, retention int NULL, publication_type tinyint NULL, pubid uniqueidentifier NOT NULL, designmasterid uniqueidentifier NULL, parentid uniqueidentifier NULL, sync_mode tinyint NULL, allow_push int NULL, allow_pull int NULL, allow_anonymous int NULL, centralized_conflicts int NULL, status tinyint NULL, snapshot_ready tinyint NULL, enabled_for_internet bit NOT NULL default 0, dynamic_filters bit NOT NULL default 0 ) if @@ERROR <> 0 goto Error exec dbo.sp_MS_marksystemobject sysmergepublications if @@ERROR <> 0 goto Error grant select on sysmergepublications to public end if not exists (select * from sysobjects where name = 'sysmergearticles') begin raiserror('Creating table sysmergearticles',0,1) create table dbo.sysmergearticles ( name sysname NOT NULL, type tinyint NULL, objid int NOT NULL, sync_objid int NOT NULL, view_type tinyint NULL, artid uniqueidentifier NOT NULL, description nvarchar(255) NULL, pre_creation_command tinyint NULL, pubid uniqueidentifier NOT NULL, nickname int NOT NULL, column_tracking int NOT NULL, status tinyint NULL, conflict_table sysname NULL, creation_script nvarchar(255) NULL, conflict_script nvarchar(255) NULL, article_resolver nvarchar(255) NULL, ins_conflict_proc sysname NULL, insert_proc sysname NULL, update_proc sysname NULL, select_proc sysname NULL, schema_option binary(8) NULL, destination_object sysname NOT NULL, resolver_clsid nvarchar(50) NULL, subset_filterclause nvarchar(1000) NULL, missing_col_count int NULL, missing_cols varbinary(128) NULL, columns varbinary(128) NULL, resolver_info nvarchar(255) NULL, view_sel_proc nvarchar(290) NULL, gen_cur int NULL ) if @@error<>0 goto Error else begin create unique clustered index uc1sysmergearticles on sysmergearticles(artid, pubid) if @@ERROR <> 0 goto Error end exec dbo.sp_MS_marksystemobject sysmergearticles if @@ERROR <> 0 goto Error grant select on sysmergearticles to public end if not exists (select * from sysobjects where name = 'sysmergesubscriptions') begin raiserror('Creating table sysmergesubscriptions',0,1) create table dbo.sysmergesubscriptions ( subid uniqueidentifier NOT NULL, partnerid uniqueidentifier NOT NULL, datasource_type int NOT NULL, datasource_path nvarchar(255) NULL, srvid int NOT NULL, db_name sysname NOT NULL constraint unique_pubsrvdb unique nonclustered (pubid, srvid, db_name), pubid uniqueidentifier NULL, status tinyint NOT NULL, subscriber_type int NOT NULL, subscription_type int NOT NULL, priority real NOT NULL, sync_type tinyint NOT NULL, -- 1 = automatic 2 = no sync description nvarchar(255) NULL, login_name sysname NOT NULL, last_validated datetime NULL ) if @@error<>0 goto Error else begin create unique clustered index uc1sysmergesubscriptions on sysmergesubscriptions (subid) if @@ERROR<>0 goto Error end exec dbo.sp_MS_marksystemobject sysmergesubscriptions if @@ERROR <> 0 goto Error grant select on sysmergesubscriptions to public end if not exists (select * from sysobjects where name = 'MSmerge_replinfo') begin raiserror('Creating table MSmerge_replinfo',0,1) create table dbo.MSmerge_replinfo ( repid uniqueidentifier NOT NULL, replnickname int NOT NULL, recgen int NULL, recguid uniqueidentifier NULL, sentgen int NULL, sentguid uniqueidentifier NULL, schemaversion int NULL, schemaguid uniqueidentifier NULL, merge_jobid binary(16) NULL, snapshot_jobid binary(16) NULL ) if @@ERROR <> 0 goto Error else begin create unique clustered index uc1MSmerge_replinfo on MSmerge_replinfo (repid) if @@ERROR <> 0 goto Error end exec dbo.sp_MS_marksystemobject MSmerge_replinfo if @@ERROR <> 0 goto Error grant select on MSmerge_replinfo to public end if not exists (select * from sysobjects where name = 'MSmerge_tombstone') begin raiserror('Creating table MSmerge_tombstone',0,1) create table dbo.MSmerge_tombstone ( rowguid uniqueidentifier rowguidcol NOT NULL, tablenick int NOT NULL, type tinyint NOT NULL, lineage varbinary(255) NOT NULL, generation int NOT NULL, reason nvarchar(255) NOT NULL, ) if @@ERROR <> 0 goto Error else begin create unique clustered index uc1MSmerge_tombstone on MSmerge_tombstone (tablenick, rowguid) if @@ERROR <> 0 goto Error create index nc2MSmerge_tombstone on MSmerge_tombstone (generation) if @@ERROR <> 0 goto Error end exec dbo.sp_MS_marksystemobject MSmerge_tombstone if @@ERROR <> 0 goto Error grant select on MSmerge_tombstone to public end if not exists (select * from sysobjects where name = 'MSmerge_contents') begin raiserror('Creating table MSmerge_contents',0,1) create table dbo.MSmerge_contents ( tablenick int NOT NULL, rowguid uniqueidentifier rowguidcol NOT NULL, generation int NOT NULL, partchangegen int NULL, joinchangegen int NULL, lineage varbinary(249) NOT NULL, colv1 varbinary(2048) NULL, ) if @@ERROR <> 0 goto Error else begin create unique clustered index uc1SycContents on MSmerge_contents( tablenick, rowguid ) if @@ERROR <> 0 goto Error create index nc2MSmerge_contents on MSmerge_contents(tablenick, generation) if @@ERROR <> 0 goto Error end exec dbo.sp_MS_marksystemobject MSmerge_contents if @@ERROR <> 0 goto Error grant select on MSmerge_contents to public end if not exists (select * from sysobjects where name = 'MSmerge_genhistory') begin raiserror('Creating table MSmerge_genhistory',0,1) create table dbo.MSmerge_genhistory ( guidsrc uniqueidentifier NOT NULL, guidlocal uniqueidentifier NOT NULL, pubid uniqueidentifier NULL, generation int NOT NULL, art_nick int NULL, nicknames varbinary(255) NOT NULL, coldate datetime NOT NULL ) if @@ERROR <> 0 goto Error create clustered index uc1MSmerge_genhistory on MSmerge_genhistory(guidsrc) if @@ERROR <> 0 goto Error create index nc1MSmerge_genhistory on MSmerge_genhistory(generation) if @@ERROR <> 0 goto Error create index nc2MSmerge_genhistory on MSmerge_genhistory(guidlocal) if @@ERROR <> 0 goto Error exec dbo.sp_MS_marksystemobject MSmerge_genhistory if @@ERROR <> 0 goto Error grant select on MSmerge_genhistory to public end if not exists (select * from sysobjects where name = 'MSmerge_delete_conflicts') begin raiserror('Creating table MSmerge_delete_conflicts',0,1) create table dbo.MSmerge_delete_conflicts ( tablenick int NOT NULL, rowguid uniqueidentifier rowguidcol NOT NULL, origin_datasource nvarchar(255) NULL, conflict_type int NULL, reason_code int NULL, reason_text nvarchar(720) NULL, pubid uniqueidentifier NULL ) if @@ERROR <> 0 goto Error else begin create clustered index uc1MSmerge_delete_conflicts on MSmerge_delete_conflicts(tablenick, rowguid) if @@ERROR <> 0 goto Error end exec dbo.sp_MS_marksystemobject MSmerge_delete_conflicts if @@ERROR <> 0 goto Error grant select on MSmerge_delete_conflicts to public end if not exists (select * from sysobjects where name = 'sysmergeschemachange') begin raiserror('Creating table sysmergeschemachange',0,1) create table dbo.sysmergeschemachange ( pubid uniqueidentifier NOT NULL, artid uniqueidentifier NULL, schemaversion int NOT NULL, schemaguid uniqueidentifier NOT NULL, schematype int NOT NULL, schematext nvarchar(2000) NOT NULL ) if @@ERROR <> 0 goto Error else begin create clustered index schemachangeversion on sysmergeschemachange(schemaversion) if @@ERROR <> 0 goto Error end exec dbo.sp_MS_marksystemobject sysmergeschemachange if @@ERROR <> 0 goto Error grant select on sysmergeschemachange to public end if not exists (select * from sysobjects where name = 'sysmergesubsetfilters') begin raiserror('Creating table sysmergesubsetfilters',0,1) create table dbo.sysmergesubsetfilters ( filtername sysname NOT NULL, join_filterid int identity NOT NULL, pubid uniqueidentifier NOT NULL, artid uniqueidentifier NOT NULL, art_nickname int NOT NULL, join_articlename sysname NOT NULL, join_nickname int NOT NULL, join_unique_key int NOT NULL, expand_proc sysname NULL, join_filterclause nvarchar(1000) NULL ) if @@ERROR <> 0 goto Error exec dbo.sp_MS_marksystemobject sysmergesubsetfilters if @@ERROR <> 0 goto Error grant select on sysmergesubsetfilters to public end if @@error <> 0 return(1) commit transaction return (0) Error: if @@trancount > 0 begin ROLLBACK TRANSACTION MScreate_mergesystables COMMIT TRANSACTION end RAISERROR (20008, 16, -1) return (1) go exec dbo.sp_MS_marksystemobject sp_MScreate_mergesystables go raiserror('Creating procedure sp_MStestbit',0,1) go create procedure sp_MStestbit @bm varbinary(125), @coltotest smallint AS declare @word smallint declare @bit smallint declare @mask binary(2) declare @mval int declare @oldword binary(2) if @coltotest < 1 return 0 SELECT @word = CONVERT(smallint, 1 + FLOOR((@coltotest -1)/16)) SELECT @bit = (@coltotest -1) % 16 SELECT @mval = POWER(2, @bit) SELECT @mask = convert( binary(2), unicode( substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) ) ) SELECT @oldword = convert( binary(2), SUBSTRING( convert( nvarchar(63),@bm), @word, 1) ) IF @oldword IS NULL return 0 return convert( smallint, @oldword ) & convert( smallint, @mask ) go exec dbo.sp_MS_marksystemobject sp_MStestbit go raiserror('Creating procedure sp_MSsetbit',0,1) go create procedure sp_MSsetbit @bm varbinary(125) output, @coltoadd smallint AS declare @word smallint declare @bit smallint declare @mask binary(2) declare @mval int declare @newword binary(2) declare @oldword binary(2) SELECT @word = CONVERT(smallint, 1 + FLOOR((@coltoadd-1)/16)) IF @word > 62 return 0 SELECT @bit = (@coltoadd-1) % 16 SET @mval = POWER(2, @bit) SELECT @mask = convert( binary(2), unicode( substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) ) ) if @bm is null set @bm = 0x0 while datalength(@bm) < @word * 2 set @bm = @bm + 0x0000 SET @oldword = convert( binary(2), SUBSTRING( convert(nvarchar(63),@bm), @word, 1) ) IF @oldword IS NULL SET @oldword = 0x00 SET @newword = convert( smallint, @oldword) | convert( smallint, @mask ) SET @bm = CONVERT(varbinary(125), STUFF( CONVERT(nvarchar(63),@bm), @word, 1, convert( nchar(1),@newword)) ) go exec dbo.sp_MS_marksystemobject sp_MSsetbit go raiserror('Creating procedure sp_MSinsertcontents',0,1) go create procedure sp_MSinsertcontents @tablenick int, @rowguid uniqueidentifier, @lineage varbinary(249), @colv1 varbinary(2048) AS /* ** permission check */ declare @retcode int declare @objid int declare @owner sysname declare @artid uniqueidentifier declare @guidstr nvarchar(32) declare @instrigger sysname select @objid = objid, @artid=artid from sysmergearticles where nickname=@tablenick select @owner =user_name(uid) from sysobjects where id=@objid exec @retcode=sp_MSguidtostr @artid, @guidstr out if @retcode<>0 or @@ERROR<>0 return (1) set @instrigger = @owner + '.ins_' + @guidstr if trigger_nestlevel(object_id(@instrigger)) = 0 begin raiserror(14126, 16, -1) return (1) -- current user does not have insert permission to underlying table end insert into MSmerge_contents (tablenick, rowguid, generation, partchangegen, joinchangegen, lineage, colv1) values (@tablenick, @rowguid, 0, 0, 0, @lineage, @colv1) if @@error <> 0 begin raiserror (20041, 16, -1) return (1) end delete from MSmerge_tombstone where rowguid = @rowguid and tablenick = @tablenick if @@error <> 0 begin raiserror (20041, 16, -1) return (1) end go exec dbo.sp_MS_marksystemobject sp_MSinsertcontents go grant exec on dbo.sp_MSinsertcontents to public raiserror('Creating procedure sp_MSupdatecontents',0,1) go create procedure sp_MSupdatecontents @tablenick int, @rowguid uniqueidentifier, @lineage varbinary(249), @colv1 varbinary(2048), @partchange int = null, @joinchange int = null AS /* ** permission check */ declare @retcode int declare @objid int declare @owner sysname declare @artid uniqueidentifier declare @guidstr nvarchar(32) declare @updtrigger sysname select @objid = objid, @artid=artid from sysmergearticles where nickname=@tablenick select @owner =user_name(uid) from sysobjects where id=@objid exec @retcode=sp_MSguidtostr @artid, @guidstr out if @retcode<>0 or @@ERROR<>0 return (1) set @updtrigger = @owner + '.upd_' + @guidstr if trigger_nestlevel(object_id(@updtrigger)) = 0 begin raiserror(14126, 16, -1) return (1) -- current user does not 'update all' permission upon underlying table end update MSmerge_contents set lineage = @lineage, generation = 0, colv1 = @colv1 where tablenick = @tablenick and rowguid = @rowguid if (@@rowcount = 0) insert into MSmerge_contents (tablenick, rowguid, generation, joinchangegen, lineage, colv1) values (@tablenick, @rowguid, 0, 1, @lineage, @colv1) if @@error <> 0 begin raiserror (20041, 16, -1) return (1) end if @partchange = 1 begin update MSmerge_contents set partchangegen = 0, joinchangegen = 0 where tablenick = @tablenick and rowguid = @rowguid if @@error <> 0 begin raiserror (20041, 16, -1) return (1) end end else if @joinchange = 1 begin update MSmerge_contents set joinchangegen = 0 where tablenick = @tablenick and rowguid = @rowguid if @@error <> 0 begin raiserror (20041, 16, -1) return (1) end end go exec dbo.sp_MS_marksystemobject sp_MSupdatecontents go grant exec on dbo.sp_MSupdatecontents to public raiserror(15339, -1, -1, 'sp_MSdeletecontents') go create procedure sp_MSdeletecontents @tablenick int, @rowguid uniqueidentifier AS declare @nick int declare @reason nvarchar(255) declare @lineage varbinary(255) /* ** permission check */ declare @retcode int declare @objid int declare @owner sysname declare @artid uniqueidentifier declare @guidstr nvarchar(32) declare @deltrigger sysname select @objid = objid, @artid=artid from sysmergearticles where nickname=@tablenick select @owner =user_name(uid) from sysobjects where id=@objid exec @retcode=sp_MSguidtostr @artid, @guidstr out if @retcode<>0 or @@ERROR<>0 return (1) set @deltrigger = @owner + '.del_' + @guidstr if trigger_nestlevel(object_id(@deltrigger)) = 0 begin raiserror(14126, 16, -1) return (1) -- current user does not have 'delete' permission to underlying table end exec dbo.sp_MSgetreplnick @nickname = @nick out if (@@error <> 0) or @nick IS NULL begin RAISERROR (14055, 11, -1) RETURN(1) end select @lineage = lineage from MSmerge_contents (UPDLOCK ROWLOCK index = 1) where tablenick = @tablenick and rowguid = @rowguid exec master..xp_updatelineage @lineage output, @nick select @reason = 'user delete' insert into MSmerge_tombstone (rowguid, tablenick, type, lineage, generation, reason) values (@rowguid, @tablenick, 1, @lineage, 0, @reason) if @@error <> 0 begin raiserror (20041, 16, -1) return (1) end delete from MSmerge_contents where tablenick = @tablenick and rowguid = @rowguid if @@error <> 0 begin raiserror (20041, 16, -1) return (1) end go exec dbo.sp_MS_marksystemobject sp_MSdeletecontents go grant exec on dbo.sp_MSdeletecontents to public raiserror('Creating procedure sp_MSunmarkifneeded',0,1) GO CREATE PROCEDURE sp_MSunmarkifneeded( @object sysname, @pubid uniqueidentifier )AS declare @table_in_use int declare @retcode int select @table_in_use = 0 if EXISTS (select * from sysmergearticles where pubid<>@pubid and objid=object_id(@object)) begin select @table_in_use = 1 select @table_in_use return (0) end exec @retcode = sp_MSunmarkreplinfo @object if @retcode <>0 or @@error<>0 return (1) select @table_in_use return (0) GO exec dbo.sp_MS_marksystemobject sp_MSunmarkifneeded go grant exec on dbo.sp_MSunmarkifneeded to public go raiserror('Creating procedure sp_MSunmarkreplinfo',0,1) GO CREATE PROCEDURE sp_MSunmarkreplinfo( @object sysname, /* Name of the table, unqualitied */ @owner sysname = NULL, /* Name of the owner, unqualified */ @type smallint = 0 /* default is to unmark, as name implies */ )AS declare @merge_pub_object_bit int declare @merge_pub_unmark_bit int declare @id int declare @qualified_name nvarchar(258) if @owner is NULL or @owner='' select @owner = user_name(uid) from sysobjects where id = object_id(QUOTENAME(@object)) select @qualified_name = QUOTENAME(@owner) + '.' + QUOTENAME(@object) select @id = object_id(@qualified_name) select @merge_pub_object_bit = 128 select @merge_pub_unmark_bit = ~@merge_pub_object_bit if exists (select name from sysobjects where id = @id) begin if @type = 0 /* type = 0, unmark; else mark the bit */ begin BEGIN TRANSACTION exec dbo.sp_replupdateschema @qualified_name update sysobjects set replinfo = replinfo & @merge_pub_unmark_bit where id = @id COMMIT TRANSACTION end else begin BEGIN TRANSACTION exec dbo.sp_replupdateschema @qualified_name update sysobjects set replinfo = replinfo | @merge_pub_object_bit where id = @id COMMIT TRANSACTION end end GO exec dbo.sp_MS_marksystemobject sp_MSunmarkreplinfo go grant execute on dbo.sp_MSunmarkreplinfo to public raiserror('Creating procedure sp_MSaddanonymousreplica',0,1) GO CREATE PROCEDURE sp_MSaddanonymousreplica (@publication sysname, @publisher sysname, @publisherDB sysname, @anonymous int ) as declare @retcode int declare @subscription_type nvarchar(15) if exists (select * from sysobjects where name='sysmergepublications') begin IF EXISTS (select name from sysmergepublications where name=@publication and UPPER(publisher)=UPPER(@publisher) and publisher_db = @publisherDB) return (0) -- replica exists. -- else call this SP to add this replica end if @anonymous = 1 select @subscription_type = 'anonymous' else select @subscription_type = 'local' exec @retcode = dbo.sp_addmergepullsubscription @publication = @publication, @publisher = @publisher, @publisher_db=@publisherDB, @subscriber_type =@subscription_type IF @retcode<>0 or @@ERROR<>0 return (1) return (0) GO exec dbo.sp_MS_marksystemobject sp_MSaddanonymousreplica go grant execute on dbo.sp_MSaddanonymousreplica to public go raiserror('Creating procedure sp_MSgetreplicainfo',0,1) GO CREATE PROCEDURE sp_MSgetreplicainfo (@publisher sysname, @publisher_db sysname, @publication sysname, @datasource_type int = 0, /* 0 = SQL Server, 1 = DSN, 2 = Jet */ @server_name sysname = NULL, /* Server Name */ @db_name sysname = NULL, /* Database Name */ @datasource_path nvarchar(255) = NULL) /* Datasource path - JET MDB file path etc */ as declare @srvid int declare @retcode int declare @repid uniqueidentifier declare @pubid uniqueidentifier declare @schemaguid uniqueidentifier declare @nickname int declare @subscription_type int declare @reptype tinyint declare @priority real declare @schversion int declare @status int declare @partnerid uniqueidentifier declare @sync_type tinyint declare @description nvarchar(255) /* ** Parameter Check: @publication. ** Make sure that the publication exists. */ if (@publication is null) begin RAISERROR(14043, 16, -1, '@publication') return (1) end if (@server_name is NULL) SET @server_name = @@SERVERNAME if (@db_name is NULL) set @db_name = db_name() SELECT @srvid = srvid FROM master..sysservers WHERE UPPER(srvname) = UPPER(@server_name) IF @@ERROR <> 0 BEGIN RAISERROR (14080, 16, -1) RETURN (1) END IF @srvid IS NULL BEGIN RAISERROR (14010, 16, -1) RETURN (1) END select @pubid = pubid from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db if (@pubid is null) begin RAISERROR (20026, 16, -1, @publication) return (1) end if (@datasource_type = 0) begin SELECT @repid = subid, @priority = priority, @reptype = subscriber_type, @subscription_type = subscription_type , @status = status, @partnerid = partnerid, @sync_type = sync_type, @description = description FROM sysmergesubscriptions WHERE srvid = @srvid and db_name = @db_name and pubid = @pubid END ELSE BEGIN SELECT @repid = subid, @priority = priority, @reptype = subscriber_type, @subscription_type = subscription_type , @status = status, @partnerid = partnerid, @sync_type = sync_type, @description = description FROM sysmergesubscriptions WHERE srvid = @srvid and pubid = @pubid END if @repid is NULL begin RAISERROR(20021, 16, -1) return (1) end select @schversion = schemaversion, @schemaguid = schemaguid from MSmerge_replinfo where repid = @repid select @nickname = replnickname from MSmerge_replinfo where repid = @repid select @repid, @nickname, @reptype, @subscription_type, @priority, @schversion, @schemaguid, @status, @partnerid, @sync_type, @description return (0) go exec dbo.sp_MS_marksystemobject sp_MSgetreplicainfo go grant execute on dbo.sp_MSgetreplicainfo to public raiserror('Creating procedure sp_MSadd_repl_job',0,1) go CREATE PROCEDURE sp_MSadd_repl_job @name nvarchar(200), @subsystem nvarchar(60) = 'TSQL', @server sysname = NULL, @username sysname = NULL, @databasename sysname = NULL, @enabled TINYINT = 0, @freqtype INT = 2, -- 2 means OnDemand @freqinterval INT = 1, @freqsubtype INT = 1, @freqsubinterval INT = 1, @freqrelativeinterval INT = 1, @freqrecurrencefactor INT = 1, @activestartdate INT = 0, @activeenddate INT = 0, @activestarttimeofday INT = 0, @activeendtimeofday INT = 0, @nextrundate INT = 0, @nextruntime INT = 0, @runpriority INT = 0, @emailoperatorname nvarchar(100) = NULL, @retryattempts INT = NULL, @retrydelay INT = 0, @command nvarchar(4000)= NULL, @loghistcompletionlevel INT = 2, @emailcompletionlevel INT = 0, @description nvarchar(255) = NULL, @tagadditionalinfo nvarchar(96) = NULL, @tagobjectid INT = NULL, @tagobjecttype INT = NULL, @cmdexecsuccesscode INT = 0, @category_name sysname = NULL, -- New for 7.0 @failure_detection BIT = 0, @agent_id INT = NULL, @job_id BINARY(16) = NULL OUTPUT AS BEGIN DECLARE @retval INT declare @step_id int declare @step_name nvarchar(100) declare @step_command nvarchar(1024) declare @on_fail_action tinyint declare @on_success_action tinyint declare @schedule_name nvarchar(100) declare @comments nvarchar(100) SET NOCOUNT ON SELECT @retval = 1 -- 0 means success, 1 means failure set @step_id = 1 set @on_fail_action = 2 -- Return failure set @on_success_action = 1 -- Return success set @step_command = NULL /* ** Set default retries to every minute for 10 minutes. ** */ if @retryattempts = NULL and @retrydelay = 0 begin select @retryattempts = 10 select @retrydelay = 1 end BEGIN TRANSACTION -- Drop the job if it already exists IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @name) begin exec @retval = msdb.dbo.sp_delete_job @job_name=@name if @@ERROR<>0 or @retval<>0 goto UNDO end -- Add the job EXECUTE @retval = msdb.dbo.sp_add_job @job_name = @name, @enabled = @enabled, @start_step_id = 1, @description = @description, @category_name = @category_name, @notify_level_eventlog = @loghistcompletionlevel, @notify_level_email = @emailcompletionlevel, @notify_email_operator_name = @emailoperatorname, @job_id = @job_id OUTPUT IF (@retval <> 0) BEGIN GOTO UNDO END -- Add startup message step if @failure_detection = 1 begin select @step_name = formatmessage(20528) select @comments = formatmessage(20529) -- Construct command based on subsystem type select @step_command = case UPPER(@subsystem) WHEN 'SNAPSHOT' THEN N'sp_MSadd_snapshot_history @perfmon_increment = 0, @agent_id = ' + convert (nvarchar(10), @agent_id) + N', @runstatus = 1, @comments = ''' + @comments + '''' WHEN 'LOGREADER' THEN N'sp_MSadd_logreader_history @perfmon_increment = 0, @agent_id = ' + convert (nvarchar(10), @agent_id) + N', @runstatus = 1, @comments = ''' + @comments + '''' WHEN 'DISTRIBUTION' THEN N'sp_MSadd_distribution_history @perfmon_increment = 0, @agent_id = ' + convert (nvarchar(10), @agent_id) + N', @runstatus = 1, @comments = ''' + @comments + '''' WHEN 'MERGE' THEN N'sp_MSadd_merge_history @perfmon_increment = 0, @agent_id = ' + convert (nvarchar(10),@agent_id) + N', @runstatus = 1, @comments = ''' + @comments + '''' end -- Add the job step EXECUTE @retval = msdb.dbo.sp_add_jobstep @job_id = @job_id, @step_id = @step_id, @step_name = @step_name, @command = @step_command, @cmdexec_success_code = @cmdexecsuccesscode, @on_success_action = 3, -- Goto next step @on_fail_action = 3, -- Goto next step @server = @server, @database_name = @databasename, @database_user_name = @username, @os_run_priority = @runpriority IF (@retval <> 0) BEGIN GOTO UNDO END set @step_id = @step_id + 1 set @on_fail_action = 3 -- Goto next step end -- Add the job step select @step_name = formatmessage(20530) EXECUTE @retval = msdb.dbo.sp_add_jobstep @job_id = @job_id, @step_id = @step_id, @step_name = @step_name, @subsystem = @subsystem, @command = @command, @cmdexec_success_code = @cmdexecsuccesscode, @on_success_action = @on_success_action, @on_fail_action = @on_fail_action, @server = @server, @database_name = @databasename, @database_user_name = @username, @retry_attempts = @retryattempts, @retry_interval = @retrydelay, @os_run_priority = @runpriority IF (@retval <> 0) BEGIN GOTO UNDO END -- Add failure message step if @failure_detection = 1 begin set @step_id = @step_id + 1 select @step_name = formatmessage(20531) -- Construct command select @step_command = N'sp_MSdetect_nonlogged_shutdown @subsystem = ''' + @subsystem + N''', @agent_id = ' + convert (nvarchar(10), @agent_id) -- Add the job step EXECUTE @retval = msdb.dbo.sp_add_jobstep @job_id = @job_id, @step_id = @step_id, @step_name = @step_name, @command = @step_command, @cmdexec_success_code = @cmdexecsuccesscode, @on_success_action = 2, -- Always quit with failure @server = @server, @database_name = @databasename, @database_user_name = @username, @os_run_priority = @runpriority IF (@retval <> 0) BEGIN GOTO UNDO END end -- Add the job schedule IF (@activestartdate = 0) SELECT @activestartdate = NULL IF (@activeenddate = 0) SELECT @activeenddate = NULL -- But if @activeenddate is NOT NULL, then @activestartdate cannot be allowed to be NULL either. Set it to today's date converted to the int format used yyyymmdd IF (@activeenddate IS NOT NULL AND @activestartdate IS NULL) SELECT @activestartdate=DATEPART(YYYY,getdate()) * 10000 + DATEPART(MM,getdate()) * 100 + DATEPART(DD,getdate()) -- But never let startdate be > end date IF (@activestartdate > @activeenddate) SELECT @activestartdate=@activeenddate IF (@activestarttimeofday = 0) SELECT @activestarttimeofday = NULL IF (@activeendtimeofday = 0) SELECT @activeendtimeofday = NULL IF (@freqtype <> 0x2) -- OnDemand tasks simply have no schedule in 7.0 BEGIN select @schedule_name = formatmessage(20532) EXECUTE @retval = msdb.dbo.sp_add_jobschedule @job_id = @job_id, @name = @schedule_name, @enabled = 1, @freq_type = @freqtype, @freq_interval = @freqinterval, @freq_subday_type = @freqsubtype, @freq_subday_interval = @freqsubinterval, @freq_relative_interval = @freqrelativeinterval, @freq_recurrence_factor = @freqrecurrencefactor, @active_start_date = @activestartdate, @active_end_date = @activeenddate, @active_start_time = @activestarttimeofday, @active_end_time = @activeendtimeofday IF (@retval <> 0) BEGIN GOTO UNDO END END -- And finally, add the job server EXECUTE @retval = msdb.dbo.sp_add_jobserver @job_id = @job_id, @server_name = '(local)' IF (@retval <> 0) BEGIN GOTO UNDO END COMMIT TRANSACTION -- If this is an autostart LogReader or Distribution or Merge job, add the [new] '-Continuous' paramter to the command IF (@freqtype = 0x40) AND ((UPPER(@subsystem) = 'LOGREADER') OR (UPPER(@subsystem) = 'DISTRIBUTION') OR (UPPER(@subsystem) = 'MERGE')) BEGIN UPDATE msdb.dbo.sysjobsteps SET command = command + ' -Continuous' WHERE (job_id = @job_id) AND ((@failure_detection = 0 and step_id = 1) or (@failure_detection = 1 and step_id = 2)) END -- If this is an autostart job, start it now (for backwards compatibility with 6.x SQLExecutive behaviour) IF (@freqtype = 0x40) EXECUTE msdb.dbo.sp_start_job @job_id = @job_id, @error_flag = 0 RETURN(0) UNDO: if @@TRANCOUNT = 1 ROLLBACK TRAN else COMMIT TRAN return(1) END go raiserror('Creating procedure sp_MScheck_subscription', 0,1) go CREATE PROCEDURE sp_MScheck_subscription ( @publication sysname, -- 1 Tran, 2 Merge @pub_type int )AS declare @merge_pubid uniqueidentifier declare @tran_pubid int if @pub_type = 2 BEGIN if not exists (select * from sysobjects where name = 'sysmergepublications') begin raiserror(20054, 16, -1) return (1) end select @merge_pubid = pubid from sysmergepublications where name=@publication and publisher=@@SERVERNAME and publisher_db=db_name() if @merge_pubid is NULL begin raiserror(20026, 16, -1, @publication) return (1) end if EXISTS (select * from sysmergesubscriptions where pubid=@merge_pubid and subid<>pubid) select 1 else select 0 END else -- if not merge, it has to be tran level. For other level, a generic error will be returned BEGIN if not exists (select * from sysobjects where name='syspublications') begin raiserror(20054, 16, -1) return (1) end select @tran_pubid = pubid from syspublications where name=@publication if @tran_pubid is NULL begin raiserror(20026, 16, -1, @publication) return (1) end if EXISTS (select * from syssubscriptions where (srvid <> -1) and artid in (select artid from sysarticles where pubid=@tran_pubid)) select 1 else select 0 END GO exec dbo.sp_MS_marksystemobject sp_MScheck_subscription go grant execute on dbo.sp_MScheck_subscription to public go raiserror('Creating procedure sp_replicationoption', 0,1) go CREATE PROCEDURE sp_replicationoption ( @optname sysname, @value nvarchar(5), @security_mode int = 0, @login sysname = 'sa', @password sysname = NULL, @reserved nvarchar(20) = NULL ) AS DECLARE @optbit bit DECLARE @osql_cmd1 nvarchar (255) DECLARE @osql_cmd_full nvarchar (255) DECLARE @osql_for_nt int DECLARE @install_path nvarchar (255) DECLARE @retcode int DECLARE @undo_install nvarchar(20) DECLARE @no_scripts nvarchar(10) DECLARE @platform_nt binary SELECT @platform_nt = 0x1 if is_srvrolemember('sysadmin') <> 1 BEGIN RAISERROR (15232, 14, -1) RETURN (1) END SELECT @no_scripts = 'no_scripts' SELECT @undo_install = 'undo_install' IF db_name() <> 'master' BEGIN RAISERROR(5001, 16,-1) GOTO FAILURE END IF LOWER(@optname) NOT IN ('transactional','merge') BEGIN RAISERROR(21014, 16, -1) GOTO FAILURE END IF LOWER(@value) NOT IN ('true','false') BEGIN RAISERROR(14137,16,-1) GOTO FAILURE END IF LOWER(@value) = 'true' SELECT @optbit = 1 ELSE SELECT @optbit = 0 /* ** Check if the option is set as required already */ IF @reserved <> @undo_install AND EXISTS (SELECT * FROM MSreplication_options WHERE optname = @optname AND value = @optbit) BEGIN IF LOWER(@value) = 'true' RAISERROR (21015, 10, -1, @optname) ELSE RAISERROR (21016, 10, -1, @optname) GOTO FAILURE END /* Install replication */ IF @optbit = 1 BEGIN IF LOWER(@reserved) = @no_scripts GOTO NO_SCRIPTS -- Set the flag for platform IF (( platform() & @platform_nt = @platform_nt )) SELECT @osql_for_nt = 1 ELSE SELECT @osql_for_nt = 0 /* ** Get installation path */ EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', 'SOFTWARE\Microsoft\MSSQLServer\Setup', 'SQLPath', @param = @install_path OUTPUT IF @@ERROR<> 0 OR @retcode <> 0 or @install_path is NULL or @install_path='' BEGIN GOTO FAILURE END /* ** Install replcom.sql and repltran.sql */ IF @security_mode = 1 SELECT @osql_cmd1 = '"' + @install_path + '\binn\osql" -E ' ELSE -- cannot specify -S w/ -E for local execution, SID does not map due to nofix bug SELECT @osql_cmd1 = '"' + @install_path + '\binn\osql" -U' + @login + ' -P' + isnull(@password,'') + ' -S' + @@SERVERNAME + ' ' select @osql_cmd1 = @osql_cmd1 + '-l30 -t30 ' -- Install replcom.sql -- bug24982 Only apply replcom.sql if it was not applied before. -- '-b' option will make osql stop at errors and return error code -- We must use this option. IF NOT EXISTS (SELECT * FROM MSreplication_options WHERE value = 1) BEGIN -- Initialize the Command IF (@osql_for_nt = 1) SELECT @osql_cmd_full = '" ' ELSE SELECT @osql_cmd_full = ' ' SELECT @osql_cmd_full = @osql_cmd_full + @osql_cmd1 + ' -dmaster' + ' -b ' + ' -i' + '"' + @install_path + '\install\replcom.sql"' + ' -o' + '"' + @install_path + '\install\replcom.out"' IF (@osql_for_nt = 1) SELECT @osql_cmd_full = @osql_cmd_full + ' "' EXEC @retcode = master..xp_cmdshell @osql_cmd_full IF @@ERROR<> 0 OR @retcode <> 0 BEGIN RAISERROR (14113, 16, -1, @osql_cmd_full, 'replcom.out') GOTO UNDO_INSTALL END END IF LOWER(@optname) = 'transactional' BEGIN -- Install repltran.sql IF (@osql_for_nt = 1) SELECT @osql_cmd_full = '" ' ELSE SELECT @osql_cmd_full = ' ' SELECT @osql_cmd_full = @osql_cmd_full + @osql_cmd1 + ' -dmaster' + ' -b ' + ' -i' + '"' + @install_path + '\install\repltran.sql"' + ' -o' + '"' + @install_path + '\install\repltran.out"' IF (@osql_for_nt = 1) SELECT @osql_cmd_full = @osql_cmd_full + ' "' EXEC @retcode = master..xp_cmdshell @osql_cmd_full IF @@ERROR<> 0 OR @retcode <> 0 BEGIN RAISERROR (14113, 16, -1, @osql_cmd_full, 'repltran.out') GOTO UNDO_INSTALL END END IF LOWER(@optname) = 'merge' BEGIN -- Install replmerg.sql IF (@osql_for_nt = 1) SELECT @osql_cmd_full = '" ' ELSE SELECT @osql_cmd_full = ' ' SELECT @osql_cmd_full = @osql_cmd_full + @osql_cmd1 + ' -dmaster' + ' -b ' + ' -i' + '"' + @install_path + '\install\replmerg.sql"' + ' -o' + '"' + @install_path + '\install\replmerg.out"' IF (@osql_for_nt = 1) SELECT @osql_cmd_full = @osql_cmd_full + ' "' EXEC @retcode = master..xp_cmdshell @osql_cmd_full IF @@ERROR<> 0 OR @retcode <> 0 BEGIN RAISERROR (14113, 16, -1, @osql_cmd_full, 'replmerg.out') GOTO UNDO_INSTALL END END NO_SCRIPTS: UPDATE MSreplication_options SET value = @optbit WHERE optname = @optname IF @@ERROR <> 0 BEGIN GOTO UNDO_INSTALL END END /* Uninstall replication */ ELSE BEGIN /* ** Make sure no distributor installed before dropping ** replication stored procedures */ IF EXISTS (SELECT * FROM master..sysservers WHERE srvstatus & 8 <> 0) BEGIN RAISERROR (21021, 16, -1) RETURN(1) END UPDATE MSreplication_options SET value = @optbit WHERE optname = @optname IF @@ERROR <> 0 BEGIN GOTO FAILURE END /* *********** Do not drop replication stored procs anymore. IF LOWER(@optname) = 'transactional' BEGIN if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSdrop_repltran') begin exec @retcode = dbo.sp_MSdrop_repltran if @@ERROR = 0 and @retcode = 0 drop procedure sp_MSdrop_repltran end END IF LOWER(@optname) = 'merge' BEGIN if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSdrop_replmerg') begin exec @retcode = dbo.sp_MSdrop_replmerg if @@ERROR = 0 and @retcode = 0 drop procedure sp_MSdrop_replmerg end END IF NOT EXISTS (SELECT * FROM MSreplication_options WHERE value = 1) BEGIN if exists (select * from sysobjects where type = 'P ' and name = 'sp_MSdrop_replcom') begin exec @retcode = dbo.sp_MSdrop_replcom if @@ERROR = 0 and @retcode = 0 drop procedure sp_MSdrop_replcom end END */ END RETURN(0) UNDO_INSTALL: /* This is needed to drop the stored procedures that were created. */ EXEC dbo.sp_replicationoption @optname = @optname, @value = 'false', @reserved = @undo_install FAILURE: RETURN(1) GO exec dbo.sp_MS_marksystemobject sp_replicationoption go grant execute on dbo.sp_replicationoption to public raiserror('Creating procedure sp_helpreplicationoption', 0,1) go CREATE PROCEDURE sp_helpreplicationoption ( @optname sysname = NULL ) AS DECLARE @optbit bit DECLARE @retcode int IF @optname IS NOT NULL AND LOWER(@optname) NOT IN ('transactional','merge') BEGIN RAISERROR(21014, 16, -1) GOTO FAILURE END SELECT optname, value, major_version, minor_version, revision FROM MSreplication_options WHERE optname = @optname OR @optname = NULL RETURN(0) FAILURE: RETURN(1) GO exec dbo.sp_MS_marksystemobject sp_helpreplicationoption go grant execute on dbo.sp_helpreplicationoption to public raiserror('Creating procedure sp_MSgetreplnick', 0,1) GO create procedure sp_MSgetreplnick ( @server sysname = NULL, @db_name sysname = NULL, @pubid uniqueidentifier = NULL, @nickname int output ) as declare @srvid int if @db_name IS NULL select @db_name = db_name() /* Use 0 if the Server name is not passed in since it would be the local server */ if @server IS NULL select @srvid = 0 else select @srvid = max(srvid) from master..sysservers where UPPER(srvname) = UPPER(@server) if (@pubid IS NOT NULL) begin select @nickname = max(replnickname) from MSmerge_replinfo where repid in (select subid from sysmergesubscriptions where srvid = @srvid and db_name = @db_name and pubid = @pubid) end else begin select @nickname = max(replnickname) from MSmerge_replinfo where repid in (select subid from sysmergesubscriptions where srvid = @srvid and db_name = @db_name) end go exec dbo.sp_MS_marksystemobject sp_MSgetreplnick go grant execute on dbo.sp_MSgetreplnick to public raiserror('Creating procedure sp_MSreplcheck_publish', 0,1) go CREATE PROCEDURE sp_MSreplcheck_publish AS if is_srvrolemember('sysadmin') <> 1 and is_member ('db_owner') <> 1 BEGIN RAISERROR (21050, 14, -1) RETURN (1) END GO raiserror('Creating procedure sp_MSlocktable', 0,1) go CREATE PROCEDURE sp_MSlocktable @ownername sysname, @tablename sysname AS declare @ispublisher bit declare @retcode int declare @procname sysname declare @objid int declare @qualified_name nvarchar(255) select @qualified_name = QUOTENAME(@ownername) + '.' + QUOTENAME(@tablename) select @objid = object_id(@qualified_name) if @objid is NULL begin select @ispublisher = 0 select @qualified_name = QUOTENAME(@tablename) select @objid = object_id(@qualified_name) end else select @ispublisher = 1 exec dbo.sp_MSreplcheck_connection @objid = @objid select @procname = select_proc from sysmergearticles where objid = @objid and select_proc is not NULL exec @retcode = @procname @type = 7 -- exec ('select count(*) from ' + @ownername + '.' + @tablename + ' (tablock holdlock) where 1 = 2') go exec dbo.sp_MS_marksystemobject sp_MSlocktable go grant execute on dbo.sp_MSlocktable to public go raiserror('Creating procedure sp_MSenumcolumns', 0,1) go CREATE PROCEDURE sp_MSenumcolumns @pubid uniqueidentifier, @artid uniqueidentifier AS declare @retcode int declare @procname sysname select @procname = select_proc from sysmergearticles where pubid = @pubid and artid = @artid exec @retcode = @procname @type =6 go exec dbo.sp_MS_marksystemobject sp_MSenumcolumns go grant execute on dbo.sp_MSenumcolumns to public go /* ** Get pubid through connection_ID and check permission of this publication */ raiserror('Creating procedure sp_MSsetaccesslist', 0,1) go CREATE PROCEDURE sp_MSsetaccesslist @publication sysname, @publisher sysname, @publisher_db sysname AS declare @pubid uniqueidentifier select @pubid = pubid from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db exec dbo.sp_MSreplcheck_connection @publication = @publication, @pubid = @pubid, @is_init = 1 go exec dbo.sp_MS_marksystemobject sp_MSsetaccesslist go grant execute on dbo.sp_MSsetaccesslist to public go raiserror('Creating procedure sp_MSreplcheck_connection', 0,1) go CREATE PROCEDURE sp_MSreplcheck_connection @publication sysname = NULL, @artid uniqueidentifier = NULL, @repid uniqueidentifier = NULL, @pubid uniqueidentifier = NULL, @objid int = NULL, @tablenick int = NULL, @is_init bit = 0 AS -- sysadmin or db_owner have access if is_srvrolemember('sysadmin') = 1 or is_member('db_owner') = 1 return 0 declare @retcode int declare @cached_id uniqueidentifier -- Need login_time to uniquely identify a connection. declare @login_time datetime select @login_time = login_time from master..sysprocesses where spid = @@spid select @cached_id = pubid from tempdb.dbo.MSpublisher_access where spid = @@spid and login_time = @login_time -- If spid with publication in the cache, return success. if @cached_id is null begin -- This stored procedure might be called by common sprocs at -- both the publisher and the subscriber by the merge agent -- The merge agent will call this sp with @is_init = 1 before -- any other calls to the publisher. All the other calls will -- set @is_init to 0. if @is_init = 0 begin RAISERROR (14126, 11, -1) return (1) end else begin exec @retcode = dbo.sp_MSreplcheck_pull @publication = @publication, @pubid = @pubid if @retcode <> 0 or @@error <> 0 return (1) end end else begin if @pubid is not null begin if @pubid <> @cached_id begin RAISERROR (14126, 11, -1) return (1) end end else if @tablenick is not null begin if not exists (select * from sysmergearticles where pubid = @cached_id and nickname = @tablenick) begin RAISERROR (14126, 11, -1) return (1) end end else if @artid is not null begin if not exists (select * from sysmergearticles where pubid = @cached_id and artid = @artid) begin RAISERROR (14126, 11, -1) return (1) end end else if @objid is not null begin if not exists (select * from sysmergearticles where pubid = @cached_id and objid=@objid) begin RAISERROR (14126, 11, -1) return (1) end end else if @publication is not null begin if not exists (select * from sysmergepublications where pubid = @cached_id and name = @publication) begin RAISERROR (14126, 11, -1) return (1) end end else if @repid is not null begin if not exists (select * from sysmergesubscriptions where pubid = @cached_id and subid = @repid) begin RAISERROR (14126, 11, -1) return (1) end end end GO exec dbo.sp_MS_marksystemobject sp_MSreplcheck_connection go grant execute on dbo.sp_MSreplcheck_connection to public go raiserror('Creating procedure sp_MSreplcheck_pull', 0,1) go CREATE PROCEDURE sp_MSreplcheck_pull ( @publication sysname, @raise_fatal_error bit = 1, @pubid uniqueidentifier = NULL ) AS -- sysadmin or db_owner have access if is_srvrolemember('sysadmin') = 1 or is_member('db_owner') = 1 return 0 -- Need login_time to uniquely identify a connection. declare @login_time datetime select @login_time = login_time from master..sysprocesses where spid = @@spid -- If spid with publication in the cache, return success. if exists (select * from tempdb.dbo.MSpublisher_access where spid = @@spid and login_time = @login_time and db_id = db_id() and publication = @publication) return (0) declare @has_access bit DECLARE @distribdb sysname DECLARE @distproc nvarchar (255) DECLARE @retcode int DECLARE @dist_rpcname sysname DECLARE @database sysname declare @login sysname select @login = suser_sname(suser_sid()) select @database = db_name() EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @dist_rpcname OUTPUT, @distribdb = @distribdb OUTPUT IF @retcode <> 0 or @@error <> 0 BEGIN RAISERROR (14071, 16, -1) return (1) END IF @retcode <> 0 OR @distribdb IS NULL OR @dist_rpcname IS NULL BEGIN RAISERROR (14071, 16, -1) return(1) END SELECT @distproc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSpublication_access' EXEC @retcode = @distproc @publisher = @@SERVERNAME, @publisher_db = @database, @publication = @publication, @operation = 'check', @login = @login, @has_access = @has_access output IF @@error <> 0 OR @retcode <> 0 BEGIN RAISERROR (14042, 16, -1) return (1) END if @has_access = 0 begin -- We don't have access if we reach here, return error IF @raise_fatal_error = 1 RAISERROR (21049, 14, -1, @login, @publication) ELSE RAISERROR (21049, 10, -1, @login, @publication) return(1) end ADD_CACHE: -- If we are here, we know that the connection has access and is not in the cache -- add it in to the cache. -- Clear the cache to keep it small. exec @retcode = dbo.sp_MSflush_access_cache if @retcode <> 0 or @@error <> 0 return (1) insert tempdb.dbo.MSpublisher_access (spid, db_id, publication, login_time, pubid) values (@@spid, db_id(), @publication, @login_time, @pubid) if @@error <> 0 return (1) return (0) GO raiserror('Creating procedure sp_MSreplcheck_qv', 0, 1) GO create procedure sp_MSreplcheck_qv as begin set nocount on declare @qv_replication varchar(10) declare @qv_engine varchar(10) declare @qv_value_replication integer declare @qv_value_engine integer select @qv_replication = '2745196162', @qv_engine = '845129433' exec @qv_value_replication = master.dbo.xp_qv @qv_replication if @@ERROR <> 0 select @qv_value_replication = 1 exec @qv_value_engine = master.dbo.xp_qv @qv_engine if @@ERROR <> 0 select @qv_value_engine = 1 -- magic number 1 assumes least common setting on all failure states select isnull( @qv_value_replication, 1 ) as VALUE_REPLICATION, isnull( @qv_value_engine, 1 ) as VALUE_ENGINE end go exec dbo.sp_MS_marksystemobject sp_MSreplcheck_qv go grant execute on dbo.sp_MSreplcheck_qv to public go raiserror('Creating procedure sp_reinitmergepullsubscription', 0, 1) GO create procedure sp_reinitmergepullsubscription @publisher sysname = 'all', @publisher_db sysname = 'all', @publication sysname = 'all' AS declare @schemaversion int declare @schematype smallint declare @schemaguid uniqueidentifier declare @pubid uniqueidentifier declare @subid uniqueidentifier declare @artid uniqueidentifier /* ** Replace 'all' with '%' */ if LOWER(@publication) = 'all' SELECT @publication = '%' if LOWER(@publisher) = 'all' SELECT @publisher = '%' if LOWER(@publisher_db) = 'all' SELECT @publisher_db = '%' /* ** At subscriber side, we need to qualify the publication with server name and database name */ IF NOT EXISTS (SELECT * FROM sysmergepublications WHERE name LIKE @publication and ((@publisher = N'%') or (UPPER(publisher) = UPPER(@publisher))) and publisher_db like @publisher_db) BEGIN IF @publication = '%' RAISERROR (14008, 11, -1) ELSE RAISERROR (20026, 11, -1, @publication) RETURN (1) END Declare SYN_CUR CURSOR LOCAL FAST_FORWARD FOR select subs.subid from sysmergepublications pubs, sysmergesubscriptions subs where pubs.name LIKE @publication AND ((@publisher = N'%') OR (UPPER(pubs.publisher) = UPPER(@publisher))) AND pubs.publisher_db LIKE @publisher_db AND pubs.pubid=subs.pubid AND subs.pubid<>subs.subid FOR READ ONLY open SYN_CUR fetch SYN_CUR into @subid while (@@fetch_status<>-1) BEGIN update MSmerge_replinfo set schemaversion=-1, recgen = NULL, recguid=NULL, sentgen=NULL, sentguid = NULL where repid=@subid -- use -1 to replace 0 fetch next from SYN_CUR into @subid -- so that it won't be treated as a new susbscription END close SYN_CUR deallocate SYN_CUR -- Forget that publisher ever sent us any generations. They must be resent. -- Publication cleanup will remove the genhistory rows. if @publication = '%' -- get them all update MSmerge_replinfo set recgen = NULL, recguid=NULL, sentgen=NULL, sentguid = NULL else begin select @pubid = pubid from sysmergepublications where name = @publication update MSmerge_replinfo set recgen = NULL, recguid=NULL, sentgen=NULL, sentguid = NULL where repid in (select subid from sysmergesubscriptions where pubid = @pubid) end GO exec dbo.sp_MS_marksystemobject sp_reinitmergepullsubscription go grant execute on dbo.sp_reinitmergepullsubscription to public raiserror('Creating procedure sp_MSreplcheck_subscribe', 0,1) go CREATE PROCEDURE sp_MSreplcheck_subscribe AS /* ** Only the System Administratr (SA) or the Database Owner (dbo) ** can subscribe from the subscribing database. */ if is_srvrolemember('sysadmin') <> 1 and is_member ('db_owner') <> 1 BEGIN RAISERROR (21050, 14, -1) RETURN (1) END GO raiserror('Creating procedure sp_MSreplicationcompatlevel', 0,1) GO create procedure sp_MSreplicationcompatlevel @dbname sysname, @cmptlevel float(8) As declare @is_distdb smallint select @is_distdb = 0 IF EXISTS (select * from msdb..sysobjects where name='MSdistributiondbs') begin IF EXISTS (SELECT * FROM msdb..MSdistributiondbs where name=@dbname) select @is_distdb = 1 end /* ** Parameter check ** @dbname */ IF NOT EXISTS (SELECT * FROM master.dbo.sysdatabases WHERE name = @dbname) BEGIN RAISERROR(15010, 16, -1, @dbname) RETURN(2) END /* ** Parameter check. NOTE ** @cmptlevel */ IF @cmptlevel<6.0 BEGIN RAISERROR(20060,16,-1) RETURN(2) END /* ** If cmptlevel is lower than 7.0, special attention should be paid. ** If current database is a distribution database or is involed in merge ** replication, then it can not be set to a level lower than 7.0. */ create table #tmp (any_merge smallint NOT NULL) insert into #tmp exec ('select count(*) from ' + @dbname + '..sysobjects where name=' + '''sysmergesubscriptions''' ) if (exists(select any_merge from #tmp where any_merge>0) OR @is_distdb = 1) AND (@cmptlevel<7.0) begin drop table #tmp return 1 end else begin drop table #tmp return 0 end go exec dbo.sp_MS_marksystemobject sp_MSreplicationcompatlevel go raiserror('Creating procedure sp_MSgenreplnickname', 0,1) GO create procedure sp_MSgenreplnickname @srcguid uniqueidentifier, /* Source Guid */ @repnick int output /* nickname */ as declare @binguid binary(16) declare @nickname int set @binguid = convert(binary(16), @srcguid) select @nickname = convert(int, convert(binary(4),substring( convert(nchar(8),@binguid), 1, 2))) while exists (select replnickname from MSmerge_replinfo where replnickname = @nickname) select @nickname = @nickname + 1 select @repnick = @nickname go exec dbo.sp_MS_marksystemobject sp_MSgenreplnickname go grant execute on dbo.sp_MSgenreplnickname to public raiserror('Creating procedure sp_MSmergesubscribedb', 0,1) GO CREATE PROCEDURE sp_MSmergesubscribedb( @value sysname ) AS SET NOCOUNT ON /* ** Declarations. */ declare @retcode int /* ** Security Check */ EXEC @retcode = dbo.sp_MSreplcheck_subscribe IF @@ERROR <> 0 or @retcode <> 0 RETURN(1) /* ** Initialization */ /* ** Parameter check ** @value */ IF LOWER(@value) NOT IN ('true','false') BEGIN RAISERROR(14137,16,-1) RETURN(1) END IF LOWER(@value) = 'true' BEGIN execute @retcode = dbo.sp_MScreate_mergesystables if @@ERROR <> 0 or @retcode <> 0 begin return (1) end END -- We assume we will do nothing about disabling a subscriber GO exec dbo.sp_MS_marksystemobject sp_MSmergesubscribedb go grant execute on dbo.sp_MSmergesubscribedb to public go raiserror('Creating procedure sp_MSenumallpublications', 0,1) go CREATE PROCEDURE sp_MSenumallpublications( @publisherdb sysname = '%', @replication_type tinyint = 1, @agent_login sysname = NULL, @security_check bit = 1 -- Security check by default so that things depending on security -- filtering will not break immediately ) as set nocount on declare @dbname sysname declare @trans tinyint declare @merge tinyint declare @3rdparty tinyint declare @retcode int DECLARE @dist_rpcname sysname declare @distribdb sysname declare @login sysname declare @proc nvarchar(255) declare @distbit int declare @is_user_admin bit declare @same_as_user bit -- UI: If the distributor is not installed, return empty result if not exists (SELECT * FROM master..sysservers WHERE srvstatus & 8 <> 0) return (0) /* Initializations */ select @trans = 1 select @merge = 2 select @3rdparty = 0 select @login = suser_sname(suser_sid()) SELECT @distbit = 16 select @is_user_admin = 0 select @same_as_user = 0 -- Get publication list create table #pubdbs (publisher_db sysname NOT NULL, replication_type int NOT NULL) /* Return everything if @replication_type is not in (@3rdparty, @trans, @merge) */ if not @replication_type in (@3rdparty, @trans, @merge) select @replication_type = null if @replication_type = @trans or @replication_type is null insert into #pubdbs select name, @trans from master..sysdatabases where name like @publisherdb and category & 1 <> 0 and (isnull(databaseproperty(name, N'issuspect'), 0) = 0 and isnull(databaseproperty(name, N'isshutdown'), 0) = 0) and has_dbaccess(name) = 1 if @replication_type = @merge or @replication_type is null insert into #pubdbs select name, @merge from master..sysdatabases where name like @publisherdb and category & 4 <> 0 and (isnull(databaseproperty(name, N'issuspect'), 0) = 0 and isnull(databaseproperty(name, N'isshutdown'), 0) = 0) and has_dbaccess(name) = 1 if @replication_type = @3rdparty insert into #pubdbs select name, @3rdparty from master..sysdatabases where name like @publisherdb and category & @distbit <> 0 and (isnull(databaseproperty(name, N'issuspect'), 0) = 0 and isnull(databaseproperty(name, N'isshutdown'), 0) = 0) and has_dbaccess(name) = 1 create table #MSenumpublications (publisher_db sysname NOT NULL, publication sysname NOT NULL, replication_type tinyint NOT NULL, immediate_sync bit NOT NULL, allow_pull bit NOT NULL, allow_anonymous bit NOT NULL, enabled_for_internet bit NOT NULL, repl_freq tinyint NOT NULL, immediate_sync_ready bit NOT NULL, allow_sync_tran bit NOT NULL, independent_agent bit NOT NULL, is_db_owner int NOT NULL, thirdparty_flag bit NOT NULL, vendor_name sysname NULL, publisher sysname NULL, description nvarchar(255) NULL, distribution_db sysname NULL) declare hCForEachDb CURSOR LOCAL FAST_FORWARD FOR select publisher_db, replication_type from #pubdbs FOR READ ONLY open hCForEachDb fetch hCForEachDb into @dbname, @replication_type /* Loop for each database */ while (@@fetch_status >= 0) begin if (@replication_type) = @trans select @proc = quotename(@dbname) + '.dbo.sp_MSenumtranpublications' else if (@replication_type) = @merge select @proc = quotename(@dbname) + '.dbo.sp_MSenummergepublications' else if (@replication_type) = @3rdparty select @proc = quotename(@dbname) + '.dbo.sp_MSenum3rdpartypublications' insert into #MSenumpublications exec @retcode = @proc if @@ERROR <> 0 or @retcode <> 0 return (1) fetch hCForEachDb into @dbname, @replication_type end /* while FETCH_SUCCESS */ -- Prepare for filtering. create table #admin_publications (publisher_db sysname not null, publication sysname not null) create table #agent_publications (publisher_db sysname not null, publication sysname not null) IF (@security_check <> 0) BEGIN EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @dist_rpcname OUTPUT, @distribdb = @distribdb OUTPUT IF @@error <> 0 OR @retcode <> 0 RETURN (1) IF @distribdb is null BEGIN RAISERROR (14071, 16, -1) RETURN (1) END SELECT @proc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSpublication_access' -- Optimization if is_srvrolemember('sysadmin') = 1 select @is_user_admin = 1 else insert into #admin_publications EXEC @retcode = @proc @publisher = @@SERVERNAME, @operation = 'get_publications', @login = @login if suser_sid(@agent_login) = suser_sid() select @same_as_user = 1 else insert into #agent_publications EXEC @retcode = @proc @publisher = @@SERVERNAME, @operation = 'get_publications', @login = @agent_login END -- IF (@security_check <> 0) -- workaround of a server bug of leaving tran open when -- insert into exec failed. while(@@trancount <> 0) commit tran DONE2: select pub.publisher_db, pub.publication, pub.replication_type, pub.immediate_sync, pub.allow_pull, pub.allow_anonymous, pub.enabled_for_internet, pub.repl_freq, pub.immediate_sync_ready, pub.allow_sync_tran, pub.independent_agent, N'agent_access' = case when (@same_as_user = 1 or exists (select * from #agent_publications agent where agent.publisher_db = pub.publisher_db and agent.publication = pub.publication)) then convert(bit,1) else convert(bit,0) end, pub.thirdparty_flag, pub.vendor_name, pub.publisher, pub.description, pub.distribution_db from #MSenumpublications pub where exists (select * from #admin_publications admin where pub.publisher_db = admin.publisher_db and pub.publication = admin.publication) or @security_check = 0 or pub.is_db_owner = 1 or @is_user_admin = 1 order by pub.publication, pub.publisher_db return (0) go grant execute on dbo.sp_MSenumallpublications to public go raiserror('Creating procedure sp_MSenumtranpublications', 0,1) go CREATE PROCEDURE sp_MSenumtranpublications as set nocount on select db_name(), name, 1, immediate_sync, allow_pull, allow_anonymous, enabled_for_internet, repl_freq, immediate_sync_ready, allow_sync_tran, independent_agent, is_member('db_owner'), 0, -- thirdparty 'Microsoft SQL Server', @@servername, description, convert(sysname, null) from syspublications pubs where exists (select * from sysarticles art where pubs.pubid = art.pubid) and status <> 0 go raiserror('Creating procedure sp_MSenummergepublications', 0,1) go CREATE PROCEDURE sp_MSenummergepublications as set nocount on select db_name(), name, 2, 1, allow_pull, allow_anonymous, enabled_for_internet, 0, snapshot_ready, 0, 1, is_member('db_owner'), 0, --thirdparty 'Microsoft SQL Server', publisher, description, convert(sysname, null) from sysmergepublications where status <> 0 go raiserror('Creating procedure sp_MSenum3rdpartypublications', 0,1) go CREATE PROCEDURE sp_MSenum3rdpartypublications as set nocount on select pubs.publisher_db, publication, case when publication_type <> 2 then 1 else 2 end, --replication_type, 1 tran, 2 merge ; pub type 0 tran 1 snapshot, 2 merge immediate_sync, allow_pull, allow_anonymous, 0, --enabled_for_internet, case when publication_type = 0 then 0 else 1 end, --repl_freq, 1, --immediate_sync_ready, always return 1 so that UI will not warn 0, -- allow_sync_tran, independent_agent, is_member('db_owner'), 1, --thirdparty pubs.vendor_name, srv.srvname, pubs.description, db_name() from MSpublications pubs, master..sysservers srv where exists (select * from MSarticles art where pubs.publication_id = art.publication_id) and thirdparty_flag <> 0 and publisher_id = srvid go dump tran master with no_log GO raiserror('Creating procedure sp_reinitpullsubscription', 0,1) go CREATE PROCEDURE sp_reinitpullsubscription ( @publisher sysname, @publisher_db sysname, @publication sysname = 'all' /* publication name */ )AS SET NOCOUNT ON declare @subscription_type int declare @sync_type tinyint /* ** Security Check */ declare @retcode int EXEC @retcode = dbo.sp_MSreplcheck_subscribe IF @@ERROR <> 0 or @retcode <> 0 RETURN(1) /* ** Initializations. */ /* ** Parameter Check: @publisher ** Check to make sure that the publisher is define */ IF @publisher IS NULL BEGIN RAISERROR (14043, 16, -1, '@publisher') RETURN (1) END IF @publisher = 'all' BEGIN RAISERROR (14136, 16, -1) RETURN (1) END EXECUTE @retcode = dbo.sp_validname @publisher IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) /* ** Parameter Check: @publisher_db */ IF @publisher_db IS NULL BEGIN RAISERROR (14043, 16, -1, '@publisher_db') RETURN (1) END IF @publisher_db = 'all' BEGIN RAISERROR (14136, 16, -1) RETURN (1) END EXECUTE @retcode = dbo.sp_validname @publisher_db IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) /* ** Parameter Check: @publication ** */ IF @publication IS NULL BEGIN RAISERROR (14043, 16, -1, '@publication') RETURN (1) END IF LOWER(@publication) = 'all' select @publication = '%' ELSE BEGIN EXECUTE @retcode = dbo.sp_validname @publication IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) END IF NOT EXISTS (SELECT * FROM MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db = @publisher_db AND publication like @publication ) BEGIN RAISERROR(14135, 11, -1, @publisher, @publisher_db, @publication) RETURN(1) END select @sync_type = immediate_sync from MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db = @publisher_db AND publication like @publication IF @sync_type = 0 BEGIN raiserror(21059, 16, -1) return (1) END UPDATE MSreplication_subscriptions set transaction_timestamp = 0x00, subid = NULL WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db = @publisher_db AND publication like @publication if @@ERROR<>0 RETURN (1) GO grant execute on dbo.sp_reinitpullsubscription to public go raiserror('Creating procedure sp_addpullsubscription', 0,1) go CREATE PROCEDURE sp_addpullsubscription ( @publisher sysname, @publisher_db sysname, @publication sysname, /* publication name */ @independent_agent nvarchar(5) = 'true', /* true or false */ @subscription_type nvarchar(9) = 'anonymous', /* subscription_type, pull or anonymous */ @description nvarchar(100) = NULL, -- SyncTran @update_mode nvarchar(15) = 'read only', -- Can be 'read only', 'sync tran' @immediate_sync bit = 1 ) AS SET NOCOUNT ON /* ** Declarations. */ DECLARE @retcode int DECLARE @subscription_type_id int /* 1 = pull, 2 = anonymous */ DECLARE @independent_agent_id bit -- SyncTran DECLARE @update_mode_id tinyint /* ** Check if replication components are installed on this server */ exec @retcode = dbo.sp_MS_replication_installed if (@retcode <> 1) begin return (1) end /* ** Security Check */ EXEC @retcode = dbo.sp_MSreplcheck_subscribe IF @@ERROR <> 0 or @retcode <> 0 RETURN(1) /* ** Initializations. */ /* ** Parameter Check: @publisher ** Check to make sure that the publisher is define */ IF @publisher IS NULL BEGIN RAISERROR (14043, 16, -1, '@publisher') RETURN (1) END IF @publisher = 'all' BEGIN RAISERROR (14136, 16, -1) RETURN (1) END EXECUTE @retcode = dbo.sp_validname @publisher IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) /* ** Parameter Check: @publisher_db */ IF @publisher_db IS NULL BEGIN RAISERROR (14043, 16, -1, '@publisher_db') RETURN (1) END IF @publisher_db = 'all' BEGIN RAISERROR (14136, 16, -1) RETURN (1) END EXECUTE @retcode = dbo.sp_validname @publisher_db IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) /* ** Parameter Check: @publication ** */ IF @publication IS NULL BEGIN RAISERROR (14043, 16, -1, '@publication') RETURN (1) END IF @publication = 'all' BEGIN RAISERROR (14136, 16, -1) RETURN (1) END EXECUTE @retcode = dbo.sp_validname @publication IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) IF @independent_agent IS NULL OR LOWER(@independent_agent) NOT IN ('true', 'false') BEGIN RAISERROR (14148, 16, -1, '@independent_agent') RETURN (1) END IF LOWER(@independent_agent) = 'true' SELECT @independent_agent_id = 1 ELSE SELECT @independent_agent_id = 0 /* ** Parameter Check: @subscription_type ** The @status value can be: ** ** type_id type ** ====== ======== ** 0 push ** 1 pull ** 2 anonymous ** ** Note: @subscription_type = push is only used by distribution agents */ IF @subscription_type IS NULL OR LOWER(@subscription_type) NOT IN ('push', 'pull','anonymous') BEGIN RAISERROR (20016, 16, -1) RETURN (1) END IF LOWER(@subscription_type) = 'pull' SELECT @subscription_type_id = 1 ELSE IF LOWER(@subscription_type) = 'anonymous' SELECT @subscription_type_id = 2 ELSE SELECT @subscription_type_id = 0 IF @independent_agent_id = 0 AND @subscription_type_id = 2 BEGIN RAISERROR (21026, 16, -1) RETURN (1) END -- SyncTran /* ** Parameter check: @update_mode */ IF @update_mode IS NULL OR LOWER(@update_mode) NOT IN ('read only', 'sync tran') BEGIN RAISERROR (20502, 16, -1, '@update_mode') RETURN (1) END IF LOWER(@update_mode) = 'sync tran' begin SELECT @update_mode_id = 1 if @subscription_type_id = 2 -- Anonymous subscriptions should not be allowed to begin -- subscribe with 'synctran option' RAISERROR (21057, 16, -1) RETURN (1) end end ELSE SELECT @update_mode_id = 0 -- SyncTran begin tran save TRAN addpullsubscription /* ** Check to see if MSreplication_subscriptions and MSsubscription_properties ** tables exists. ** If not, create it. */ exec @retcode = dbo.sp_MScreate_sub_tables @tran_sub_table = 1, @property_table = 1 IF @@ERROR <> 0 or @retcode <> 0 goto UNDO /* ** Check to make sure that the subscription does not already exist */ -- Delete the push subscription entry first. If may be obsolete and left by -- defunct push agents delete MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db = @publisher_db AND publication = @publication and subscription_type = 0 if @@error <> 0 goto UNDO -- It is not allowed to subscribe to the same publication twice even with -- differnet publication type. IF EXISTS (SELECT * FROM MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db = @publisher_db AND publication = @publication) /* OR -- If the subscription is already added by the distribution agent (@independent_agent_id = 0 AND (publication IS NULL OR publication = ''))) AND independent_agent = @independent_agent_id AND subscription_type = @subscription_type_id) */ BEGIN RAISERROR (14058, 16, -1) GOTO UNDO END /* ** Add the subscription */ INSERT MSreplication_subscriptions (publisher, publisher_db, publication, independent_agent, subscription_type, distribution_agent, description, time, transaction_timestamp, -- SyncTran update_mode, immediate_sync) VALUES (@publisher, @publisher_db, @publication, @independent_agent_id, @subscription_type_id, NULL, @description, getdate(), 0, -- SyncTran @update_mode_id, @immediate_sync ) IF @@ERROR <> 0 BEGIN RAISERROR (14057, 16, -1) GOTO UNDO END COMMIT TRAN RETURN (0) UNDO: IF @@TRANCOUNT > 0 begin ROLLBACK TRAN addpullsubscription COMMIT TRAN end return 1 go raiserror('Creating procedure sp_addpullsubscription_agent', 0,1) go CREATE PROCEDURE sp_addpullsubscription_agent ( @publisher sysname, @publisher_db sysname, @publication sysname, /* publication name */ @subscriber sysname = NULL, @subscriber_db sysname = NULL, @subscriber_security_mode int = NULL, /* 0 standard; 1 integrated */ @subscriber_login sysname = NULL, @subscriber_password sysname = NULL, @distributor sysname = @publisher, @distribution_db sysname = NULL, @distributor_security_mode int = 0, @distributor_login sysname = 'sa', @distributor_password sysname = NULL, @optional_command_line nvarchar(4000) = '', @frequency_type int = 2 , /* 2== OnDemand */ @frequency_interval int = 1, @frequency_relative_interval int = 1, @frequency_recurrence_factor int = 1, @frequency_subday int = 1, @frequency_subday_interval int = 1 , @active_start_time_of_day int = 0, @active_end_time_of_day int = 0, @active_start_date int = 0, @active_end_date int =0, @distribution_jobid binary(16) = NULL OUTPUT, @encrypted_distributor_password bit = 0, @enabled_for_syncmgr nvarchar(5) = 'false', /* Enabled for SYNCMGR: true or false */ @ftp_address sysname = NULL, @ftp_port int = NULL, @ftp_login sysname = NULL, @ftp_password sysname = NULL ) AS SET NOCOUNT ON /* ** Declarations. */ DECLARE @command nvarchar(4000) DECLARE @name nvarchar(255) DECLARE @retcode int DECLARE @subscription_type_id int /* 1 = pull, 2 = anonymous */ DECLARE @independent_agent_id bit DECLARE @distribution_agent nvarchar(100) DECLARE @category_name sysname DECLARE @platform_nt binary DECLARE @subscriber_enc_password sysname select @platform_nt = 0x1 /* ** Security Check */ EXEC @retcode = dbo.sp_MSreplcheck_subscribe IF @@ERROR <> 0 or @retcode <> 0 RETURN(1) /* ** Initializations. */ -- Set null @optional_command_line to empty string to avoid string concat problem if @optional_command_line is null set @optional_command_line = '' IF @distributor_password = N'' select @distributor_password = NULL IF @ftp_password = N'' select @ftp_password = NULL /* ** Parameter Check: @publisher ** Check to make sure that the publisher is define */ IF @publisher IS NULL BEGIN RAISERROR (14043, 16, -1, '@publisher') RETURN (1) END EXECUTE @retcode = dbo.sp_validname @publisher IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) /* ** Parameter Check: @publisher_db */ IF @publisher_db IS NULL BEGIN RAISERROR (14043, 16, -1, '@publisher_db') RETURN (1) END EXECUTE @retcode = dbo.sp_validname @publisher_db IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) /* ** Parameter Check: @publication ** */ IF @publication IS NULL BEGIN RAISERROR (14043, 16, -1, '@publication') RETURN (1) END EXECUTE @retcode = dbo.sp_validname @publication IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) /* ** Parameter Check: @subscriber and @subscriber_db */ if @subscriber IS NULL or rtrim(@subscriber) = '' SELECT @subscriber = @@SERVERNAME if @subscriber_db IS NULL or rtrim(@subscriber_db) = '' SELECT @subscriber_db = DB_NAME() EXECUTE @retcode = dbo.sp_validname @subscriber IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) EXECUTE @retcode = dbo.sp_validname @subscriber_db IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) /* ** Check to see if MSreplictaion_subscriptions table exists. ** If so, copy it into the temp table */ IF NOT EXISTS (SELECT * FROM sysobjects WHERE type = 'U' AND name = 'MSreplication_subscriptions') BEGIN RAISERROR (20017, 16, -1) RETURN (1) END /* ** Check to make sure that the subscription does exist */ IF NOT EXISTS (SELECT * FROM MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db = @publisher_db AND publication = @publication) BEGIN RAISERROR (20017, 16, -1) RETURN (1) END SELECT @distribution_agent = NULL SELECT @independent_agent_id = independent_agent, @subscription_type_id = subscription_type, @distribution_agent = distribution_agent FROM MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db = @publisher_db AND publication = @publication /* Distribution agent for push subscriptions is at distributor side */ IF @subscription_type_id = 0 BEGIN RAISERROR (21001, 16, -1) RETURN (1) END IF @distribution_agent IS NOT NULL BEGIN RAISERROR (21002, 11, -1, @distribution_agent) RETURN (1) END -- Parameter check: @subscriber_security_mode if @subscriber_security_mode is null begin if ( platform() & @platform_nt ) = @platform_nt select @subscriber_security_mode = 1 else select @subscriber_security_mode = 0 end if ( ( platform() & @platform_nt ) <> @platform_nt and @subscriber_security_mode = 1 ) begin RAISERROR(21038, 16, -1) RETURN (1) end if (@subscription_type_id <> 0) begin if (@subscriber_security_mode = 0) and (@subscriber_login IS NULL or rtrim(@subscriber_login) = '') begin raiserror(3217, 16, -1, '@subscriber_login') return (1) end end IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U') begin raiserror(14027, 16, -1, 'The subscription properties table ''MSsubscription_properties''') return (1) end /* ** Construct unique name */ if @subscriber is NULL select @subscriber = '' if @subscriber_db is NULL select @subscriber_db = '' SELECT @name = CONVERT(nvarchar(23),@publisher ) + '-' + CONVERT(nvarchar(23),@publisher_db) + '-' + CONVERT(nvarchar(23),@publication) + '-' + CONVERT(nvarchar(23),@subscriber) + '-' + CONVERT(nvarchar(23),@subscriber_db) + '- 0' BEGIN TRAN /* ** If the publication is independent agent type or it is the first ** subscription on the non independent agent publications. */ IF @independent_agent_id = 1 OR NOT EXISTS (SELECT * FROM MSreplication_subscriptions WHERE UPPER(@publisher) = UPPER(publisher) and @publisher_db = publisher_db and agent_id IS NOT NULL and independent_agent = 0) BEGIN /* Construct agent command */ SELECT @command = '-Publisher ' + @publisher + ' ' SELECT @command = @command + '-PublisherDB ' + QUOTENAME(@publisher_db) + ' ' IF @independent_agent_id = 1 SELECT @command = @command + '-Publication ' + QUOTENAME(@publication) + ' ' SELECT @command = @command + '-Distributor ' + QUOTENAME(@distributor) + ' ' /* Use -Xdatabase to save command line space We can not use -Xserver for distribution because SQLExec will valid the server to be in sysservers. SELECT @command = @command + '-DistributionDB ' + QUOTENAME(@distribution_db) + ' ' */ SELECT @command = @command + '-SubscriptionType ' + convert(nvarchar(10),@subscription_type_id) + ' ' SELECT @command = @command + '-Subscriber ' + QUOTENAME(@subscriber) + ' ' select @command = @command + '-SubscriberSecurityMode ' + convert(nvarchar(10),@subscriber_security_mode) + ' ' if @subscriber_login is not NULL select @command = @command + '-SubscriberLogin ' + quotename(@subscriber_login) + ' ' if @subscriber_password is not NULL begin set @subscriber_enc_password = @subscriber_password exec @retcode = master.dbo.xp_repl_encrypt @subscriber_enc_password OUTPUT select @command = @command + '-SubscriberEncryptedPassword ' + quotename(@subscriber_enc_password) + ' ' end SELECT @command = @command + '-SubscriberDB ' + QUOTENAME(@subscriber_db) + ' ' /* ** make sure the command line is not truncated */ /* Use datalength because len doesn't count the last space in @command */ IF (datalength(@command) + datalength(@optional_command_line)) > 8000 BEGIN RAISERROR(20018, 16, -1) RETURN(1) END SELECT @command = @command + @optional_command_line -- Get Distribution category name (assumes category_id = 10) select @category_name = name FROM msdb.dbo.syscategories where category_id = 10 EXEC @retcode = dbo.sp_MSadd_repl_job @name = @name, @subsystem = 'Distribution', @server = @@SERVERNAME, @databasename = @distribution_db, @enabled = 1, @freqtype = @frequency_type, @freqinterval = @frequency_interval, @freqsubtype = @frequency_subday, @freqsubinterval = @frequency_subday_interval, @freqrelativeinterval = @frequency_relative_interval, @freqrecurrencefactor = @frequency_recurrence_factor, @activestartdate = @active_start_date, @activeenddate = @active_end_date, @activestarttimeofday = @active_start_time_of_day, @activeendtimeofday = @active_end_time_of_day, @command = @command, @category_name = @category_name, @retryattempts = 10, @retrydelay = 1, @job_id = @distribution_jobid OUTPUT IF @@ERROR <> 0 or @retcode <> 0 BEGIN IF @@TRANCOUNT = 1 ROLLBACK TRAN ELSE COMMIT TRAN RETURN(1) END END if (@subscription_type_id = 1) OR (@subscription_type_id = 2) BEGIN IF NOT EXISTS (select * from MSsubscription_properties where UPPER(publisher) = UPPER(@publisher) and publisher_db = @publisher_db and publication = @publication) BEGIN -- 0 transactional -- 1 snapshot -- 2 merge IF (@encrypted_distributor_password = 0) -- Encrypt the password BEGIN EXEC @retcode = master.dbo.xp_repl_encrypt @distributor_password OUTPUT IF @@error <> 0 OR @retcode <> 0 return 1 END INSERT INTO MSsubscription_properties (publisher, publisher_db, publication, publication_type, publisher_login,publisher_password, publisher_security_mode, distributor, distributor_login, distributor_password, distributor_security_mode, ftp_address, ftp_port, ftp_login, ftp_password) values (@publisher, @publisher_db, @publication, 0, NULL, NULL, 1, @distributor, @distributor_login, @distributor_password, @distributor_security_mode, @ftp_address, @ftp_port, @ftp_login, @ftp_password) IF @@ERROR <> 0 BEGIN IF @@TRANCOUNT = 1 ROLLBACK TRAN ELSE COMMIT TRAN RETURN(1) END END ELSE BEGIN update MSsubscription_properties set distributor = @distributor, distributor_login = @distributor_login, distributor_password = @distributor_password, distributor_security_mode = @distributor_security_mode where UPPER(publisher) = UPPER(@publisher) and publisher_db = @publisher_db and publication = @publication END IF @@ERROR <> 0 BEGIN IF @@TRANCOUNT = 1 ROLLBACK TRAN ELSE COMMIT TRAN RETURN(1) END END /* If we do not have independent agents , i.e. independent_agent=0, but there is already a row for that publisher and that publisher database with a NOT null distribution_agent_id, then set the @distribution_jobid to that id. Note that if there are no rows returned, the value of the variable does not change, which is what we want. There should never be more than one row ever returned for this query - but will use TOP 1 to insist that is the case. */ SELECT DISTINCT @distribution_jobid=agent_id FROM MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db = @publisher_db AND agent_id IS NOT NULL AND independent_agent=0 UPDATE MSreplication_subscriptions SET distribution_agent = @name, agent_id = @distribution_jobid WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db = @publisher_db AND publication = @publication AND (subscription_type = 1 /* pull*/ OR subscription_type = 2) /*anonymous*/ IF @@ERROR <> 0 BEGIN IF @@TRANCOUNT = 1 ROLLBACK TRAN ELSE COMMIT TRAN RETURN(1) END /* Conditional support for MobileSync */ if LOWER(@enabled_for_syncmgr) = 'true' BEGIN /* Call sp_MSregistersubscription so that the subscription can be synchronized via MobileSync etc. */ declare @subscription_id uniqueidentifier set @subscription_id = convert(uniqueidentifier, @distribution_jobid) exec @retcode = dbo.sp_MSregistersubscription @replication_type = 1, @publisher = @publisher, @publisher_db = @publisher_db, @publication = @publication, @subscriber = @subscriber, @subscriber_db = @subscriber_db, @subscriber_security_mode = @subscriber_security_mode, @subscriber_login = @subscriber_login, @subscriber_password = @subscriber_password, @distributor = @distributor, @subscription_id = @subscription_id, @independent_agent = @independent_agent_id, @subscription_type = @subscription_type_id IF @@ERROR <> 0 or @retcode <> 0 BEGIN IF @@TRANCOUNT = 1 ROLLBACK TRAN ELSE COMMIT TRAN RETURN(1) END END COMMIT TRAN RETURN(0) GO raiserror('Creating procedure sp_helpsubscription_properties', 0,1) go CREATE PROCEDURE sp_helpsubscription_properties @publisher sysname = '%', @publisher_db sysname = '%', @publication sysname = '%', @publication_type int = NULL AS SET NOCOUNT ON declare @retcode int /* ** Security Check */ EXEC @retcode = dbo.sp_MSreplcheck_subscribe IF @@ERROR <> 0 or @retcode <> 0 RETURN(1) /* ** The logic is added here for the case where MSsubscription_properties table does not exist ** or relevant entry is not added because sp_addmergepullsubscription_agent or sp_addsubscription_agent ** is not called. */ IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U') begin return (0) end IF (@publication IS NULL) OR (@publication = '') select @publication = '%' IF @publication_type IS NULL BEGIN select publisher, publisher_db, publication, publication_type, publisher_login, publisher_password, publisher_security_mode, distributor, distributor_login, distributor_password, distributor_security_mode, ftp_address, isnull(ftp_port, 0), ftp_login, ftp_password from MSsubscription_properties where ((@publisher = N'%') or (UPPER(publisher) = UPPER(@publisher))) and publisher_db like @publisher_db and publication like @publication END ELSE BEGIN select publisher, publisher_db, publication, publication_type, publisher_login, publisher_password, publisher_security_mode, distributor, distributor_login, distributor_password, distributor_security_mode, ftp_address, isnull(ftp_port, 0), ftp_login, ftp_password from MSsubscription_properties where ((@publisher = N'%') or (UPPER(publisher) = UPPER(@publisher))) and publisher_db like @publisher_db and publication like @publication and publication_type = @publication_type END return (0) GO EXEC dbo.sp_MS_marksystemobject sp_helpsubscription_properties GO raiserror('Creating procedure sp_change_subscription_properties', 0,1) go CREATE PROCEDURE sp_change_subscription_properties @publisher sysname, @publisher_db sysname, @publication sysname, @property sysname, @value sysname AS SET NOCOUNT ON DECLARE @command nvarchar(2000) DECLARE @column_to_update nvarchar(64) DECLARE @value_string nvarchar(255) DECLARE @retcode int /* ** Security Check */ EXEC @retcode = dbo.sp_MSreplcheck_subscribe IF @@ERROR <> 0 or @retcode <> 0 RETURN(1) IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U') begin raiserror(14027, 16, -1, 'The subscription properties table ''MSsubscription_properties''') return (1) end if (@publisher is null) begin raiserror(14043, 16, -1, '@publisher') return (1) end if(@publisher_db is null) begin raiserror(14043, 16, -1, '@publisher_db') return (1) end IF (@property IS NULL) begin raiserror(14043, 16, -1, '@property') return (1) end ELSE IF (lower(@property) = 'publisher_login') select @column_to_update = 'publisher_login' ELSE IF (lower(@property) = 'publisher_password') begin select @column_to_update = 'publisher_password' EXEC @retcode = master.dbo.xp_repl_encrypt @value OUTPUT IF @@error <> 0 OR @retcode <> 0 return 1 end ELSE IF (lower(@property) = 'publisher_security_mode') select @column_to_update = 'publisher_security_mode' ELSE IF (lower(@property) = 'distributor') select @column_to_update = 'distributor' ELSE IF (lower(@property) = 'distributor_login') select @column_to_update = 'distributor_login' ELSE IF (lower(@property) = 'distributor_password') begin select @column_to_update = 'distributor_password' EXEC @retcode = master.dbo.xp_repl_encrypt @value OUTPUT IF @@error <> 0 OR @retcode <> 0 return 1 end ELSE IF (lower(@property) = 'distributor_security_mode') select @column_to_update = 'distributor_security_mode' ELSE IF (lower(@property) = 'ftp_address') select @column_to_update = 'ftp_address' ELSE IF (lower(@property) = 'ftp_port') select @column_to_update = 'ftp_port' ELSE IF (lower(@property) = 'ftp_login') select @column_to_update = 'ftp_login' ELSE IF (lower(@property) = 'ftp_password') select @column_to_update = 'ftp_password' ELSE BEGIN raiserror (3217, 16, -1, '@property') return(1) END IF (lower(@property) = 'distributor_security_mode') OR (lower(@property) = 'publisher_security_mode') BEGIN IF NOT ( @value = 0 or @value = 1 or (@value = 2 and lower(@property) = 'publisher_security_mode' )) BEGIN raiserror(3217, 16, -1, '@value') return(1) END select @value_string = convert(nvarchar(1), @value) END ELSE BEGIN IF (@value IS NULL) select @value_string = 'NULL' ELSE select @value_string = 'N''' + rtrim(@value) + '''' END if (@publication is null) or (@publication = '') begin select @publication = '%' end -- Password is encrypted. Cannot use dynamic query (exec (@cmd)) to update -- otherwise, the chars will be convert to '???' IF (lower(@property) = 'distributor_password') begin update MSsubscription_properties set distributor_password = @value where UPPER(publisher) = UPPER(@publisher) and publisher_db = @publisher_db and publication like @publication end ELSE IF (lower(@property) = 'publisher_password') begin update MSsubscription_properties set publisher_password = @value where UPPER(publisher) = UPPER(@publisher) and publisher_db = @publisher_db and publication like @publication end else begin select @command = N'update MSsubscription_properties set ' + @column_to_update + '= ' + @value_string + ' where UPPER(publisher) = UPPER(''' + @publisher + ''') and publisher_db = ''' + @publisher_db + ''' and publication like ''' + @publication + '''' EXEC (@command) end if @@error <> 0 return (1) else return (0) GO EXEC dbo.sp_MS_marksystemobject sp_change_subscription_properties GO grant execute on dbo.sp_change_subscription_properties to public raiserror('Creating procedure sp_MSget_pullsubsagent_owner', 0,1) go CREATE PROCEDURE sp_MSget_pullsubsagent_owner ( @publisher sysname, @publisher_db sysname, @publication sysname, /* publication name */ @owner_sid varbinary(85) OUTPUT ) AS declare @job_id uniqueidentifier set nocount on select @owner_sid = null if exists (select * from sysobjects where type = 'U' and name = 'MSreplication_subscriptions') begin -- Get the job_id corresponding to the publication select @job_id = agent_id from MSreplication_subscriptions where upper(@publisher) = upper(publisher) and @publisher_db = publisher_db and @publication = publication -- Using the job_id in MSsubscription properties to get the owner_sid -- in msdb..sysjobs select @owner_sid = owner_sid from msdb..sysjobs where @job_id = job_id end go exec dbo.sp_MS_marksystemobject 'sp_MSget_pullsubsagent_owner' raiserror('Creating procedure sp_droppullsubscription', 0,1) go CREATE PROCEDURE sp_droppullsubscription ( @publisher sysname, @publisher_db sysname, @publication sysname, /* publication name */ @reserved bit = 0 ) AS SET NOCOUNT ON /* ** Declarations. */ DECLARE @name nvarchar(255) DECLARE @retcode int DECLARE @agent_id binary(16) DECLARE @publisher_ex sysname /* Expression used in the cursor */ DECLARE @publisher_db_ex sysname /* Expression used in the cursor */ DECLARE @publication_ex sysname /* Expression used in the cursor */ DECLARE @expanded bit DECLARE @subscription_type_id int DECLARE @count_sub int DECLARE @drop_null_pub bit DECLARE @drop_push_bit bit DECLARE @push int DECLARE @implicit_transaction int DECLARE @close_cursor_at_commit int DECLARE @owner_sid varbinary(85) DECLARE @owner_name sysname DECLARE @qualified_publication_name nvarchar(512) /* ** Initialization */ SELECT @expanded = 0 SELECT @drop_null_pub = 0 SELECT @push = 0 /* ** Get the original set value off IMPLICIT_TRANSACTIONS and CURSOR_CLOSE_ON_COMMIT ** before set these two to off */ select @implicit_transaction = 0 select @close_cursor_at_commit = 0 IF (@reserved = 0) BEGIN SELECT @implicit_transaction = @@options & 2 SELECT @close_cursor_at_commit = @@options & 4 SET IMPLICIT_TRANSACTIONS OFF SET CURSOR_CLOSE_ON_COMMIT OFF END /* ** Security Check */ EXEC @retcode = dbo.sp_MSreplcheck_subscribe IF @@ERROR <> 0 or @retcode <> 0 RETURN(1) SELECT @drop_push_bit = 0 /* ** Check parameter and set expressions used by cursor */ /* Publisher */ IF @publisher IS NULL BEGIN RAISERROR (14043, 16, -1, '@publisher') RETURN (1) END IF @publisher = 'all' BEGIN SELECT @publisher_ex = '%' SELECT @expanded = 1 END ELSE BEGIN EXECUTE @retcode = dbo.sp_validname @publisher IF @retcode <> 0 RETURN (1) SELECT @publisher_ex = @publisher END /* Publisher_db */ IF @publisher_db IS NULL BEGIN RAISERROR (14043, 16, -1, '@publisher_db') RETURN (1) END IF @publisher_db = 'all' BEGIN SELECT @publisher_db_ex = '%' select @expanded = 1 END ELSE BEGIN /* EXECUTE @retcode = dbo.sp_validname @publisher_db IF @retcode <> 0 RETURN (1) */ SELECT @publisher_db_ex = @publisher_db END /* ** Publication ** '' is not a valid name but it may be in the publication name in the table. */ IF @publication IS NULL OR @publication = '' BEGIN SELECT @drop_null_pub = 1 END ELSE IF @publication = 'all' BEGIN SELECT @publication_ex = '%' SELECT @expanded = 1 SELECT @drop_null_pub = 1 END ELSE BEGIN EXECUTE @retcode = dbo.sp_validname @publication IF @retcode <> 0 RETURN (1) SELECT @publication_ex = @publication END /* ** Check to see if the subscription table exists */ IF NOT EXISTS (SELECT * FROM sysobjects WHERE type = 'U' AND name = 'MSreplication_subscriptions') BEGIN IF @expanded = 0 BEGIN RAISERROR(14135, 11, -1, @publisher, @publisher_db, @publication) RETURN(1) END ELSE RETURN(0) END IF @expanded = 0 BEGIN /* ** ** Check to see if the subscription entry exists */ IF NOT EXISTS (SELECT * FROM MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db = @publisher_db AND publication = @publication) BEGIN RAISERROR(14135, 11, -1, @publisher, @publisher_db, @publication) RETURN(1) END /* ** Make sure the subscription is not push type if @drop_push_bit = 0 */ IF @drop_push_bit = 0 BEGIN IF EXISTS (SELECT * FROM MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db = @publisher_db AND publication = @publication AND subscription_type = @push AND @drop_push_bit = 0) BEGIN RAISERROR(20017, 16, -1) RETURN(1) END END END ELSE /* ** Open a cursor and call recursively if ** parameters are expanded. */ BEGIN /* ** Note: Any expression check on null value is false ** @subscription_type_id is NULL <==> push ** @subscription_type_id is NOT NULL <==> non push */ DECLARE hCdroppullsubscription CURSOR LOCAL FAST_FORWARD FOR SELECT DISTINCT publisher, publisher_db, publication FROM MSreplication_subscriptions WHERE ((@publisher_ex = N'%') OR (UPPER(publisher) = UPPER(@publisher_ex))) AND publisher_db LIKE @publisher_db_ex AND (publication LIKE @publication_ex OR (@drop_null_pub = 1 AND publication IS NULL)) AND ((@drop_push_bit =0 AND subscription_type <> @push) OR @drop_push_bit = 1) FOR READ ONLY OPEN hCdroppullsubscription FETCH hCdroppullsubscription INTO @publisher, @publisher_db, @publication WHILE (@@fetch_status <> -1) BEGIN EXECUTE @retcode = dbo.sp_droppullsubscription @publisher = @publisher, @publisher_db = @publisher_db, @publication = @publication, @reserved = 1 FETCH hCdroppullsubscription INTO @publisher, @publisher_db, @publication END CLOSE hCdroppullsubscription DEALLOCATE hCdroppullsubscription RETURN (0) END /* ** Only members of the sysadmin group and the creator of the distribution ** agent can drop a pull subscription successfully. This behavior matches ** the behavior of the sysjobs_view. DBO of the subscriber database, ** sysadmins (owner is undefined) can drop a subscription if the owner_sid ** is null. */ EXEC sp_MSget_pullsubsagent_owner @publisher = @publisher, @publisher_db = @publisher_db, @publication = @publication, @owner_sid = @owner_sid OUTPUT IF (@owner_sid is not null AND (SUSER_SID() <> @owner_sid) AND (ISNULL(IS_SRVROLEMEMBER('sysadmin'),0) = 0)) BEGIN SELECT @owner_name = SUSER_SNAME(@owner_sid) SELECT @qualified_publication_name = @publisher + N':' + @publisher_db + N':' + @publication RAISERROR(21121,16,-1,@owner_name, @qualified_publication_name) RETURN (1) END /* ** Get the agent name, it may be dropped later. */ SELECT @agent_id = agent_id FROM MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db = @publisher_db AND publication = @publication begin tran save TRAN droppullsubscription /* ** Drop the subscription entry and the distribution agent if it exists */ /* ** If the distribution agent is not used anymore, ** drop the agent if it exists */ IF @agent_id IS NOT NULL BEGIN IF (EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @agent_id)) BEGIN EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @agent_id IF @@ERROR <> 0 or @retcode <> 0 GOTO UNDO -- Delete MSreplication_subsciptions table after dropping -- the distribution agent and delay one second -- to avoid deadlock with it. WAITFOR DELAY '00:00:01' END END /* Call sp_MSunregistersubscription so that the reg entries get deleted */ declare @subscriber_db sysname set @subscriber_db = DB_NAME() exec @retcode = dbo.sp_MSunregistersubscription @publisher = @publisher, @publisher_db = @publisher_db, @publication = @publication, @subscriber = @@SERVERNAME, @subscriber_db = @subscriber_db IF @retcode<>0 or @@ERROR<>0 GOTO UNDO /* -- Delete MSreplication_subsciptions table after dropping the distribution agent\ -- To avoid deadlock with it. --DELETE MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher) AND --publisher_db = @publisher_db AND --publication = @publication --IF @@ERROR <> 0 -- GOTO UNDO */ IF EXISTS(select * from sysobjects where type='U' and name = 'MSsubscription_properties') BEGIN DELETE FROM MSsubscription_properties WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db = @publisher_db AND publication = @publication IF @@ERROR <> 0 GOTO UNDO IF NOT EXISTS (SELECT * FROM MSsubscription_properties) BEGIN DROP TABLE MSsubscription_properties IF @@ERROR <> 0 GOTO UNDO END END /* ** Clean up metadata at subscriber side */ exec @retcode = dbo.sp_subscription_cleanup @publisher = @publisher, @publisher_db = @publisher_db, @publication = @publication IF @retcode<>0 or @@ERROR<>0 GOTO UNDO IF NOT EXISTS (SELECT * FROM MSreplication_subscriptions) BEGIN DROP TABLE MSreplication_subscriptions IF @@ERROR <> 0 GOTO UNDO END COMMIT TRAN /* ** set back the two settings if needed */ if @reserved = 0 BEGIN IF @implicit_transaction <>0 SET IMPLICIT_TRANSACTIONS ON IF @close_cursor_at_commit <>0 SET CURSOR_CLOSE_ON_COMMIT ON END RETURN (0) UNDO: IF @@TRANCOUNT > 0 begin ROLLBACK TRAN droppullsubscription COMMIT TRAN end /* ** set back the two settings if needed */ if @reserved = 0 BEGIN IF @implicit_transaction <>0 SET IMPLICIT_TRANSACTIONS ON IF @close_cursor_at_commit <>0 SET CURSOR_CLOSE_ON_COMMIT ON END return 1 go raiserror('Creating procedure sp_helppullsubscription', 0,1, 0,1) go CREATE PROCEDURE sp_helppullsubscription ( @publisher sysname = '%', @publisher_db sysname = '%', @publication sysname = '%', @show_push nvarchar(5) = 'false' ) AS SET NOCOUNT ON /* ** Declarations. */ DECLARE @command nvarchar(255) DECLARE @name nvarchar(255) DECLARE @retcode int DECLARE @show_push_bit bit DECLARE @push int declare @subscriber sysname declare @subscriber_db sysname declare @publisher_local sysname declare @publisher_db_local sysname declare @publication_local sysname declare @subscription_name nvarchar(1000) declare @regkey nvarchar(1000) declare @syncmgr_keyexist int declare @helpsubscriptioncursor_open int SELECT @push = 0 /* ** Security Check */ EXEC @retcode = dbo.sp_MSreplcheck_subscribe IF @@ERROR <> 0 or @retcode <> 0 RETURN(1) /* ** Initializations. */ set @subscriber = @@SERVERNAME set @subscriber_db = DB_NAME() /* ** Parameter Check: @publisher ** Check to make sure that the publisher is define */ IF @publisher IS NULL BEGIN RAISERROR (14043, 16, -1, '@publisher') RETURN (1) END IF @publisher <> '%' BEGIN EXECUTE @retcode = dbo.sp_validname @publisher IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) END IF @publication <> '%' BEGIN EXECUTE @retcode = dbo.sp_validname @publication IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) END IF @show_push IS NOT NULL AND LOWER(@show_push) NOT IN ('true', 'false') BEGIN RAISERROR (14148, 16, -1, '@show_push') RETURN (1) END IF LOWER(@show_push) = 'false' SELECT @show_push_bit = 0 IF LOWER(@show_push) = 'true' SELECT @show_push_bit = 1 IF NOT EXISTS (SELECT * FROM sysobjects WHERE type = 'U' AND name = 'MSreplication_subscriptions') RETURN (0) create table #helpsubscription ( publisher sysname NOT NULL, publisher_db sysname NOT NULL, publication sysname NULL, independent_agent bit NOT NULL, subscription_type int NOT NULL, distribution_agent nvarchar(100) NULL, time smalldatetime NOT NULL, description nvarchar(255) NULL, transaction_timestamp varbinary(16) NOT NULL, -- SyncTran update_mode tinyint NOT NULL, agent_id binary(16) NULL, subscription_guid binary(16) NULL, subid binary(16) NULL, immediate_sync bit NOT NULL, enabled_for_syncmgr int NULL ) insert into #helpsubscription select *, 0 from MSreplication_subscriptions WHERE ((@publisher = N'%') OR (UPPER(publisher) = UPPER(@publisher))) AND publisher_db LIKE @publisher_db AND publication LIKE @publication AND (subscription_type <> @push OR @show_push_bit = 1) ORDER BY publisher, publisher_db, publication declare #helpsubscriptioncursor CURSOR LOCAL FAST_FORWARD FOR select DISTINCT publisher, publisher_db, publication FROM #helpsubscription FOR READ ONLY create table #syncmgr_keyexist (syncmgr_keyexist int) open #helpsubscriptioncursor select @helpsubscriptioncursor_open = 1 fetch next from #helpsubscriptioncursor into @publisher_local, @publisher_db_local, @publication_local while (@@fetch_status <> -1) begin set @subscription_name = @publisher_local + ':' + @publisher_db_local + ':' + @publication_local + ':' + @subscriber + ':' + @subscriber_db /* Replace back slash with forward slash so that the key name is a valid REGISTRY key name */ set @subscription_name = REPLACE(@subscription_name,'\','/') set @regkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\' + @subscription_name insert into #syncmgr_keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @regkey select @syncmgr_keyexist = syncmgr_keyexist from #syncmgr_keyexist update #helpsubscription set enabled_for_syncmgr = @syncmgr_keyexist where UPPER(publisher) = UPPER(@publisher_local) and publisher_db = @publisher_db_local and publication = @publication_local fetch next from #helpsubscriptioncursor into @publisher_local, @publisher_db_local, @publication_local end /* ** Get the result ** ** Note: have to return meta data */ SELECT 'publisher' = publisher, 'publisher database' = publisher_db, 'publication' = publication, 'independent_agent' = independent_agent, 'subscription type' = subscription_type, 'distribution agent' = distribution_agent, 'publication description' = description, 'last updating time' = convert(nvarchar(12), time, 112) + substring(convert(nvarchar(24), time, 121), 11,13), 'subscription_name' = publisher + ':' + publisher_db + ':' + publication, 'last transaction timestamp' = transaction_timestamp, -- SyncTran 'update_mode' = update_mode, 'distribution agent job_id' = agent_id, 'enabled for syncmgr' = enabled_for_syncmgr, 'subscription guid' = subscription_guid, 'subid ' = subid, 'immediate_sync' = immediate_sync FROM #helpsubscription drop table #helpsubscription if (@helpsubscriptioncursor_open = 1) begin close #helpsubscriptioncursor deallocate #helpsubscriptioncursor end drop table #syncmgr_keyexist GO raiserror('Creating procedure sp_MStable_has_unique_index', 0,1) go create procedure sp_MStable_has_unique_index @tabid int as begin /* ** Returns id of unique index, if it exists, else 0 */ declare @indid int if (ObjectProperty(@tabid, 'IsTable') = 1) and (ObjectProperty(@tabid, 'TableHasIndex') = 1) begin -- First get the primary index id. See bug 52471 select @indid = i.indid from sysindexes i where -- get the primary key index (i.status & 2048) <> 0 and i.id = @tabid if @indid is null begin -- Get the first unique index select top 1 @indid = i.indid from sysindexes i where (i.status & 2) <> 0 and i.id = @tabid order by i.indid asc end if @indid is null select @indid = 0 end else select @indid = 0 return @indid end go raiserror('Creating procedure sp_MSchange_priority', 0,1) GO -- @value has to be unicode too. CREATE PROCEDURE sp_MSchange_priority (@subid uniqueidentifier, @value nvarchar(255)) as update sysmergesubscriptions set priority = convert(real, @value) where subid = @subid go exec dbo.sp_MS_marksystemobject sp_MSchange_priority go grant execute on dbo.sp_MSchange_priority to public raiserror('Creating procedure sp_expired_subscription_cleanup', 0,1) GO CREATE PROCEDURE sp_expired_subscription_cleanup AS declare @retcode int declare @publisher_db sysname declare @category int declare @proc_name nvarchar(200) declare @distributor sysname declare @distribdb sysname declare @distproc nvarchar(270) /* ** Security Check */ EXEC @retcode = dbo.sp_MSreplcheck_publish IF @@ERROR <> 0 or @retcode <> 0 return (1) /* ** Get distribution server information for remote RPC call. */ EXECUTE @retcode = sp_helpdistributor @rpcsrvname = @distributor OUTPUT, @distribdb = @distribdb OUTPUT IF @@ERROR <> 0 or @retcode <> 0 BEGIN RAISERROR (20036, 16, -1) return (1) END DECLARE DC CURSOR LOCAL FAST_FORWARD for select DISTINCT name, category from master..sysdatabases where (category & 4) = 4 or (category & 1 = 1) for read only open DC fetch DC into @publisher_db, @category WHILE (@@fetch_status <> -1) BEGIN if (@category & 4 = 4) begin select @proc_name = @publisher_db + '.dbo.sp_MSdrop_expired_mergesubscription' exec @retcode = @proc_name if @retcode<>0 or @@ERROR<>0 goto DONE end if (@category & 1 = 1) begin select @proc_name = @publisher_db + '.dbo.sp_MSdrop_expired_subscription' exec @retcode = @proc_name if @retcode<>0 or @@ERROR<>0 goto DONE end fetch DC into @publisher_db, @category END /* ** sp_MScleanup_agent_entry in distribution database is called to periodically remove obselete ** entries in MSmerge_agents, which may be caused by the following reasons: ** 1. publishing database is externally removed; therefore cleanup agent can not do its job ** 2. Entries for anonymous merge subscriptions */ SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '..sp_MScleanup_agent_entry' exec @retcode = @distproc if @@ERROR<>0 or @retcode<>0 BEGIN close DC deallocate DC return (1) END DONE: close DC deallocate DC GO go exec dbo.sp_MS_marksystemobject sp_expired_subscription_cleanup go grant execute on dbo.sp_expired_subscription_cleanup to public raiserror('Creating procedure sp_addmergepullsubscription', 0,1) GO CREATE PROCEDURE sp_addmergepullsubscription ( @publication sysname, /* Publication name */ @publisher sysname = @@SERVERNAME, /* Publisher server */ @publisher_db sysname = NULL, /* Publication database */ @subscriber_type nvarchar(15) = 'local', /* Subscriber type */ @subscription_priority real = NULL, /* Subscription priority */ @sync_type nvarchar(15) = 'automatic', /* subscription sync type */ @description nvarchar(255) = NULL ) AS SET NOCOUNT ON /* ** Declarations. */ declare @retcode int declare @subscriber_db sysname declare @subnickname int declare @subscriber_srvid int declare @publisher_srvid int declare @priority real declare @subid uniqueidentifier declare @subscriber_typeid smallint declare @subscription_type smallint declare @command nvarchar(255) declare @inactive tinyint declare @global tinyint /* subscriber type is global */ declare @push tinyint /* subscription type is push */ declare @sync_typeid tinyint declare @nosync tinyint declare @automatic tinyint declare @pubid uniqueidentifier declare @partnerid uniqueidentifier declare @parentid uniqueidentifier /* ** Initializations. */ SET @nosync = 2 /* Const: synchronization type 'nosync' */ SET @automatic = 1 /* Const: synchronization type 'automatic' */ SET @inactive = 0 SET @global = 1 SET @push = 0 set @pubid = newid() set @partnerid = @pubid set @parentid = '00000000-0000-0000-0000-000000000000' /* ** Check if replication components are installed on this server */ exec @retcode = dbo.sp_MS_replication_installed if (@retcode <> 1) begin return (1) end /* ** Security Check. */ EXEC @retcode = dbo.sp_MSreplcheck_subscribe if @@ERROR <> 0 or @retcode <> 0 return(1) /* ** Check to see if merge system tables exist. Create them unless they already ** exist. */ IF not exists (select name from sysobjects where name='sysmergesubscriptions') BEGIN execute @retcode = dbo.sp_MScreate_mergesystables if @@ERROR <> 0 or @retcode <> 0 begin return (1) end END if UPPER(@publisher) = UPPER(@@SERVERNAME) and @publisher_db = db_name() begin raiserror(21126, 16, -1) return (1) end if exists (select pubid from sysmergepublications where UPPER(publisher) = UPPER(@@SERVERNAME) and publisher_db=db_name()) and @subscriber_type in ('local', 'anonymous') begin declare @dbname sysname select @dbname = DB_NAME() raiserror(21127, 16, -1, @dbname) return (1) end /* ** When adding a pull subscription, if a push subscription for that publication already exists, ** we will cleanup all the traces of that subscription */ IF EXISTS (select name from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db) BEGIN select @pubid=pubid from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db IF EXISTS (select subid from sysmergesubscriptions where pubid=@pubid and subid<>@pubid and subscription_type=0) begin exec @retcode = dbo.sp_MSpublicationcleanup @publisher=@publisher, @publisher_db=@publisher_db, @publication=@publication IF @@ERROR <> 0 or @retcode <>0 BEGIN RAISERROR (20025, 16, -1, @publication) return (1) END end ELSE begin IF EXISTS (select status from sysmergesubscriptions where pubid=@pubid and status = 2) begin select @subid = subid from sysmergesubscriptions where pubid=@pubid and subid<>pubid delete sysmergesubscriptions where pubid=@pubid delete MSmerge_replinfo where repid = @subid end ELSE begin RAISERROR (14058, 16, -1) return (1) end end END set @partnerid = @pubid /* ** Assign parameter values appropriately for the local server database */ set @subscriber_db = DB_NAME() select @subscriber_srvid = 0 /* ** Parameter Check: @publisher ** Check to make sure that the publisher is defined */ IF @publisher IS NULL BEGIN RAISERROR (14043, 16, -1, '@publisher') RETURN (1) END IF @publisher = 'all' BEGIN RAISERROR (14136, 16, -1) RETURN (1) END EXECUTE @retcode = dbo.sp_validname @publisher IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) /* ** Validate that the publisher is a valid server */ select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher) IF @publisher_srvid IS NULL BEGIN EXECUTE @retcode = dbo.sp_addserver @publisher IF @@error <> 0 OR @retcode <> 0 BEGIN RAISERROR (14010, 16, -1) RETURN (1) END ELSE select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher) END /* ** Parameter Check: @publisher_db */ IF @publisher_db IS NULL BEGIN RAISERROR (14043, 16, -1, '@publisher_db') RETURN (1) END IF @publisher_db = 'all' BEGIN RAISERROR (14136, 16, -1) RETURN (1) END /* ** Check to see if the publication name is already used in the subscription ** database - This is the case where we are resubscribing to the same publication. ** Execute dbo.sp_MSpublicationcleanup to cleanup all all the defunct rows ** if exists (select * from sysmergepublications where name = @publication) ** begin ** exec @retcode = dbo.sp_MSpublicationcleanup ** IF @@ERROR <> 0 OR @retcode <> 0 ** BEGIN ** RAISERROR (20025, 16, -1, @publication) ** RETURN (1) ** END ** end */ /* ** Parameter Check: @subscriber_type. ** Set subscriber_typeid based on the @subscriber_type specified. ** ** subscriber_type subscriber_type ** ================= =============== ** 1 global ** 2 local ** 3 anonymous ** NO support for republisher for B 3 */ if LOWER(@subscriber_type) NOT IN ('local', 'global', 'anonymous') BEGIN RAISERROR (20023, 16, -1) RETURN (1) END set @subscription_type = 1 /* pull by default */ if LOWER(@subscriber_type) IN ('global') set @subscriber_typeid = 1 else if LOWER(@subscriber_type) IN ('local') set @subscriber_typeid = 2 else if LOWER(@subscriber_type) IN ('anonymous') begin /* For anonymous subscribers set subscription type appropriately */ set @subscriber_typeid = 3 set @subscription_type = 2 end /* ** Assign priority appropriately - choose 0.99 times the minimum priority ** of the global replicas. */ if (@subscription_priority > 100.0 or @subscription_priority < 0.0) set @subscription_priority = NULL if (@subscription_priority IS NULL) begin select @priority = 0.99 * min(priority) from sysmergesubscriptions where subscriber_type = 1 /* global/loopback */ if (@priority IS NOT NULL) select @subscription_priority = @priority if (@subscription_priority IS NULL) select @subscription_priority = 0.0 end /* ** For local and anonymous subscriptions the priority is 0.0 */ if LOWER(@subscriber_type) IN ('local', 'anonymous') select @subscription_priority = 0.0 /* ** If the subscription already exists, don't add it. ** if EXISTS (select db_name, srvid ** FROM sysmergesubscriptions ** WHERE db_name = @subscriber_db ** AND srvid = @subscriber_srvid ** AND pubid = @pubid) ** BEGIN ** RAISERROR (14058, 16, -1) ** RETURN (1) ** END */ /* ** Parameter Check: @sync_type. ** Set sync_typeid based on the @sync_type specified. ** ** sync_typeid sync_type ** =========== ========= ** 1 automatic ** 2 nosync */ IF LOWER(@sync_type) NOT IN ('automatic', 'none') BEGIN RAISERROR (14052, 16, -1) RETURN (1) END IF LOWER(@sync_type) = 'automatic' BEGIN SET @sync_typeid = @automatic END ELSE BEGIN SET @sync_typeid = @nosync END /* ** UNDONE: Validate that the publisher is of type 'republisher' */ begin tran save TRAN addmergepullsubscription /* Generate a guid for the Subscriber ID */ set @subid = newid() /* Look for existing nickname from any other subscription */ exec dbo.sp_MSgetreplnick NULL, NULL , NULL, @subnickname out if (@@error <> 0) begin goto FAILURE end /* Generate a new replica nickname from the @subid */ if (@subnickname is null) EXECUTE dbo.sp_MSgenreplnickname @subid, @subnickname output /* ** Check to see if MSsubscription_properties table exists. ** If not, create it. */ exec @retcode = dbo.sp_MScreate_sub_tables IF @@ERROR <> 0 or @retcode <> 0 goto FAILURE /* ** The subscription doesn't exist, so let's add it to sysmergesubscriptions */ INSERT sysmergesubscriptions (subid, partnerid, datasource_type, srvid, db_name, pubid, status, subscriber_type, subscription_type, priority, sync_type, description, login_name) VALUES (@subid, @partnerid, 0, @subscriber_srvid, @subscriber_db, @pubid, @inactive, @subscriber_typeid, @subscription_type, /* for a pull/anon subscription */ @subscription_priority, @sync_typeid, @description, suser_sname(suser_sid())) if @@ERROR <> 0 BEGIN GOTO FAILURE END /* Add a self-subscribed subscription to represent the publication */ insert sysmergepublications(publisher, publisher_db, pubid, name, parentid) values(@publisher, @publisher_db, @pubid, @publication, @parentid) if @@ERROR <> 0 begin goto FAILURE end insert sysmergesubscriptions(subid, partnerid, datasource_type, srvid, db_name, pubid, subscriber_type, subscription_type, status, priority, sync_type, description, login_name) values (@pubid, @pubid, 0, @publisher_srvid, @publisher_db, @pubid, @global, @push, @inactive, 100.0, @sync_typeid, @description, suser_sname(suser_sid())) if @@ERROR <> 0 begin goto FAILURE end /* ** Add row for subscription in MSmerge_replinfo. */ insert MSmerge_replinfo(repid, replnickname) values (@subid, @subnickname) if @@ERROR <> 0 BEGIN GOTO FAILURE END COMMIT TRAN return (0) FAILURE: RAISERROR (14057, 16, -1) if @@trancount > 0 begin ROLLBACK TRANSACTION addmergepullsubscription COMMIT TRANSACTION end RETURN (1) go exec dbo.sp_MS_marksystemobject sp_addmergepullsubscription go grant execute on dbo.sp_addmergepullsubscription to public go raiserror('Creating procedure sp_changemergepullsubscription', 0,1) GO CREATE PROCEDURE sp_changemergepullsubscription ( @publication sysname = '%', /* Publication name */ @publisher sysname = '%', /* Publisher server */ @publisher_db sysname = '%', /* Publication database */ @property sysname = NULL, /* The property to change */ @value nvarchar(255) = NULL /* The new property value */ ) AS SET NOCOUNT ON /* ** Declarations. */ declare @subscriber_srvid int declare @publisher_srvid int declare @retcode int declare @pubid uniqueidentifier declare @subid uniqueidentifier declare @partnerid uniqueidentifier declare @sync_typeid tinyint declare @nosync tinyint declare @automatic tinyint declare @artid uniqueidentifier declare @subscriber sysname declare @subscriber_db sysname declare @schematype int declare @schemaversion int declare @schemaguid uniqueidentifier declare @db_name sysname declare @subscriber_type int declare @schematext nvarchar(2000) /* ** Initializations. */ SET @subscriber = @@SERVERNAME SET @subscriber_db = DB_NAME() SET @nosync = 2 /* Const: synchronization type 'none' */ SET @automatic = 1 /* Const: synchronization type 'automatic' */ select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber) IF @subscriber_srvid IS NULL BEGIN RAISERROR (14010, 16, -1) RETURN (1) END /* ** Security Check. */ BEGIN exec @retcode = dbo.sp_MSreplcheck_subscribe if @@ERROR <> 0 or @retcode <> 0 return(1) END /* ** Check to see if current database is enabled for subscribing */ IF not exists (select name from sysobjects where name='sysmergesubscriptions') BEGIN RAISERROR (14055, 16, -1) RETURN (1) END /* ** Parameter Check: @property. ** If the @property parameter is NULL, print the options. */ IF @property IS NULL BEGIN CREATE TABLE #tab1 (properties sysname NOT NULL) INSERT INTO #tab1 VALUES ('sync_type') INSERT INTO #tab1 VALUES ('priority') INSERT INTO #tab1 VALUES ('description') select * FROM #tab1 RETURN (0) END /* ** Parameter Check: @publisher. ** Check to make sure we have a valid publisher. ** Should make sure that @publisher is non-null before using it to check whether @publication is valid */ IF @publisher IS NULL BEGIN RAISERROR (14043, 16, -1, '@publisher') RETURN (1) END /* ** Parameter Check: @publication. ** Make sure that the publication exists. */ IF @publication IS NULL BEGIN RAISERROR (14043, 16, -1, '@publication') RETURN (1) END select @pubid = pubid FROM sysmergepublications WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db IF @pubid IS NULL BEGIN RAISERROR (20026, 11, -1, @publication) RETURN (1) END /* ** Validate that the publisher is a valid server */ select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher) IF @publisher_srvid IS NULL BEGIN RAISERROR (14010, 16, -1) RETURN (1) END /* ** Check to see if you have a local / global subscription on this publication */ set @subid = NULL select @subid = subs1.subid, @pubid = pubs.pubid, /* identified from publication name */ @subscriber_type=subs1.subscriber_type, @partnerid = subs2.subid from sysmergesubscriptions subs1, sysmergesubscriptions subs2, sysmergepublications pubs where subs1.srvid = @subscriber_srvid and subs1.db_name = @subscriber_db and subs2.srvid = @publisher_srvid and subs2.db_name = @publisher_db and subs1.pubid = subs2.subid and subs2.pubid = pubs.pubid and pubs.name = @publication and UPPER(pubs.publisher)=UPPER(@publisher) and pubs.publisher_db = @publisher_db if @subid IS NULL begin RAISERROR (14050, 11, -1) RETURN(1) end /* ** Parameter Check: @property. ** Check to make sure that @property is a valid property in ** sysarticles. */ IF LOWER(@property) NOT IN ('sync_type', 'priority', 'description') BEGIN RAISERROR (14051, 16, -1) RETURN (1) END /* ** Change the property. */ IF LOWER(@property) = 'sync_type' BEGIN /* ** Check to make sure that we have a valid sync_type. */ IF LOWER(@value) NOT IN ('automatic', 'none') BEGIN RAISERROR (14052, 16, -1) RETURN (1) END /* ** Determine the integer value for the sync_type. */ IF LOWER(@value) = 'automatic' SET @sync_typeid = @automatic ELSE SET @sync_typeid = @nosync /* ** Update the subscription with the new sync_type. */ UPDATE sysmergesubscriptions SET sync_type = @sync_typeid WHERE subid = @subid IF @@ERROR <> 0 BEGIN RAISERROR (14053, 16, -1) RETURN (1) END END IF LOWER(@property) = 'description' BEGIN UPDATE sysmergesubscriptions SET description = @value WHERE subid = @subid IF @@ERROR <> 0 BEGIN RAISERROR (14053, 16, -1) RETURN (1) END END IF LOWER(@property) = 'priority' BEGIN select @db_name = db_name from sysmergesubscriptions where (pubid=@pubid) and (subid=@pubid) IF @db_name <> db_name() BEGIN RAISERROR (20047, 16, -1) RETURN (1) END /* Only the original publisher can change priority of a global subscriptions */ IF @subscriber_type<>1 BEGIN RAISERROR (20044, 16, -1) /* Local subscriber does not have priority*/ RETURN (1) END select @schemaversion = schemaversion from sysmergeschemachange if (@schemaversion is NULL) set @schemaversion = 1 else select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange set @schemaguid = newid() set @artid = newid() set @schematype = 8 /* change priority */ select @schematext = 'exec dbo.sp_MSchange_priority '+ '''' + convert(nchar(36),@subid) + '''' + ',' + '''' + @value + '''' BEGIN TRANSACTION exec dbo.sp_MSchange_priority @subid, @value exec dbo.sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext COMMIT TRANSACTION END /* ** Return succeed. */ RAISERROR (14054, 10, -1) RETURN (0) go exec dbo.sp_MS_marksystemobject sp_changemergepullsubscription go grant execute on dbo.sp_changemergepullsubscription to public go raiserror('Creating procedure sp_helpmergepullsubscription', 0,1) GO CREATE PROCEDURE sp_helpmergepullsubscription( @publication sysname = '%', /* Publication name */ @publisher sysname = '%', /* Publisher server */ @publisher_db sysname = '%', /* Publication database */ @subscription_type nvarchar(10) = 'pull' /* Show only pull subscriptions */ )AS SET NOCOUNT ON /* ** Declarations. */ declare @retcode int declare @srvid int declare @pubid uniqueidentifier declare @subid uniqueidentifier declare @partnerid uniqueidentifier declare @cursor_open int declare @subscriber sysname declare @subscriber_db sysname declare @subscription_set nvarchar(10) declare @publisher_local sysname declare @publisher_db_local sysname declare @publication_local sysname declare @subscription_name nvarchar(1000) declare @regkey nvarchar(1000) declare @syncmgr_keyexist int declare @helpsubscriptioncursor_open int /* ** Initializations. */ set @cursor_open = 0 select @publisher_db = RTRIM(@publisher_db) select @publication = RTRIM(@publication) /* ** Calling sp_help* is all right whether current database is enabled for pub/sub or not */ IF not exists (select * from sysobjects where name='sysmergesubscriptions') RETURN (0) /* Security check */ EXEC @retcode = dbo.sp_MSreplcheck_subscribe if @@ERROR <> 0 or @retcode <> 0 return(1) set @subscriber = @@SERVERNAME set @subscriber_db = DB_NAME() /* ** Parameter Check: @publisher ** Check to make sure that the publisher is defined */ IF @publisher <> '%' AND @publisher IS NOT NULL BEGIN EXECUTE @retcode = dbo.sp_validname @publisher IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) END /* ** Parameter Check: @publication. ** If the publication name is specified, check to make sure that it ** conforms to the rules for identifiers and that the publication ** actually exists. Disallow NULL. */ if @publication IS NULL BEGIN RAISERROR (14043, 16, -1, '@publication') RETURN (1) END /* ** Parameter Check: @subscription_type. ** Set subscription_typeid based on the @subscription_type specified. ** ** subscription_type subscription_type ** ================= =============== ** 0 push ** 1 pull ** 0,1 both */ if LOWER(@subscription_type) NOT IN ('push', 'pull', 'both') BEGIN RAISERROR (14128, 16, -1) RETURN (1) END IF LOWER(@subscription_type) = 'both' set @subscription_set = '(0, 1)' else IF LOWER(@subscription_type) = 'push' set @subscription_set = '(0)' else set @subscription_set = '(1,2)' -- including pull subscription and pull/anonymous subscription /* ** Get subscriptions */ create table #helpmergepullsubscription ( publication sysname NOT NULL, publisher sysname NOT NULL, publisher_db sysname NOT NULL, subscriber sysname NOT NULL, subscriber_db sysname NOT NULL, status int NOT NULL, subscriber_type int NOT NULL, subscription_type int NOT NULL, priority float(8) NOT NULL, sync_type tinyint NOT NULL, description nvarchar(255) NULL, merge_jobid binary(16) NULL, enabled_for_syncmgr int NULL ) IF @publisher IS NULL and @publisher_db IS NULL BEGIN select @subid = subid from sysmergesubscriptions where subid = partnerid set @partnerid = @subid -- show the loopback subscription insert into #helpmergepullsubscription select pubs.name, servers2.srvname, subs2.db_name, servers1.srvname, subs1.db_name, subs1.status, subs1.subscriber_type, subs1.subscription_type, subs1.priority, subs1.sync_type, subs1.description, replinfo.merge_jobid, 0 FROM sysmergesubscriptions subs1, sysmergesubscriptions subs2, MSmerge_replinfo replinfo, master..sysservers servers1, master..sysservers servers2, sysmergepublications pubs where subs1.subid = @subid and subs2.subid = @partnerid and pubs.pubid = subs1.pubid and servers1.srvid = subs1.srvid and servers2.srvid = subs2.srvid and subs1.subid = subs1.partnerid and replinfo.repid = subs1.subid END else begin /* exec ('declare #cursor cursor FOR select DISTINCT sub.subid, sub.partnerid ' + 'FROM sysmergesubscriptions sub, ' + 'sysmergesubscriptions sub1, ' + 'master..sysservers ss, ' + 'master..sysservers ss1, ' + 'sysmergepublications pub ' + 'WHERE ss.srvname LIKE ''' + @subscriber + '''AND UPPER(ss1.srvname) like UPPER(''' + @publisher + ''') AND sub1.srvid = ss1.srvid ' + 'AND sub.srvid = ss.srvid ' + 'AND pub.name LIKE ''' + @publication + '''AND sub.pubid = pub.pubid ' + 'AND sub.db_name LIKE ''' + @subscriber_db + '''AND sub1.db_name LIKE ''' + @publisher_db + '''AND sub1.pubid = pub.pubid ' + 'AND sub.subscription_type IN ' + @subscription_set + ' FOR READ ONLY') -- UNDONE 'AND sub1.subid = sub.partnerid ' */ declare #cursor cursor local FAST_FORWARD FOR select DISTINCT sub.subid, sub.partnerid FROM sysmergesubscriptions sub, sysmergesubscriptions sub1, master..sysservers ss, master..sysservers ss1, sysmergepublications pub WHERE ((@subscriber = N'%') OR (UPPER(ss.srvname) = UPPER(@subscriber))) AND ((@publisher = N'%') OR (UPPER(ss1.srvname) = UPPER(@publisher))) AND sub1.srvid = ss1.srvid AND sub.srvid = ss.srvid AND pub.name LIKE @publication AND sub.pubid = pub.pubid AND sub.db_name LIKE @subscriber_db AND sub1.db_name LIKE @publisher_db AND sub1.pubid = pub.pubid AND (sub.subscription_type=1 or sub.subscription_type=2) FOR READ ONLY open #cursor select @cursor_open = 1 fetch next from #cursor into @subid, @partnerid while (@@fetch_status <> -1) begin insert into #helpmergepullsubscription select pubs.name, servers2.srvname, subs2.db_name, servers1.srvname, subs1.db_name, subs1.status, subs1.subscriber_type, subs1.subscription_type, subs1.priority, subs1.sync_type, subs1.description, replinfo.merge_jobid, 0 FROM sysmergesubscriptions subs1, sysmergesubscriptions subs2, MSmerge_replinfo replinfo, master..sysservers servers1, master..sysservers servers2, sysmergepublications pubs where subs1.subid = @subid and subs2.subid = @partnerid and pubs.pubid = subs1.pubid and servers1.srvid = subs1.srvid and servers2.srvid = subs2.srvid and @subid <> @partnerid -- do not show the loopback subscription and replinfo.repid = subs1.subid if @@ERROR <> 0 begin set @retcode = 1 goto DONE end fetch next from #cursor into @subid, @partnerid end end declare #helpsubscriptioncursor CURSOR LOCAL FAST_FORWARD FOR select DISTINCT publisher, publisher_db, publication FROM #helpmergepullsubscription FOR READ ONLY create table #syncmgr_keyexist (syncmgr_keyexist int) open #helpsubscriptioncursor select @helpsubscriptioncursor_open = 1 fetch next from #helpsubscriptioncursor into @publisher_local, @publisher_db_local, @publication_local while (@@fetch_status <> -1) begin set @subscription_name = @publisher_local + ':' + @publisher_db_local + ':' + @publication_local + ':' + @subscriber + ':' + @subscriber_db /* Replace back slash with forward slash so that the key name is a valid REGISTRY key name */ set @subscription_name = REPLACE(@subscription_name,'\','/') set @regkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\' + @subscription_name insert into #syncmgr_keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @regkey select @syncmgr_keyexist = syncmgr_keyexist from #syncmgr_keyexist update #helpmergepullsubscription set enabled_for_syncmgr = @syncmgr_keyexist where UPPER(publisher) = UPPER(@publisher_local) and publisher_db = @publisher_db_local and publication = @publication_local fetch next from #helpsubscriptioncursor into @publisher_local, @publisher_db_local, @publication_local end select 'subscription_name'= publisher + ':' + publisher_db + ':' + publication, * from #helpmergepullsubscription order by publisher, publisher_db, publication, subscriber, subscriber_db select @retcode = 0 DONE: if (@cursor_open = 1) begin close #cursor deallocate #cursor end drop table #helpmergepullsubscription if (@helpsubscriptioncursor_open = 1) begin close #helpsubscriptioncursor deallocate #helpsubscriptioncursor end drop table #syncmgr_keyexist return @retcode go exec dbo.sp_MS_marksystemobject sp_helpmergepullsubscription go grant execute on dbo.sp_helpmergepullsubscription to public go raiserror('Creating procedure sp_addmergepullsubscription_agent', 0,1) GO CREATE PROCEDURE sp_addmergepullsubscription_agent ( @name sysname = NULL, @publisher sysname, /* Publisher server */ @publisher_db sysname, /* Publisher database */ @publication sysname, /* Publication name */ @publisher_security_mode int = 1, @publisher_login sysname = NULL, @publisher_password sysname = NULL, @publisher_encrypted_password bit = 0, @subscriber sysname = NULL, @subscriber_db sysname = NULL, @subscriber_security_mode int = NULL, /* 0 standard; 1 integrated */ @subscriber_login sysname = NULL, @subscriber_password sysname = NULL, @distributor sysname = @@SERVERNAME, @distributor_security_mode int = 1, /* 0 standard; 1 integrated */ @distributor_login sysname = NULL, @distributor_password sysname = NULL, @encrypted_password bit = 0, /* distributor password encrypted or not */ @frequency_type int = NULL, @frequency_interval int = NULL, @frequency_relative_interval int = NULL, @frequency_recurrence_factor int = NULL, @frequency_subday int = NULL, @frequency_subday_interval int = NULL, @active_start_time_of_day int = NULL, @active_end_time_of_day int = NULL, @active_start_date int = NULL, @active_end_date int = NULL, @optional_command_line nvarchar(255) = '', /* Optional command line arguments */ @merge_jobid binary(16) = NULL OUTPUT, @enabled_for_syncmgr nvarchar(5) = 'false', /* Enabled for SYNCMGR: true or false */ @ftp_address sysname = NULL, @ftp_port int = NULL, @ftp_login sysname = NULL, @ftp_password sysname = NULL ) AS SET NOCOUNT ON /* ** Declarations. */ declare @command nvarchar(4000) declare @retcode int declare @database sysname declare @repid uniqueidentifier declare @pubid uniqueidentifier declare @subscriber_srvid int declare @publisher_srvid int declare @name_id nvarchar(50) declare @subscriber_typeid int declare @subscription_type_id int declare @category_name sysname declare @platform_nt binary DECLARE @subscriber_enc_password sysname select @platform_nt = 0x1 -- Set null @optional_command_line to empty string to avoid string concat problem if @optional_command_line is null set @optional_command_line = '' IF @distributor_password = N'' select @distributor_password = NULL IF @publisher_password = N'' select @publisher_password = NULL IF @ftp_password = N'' select @ftp_password = NULL /* ** Parameter Check: @subscriber and @subscriber_db */ if @subscriber IS NULL or rtrim(@subscriber) = '' SELECT @subscriber = @@SERVERNAME if @subscriber_db IS NULL or rtrim(@subscriber_db) = '' SELECT @subscriber_db = DB_NAME() EXECUTE @retcode = dbo.sp_validname @subscriber IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) EXECUTE @retcode = dbo.sp_validname @subscriber_db IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) -- Parameter check: @subscriber_security_mode if @subscriber_security_mode is null begin if ( platform() & @platform_nt ) = @platform_nt select @subscriber_security_mode = 1 else select @subscriber_security_mode = 0 end if ( ( platform() & @platform_nt ) <> @platform_nt and @subscriber_security_mode = 1) begin RAISERROR(21038, 16, -1) RETURN (1) end select @subscription_type_id = 1 /* pull agent only */ /* ** Set Default schedule values if NULL is specified ** The default are not implemented during parmeter defintion because this procedure ** is can be called from sp_addmergesubscription. */ if @frequency_type is NULL set @frequency_type = 4 /* Daily */ if @frequency_interval is NULL set @frequency_interval = 1 if @frequency_relative_interval is NULL set @frequency_relative_interval = 1 if @frequency_recurrence_factor is NULL set @frequency_recurrence_factor = 0 if @frequency_subday is NULL set @frequency_subday = 8 /* Hour */ if @frequency_subday_interval is NULL set @frequency_subday_interval = 1 if @active_start_time_of_day is NULL set @active_start_time_of_day = 0 if @active_end_time_of_day is NULL set @active_end_time_of_day = 235959 if @active_start_date is NULL set @active_start_date = 0 if @active_end_date is NULL set @active_end_date = 99991231 select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@@SERVERNAME) IF @subscriber_srvid IS NULL BEGIN RAISERROR (14010, 16, -1) RETURN (1) END select @pubid = pubid from sysmergepublications where name = @publication IF @pubid is NULL begin RAISERROR (14027, 16, -1, @publication) RETURN (1) end select @repid = subid, @subscriber_typeid = subscriber_type from sysmergesubscriptions where srvid = @subscriber_srvid and pubid<>subid and pubid = @pubid if @subscriber_typeid = 3 set @subscription_type_id = 2 /* This corresponds to anonymous subscription */ if (@subscription_type_id <> 0) begin if (@subscriber_security_mode = 0) and (@subscriber_login IS NULL or rtrim(@subscriber_login) = '') begin raiserror(3217, 16, -1, '@subscriber_login') return (1) end end IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U') begin raiserror(14027, 16, -1, 'The subscription properties table ''MSsubscription_properties''') return (1) end /* ** Construct unique task name if @name = NULL */ IF @name IS NULL begin SELECT @name = CONVERT(nvarchar(23),@publisher ) + '-' + CONVERT(nvarchar(23),@publisher_db) + '-' + CONVERT(nvarchar(23),@publication) + '-' + CONVERT(nvarchar(23),@subscriber) + '-' + CONVERT(nvarchar(23), @subscriber_db) + '- 0' end else begin /* ** validate name */ exec @retcode = dbo.sp_MSreplcheck_name @name if @@ERROR <> 0 or @retcode <> 0 return(1) end /* Construct task command */ select @command = '-Publisher ' + @publisher + ' -PublisherDB ' + QUOTENAME(@publisher_db) + ' ' select @command = @command + '-Publication ' + QUOTENAME(@publication) + ' ' select @command = @command + '-Subscriber ' + QUOTENAME(@@SERVERNAME) + ' ' select @command = @command + '-SubscriberDB ' + QUOTENAME(db_name()) + ' ' SELECT @command = @command + '-SubscriptionType ' + convert(nvarchar(10), @subscription_type_id) + ' ' select @command = @command + '-SubscriberSecurityMode ' + convert(nvarchar(10),@subscriber_security_mode) + ' ' if @subscriber_login is not NULL select @command = @command + '-SubscriberLogin ' + quotename(@subscriber_login) + ' ' if @subscriber_password is not NULL begin set @subscriber_enc_password = @subscriber_password exec @retcode = master.dbo.xp_repl_encrypt @subscriber_enc_password OUTPUT select @command = @command + '-SubscriberEncryptedPassword ' + quotename(@subscriber_enc_password) + ' ' end select @command = @command + @optional_command_line select @command = @command + '-Distributor ' + @distributor + ' ' select @database = db_name() -- Get Merge category name (assumes category_id = 14) select @category_name = name FROM msdb.dbo.syscategories where category_id = 14 begin tran EXEC @retcode = dbo.sp_MSadd_repl_job @name = @name, @subsystem = 'Merge', @server = @@SERVERNAME, @databasename = @database, @enabled = 1, @freqtype = @frequency_type, @freqinterval = @frequency_interval, @freqsubtype = @frequency_subday, @freqsubinterval = @frequency_subday_interval, @freqrelativeinterval = @frequency_relative_interval, @freqrecurrencefactor = @frequency_recurrence_factor, @activestartdate = @active_start_date, @activeenddate = @active_end_date, @activestarttimeofday = @active_start_time_of_day, @activeendtimeofday = @active_end_time_of_day, @command = @command, @retryattempts = 10, @retrydelay = 1, @category_name = @category_name, @job_id = @merge_jobid OUTPUT if @@ERROR <> 0 or @retcode <> 0 begin goto undo end if (@subscription_type_id = 1) OR (@subscription_type_id = 2) begin IF NOT EXISTS (select * from MSsubscription_properties where UPPER(publisher) = UPPER(@publisher) and publisher_db = @publisher_db and publication = @publication) BEGIN IF (@encrypted_password = 0) -- Encrypt the password BEGIN EXEC @retcode = master.dbo.xp_repl_encrypt @distributor_password OUTPUT IF @@error <> 0 OR @retcode <> 0 return 1 END IF (@publisher_encrypted_password = 0) -- Encrypt the password BEGIN EXEC @retcode = master.dbo.xp_repl_encrypt @publisher_password OUTPUT IF @@error <> 0 OR @retcode <> 0 return 1 END INSERT INTO MSsubscription_properties (publisher, publisher_db, publication, publication_type, publisher_login,publisher_password, publisher_security_mode, distributor, distributor_login, distributor_password, distributor_security_mode, ftp_address, ftp_port, ftp_login, ftp_password) values (@publisher, @publisher_db, @publication, 2, @publisher_login, @publisher_password, @publisher_security_mode, @distributor, @distributor_login, @distributor_password, @distributor_security_mode, @ftp_address, @ftp_port, @ftp_login, @ftp_password) IF @@ERROR <> 0 BEGIN IF @@TRANCOUNT = 1 ROLLBACK TRAN ELSE COMMIT TRAN RETURN(1) END END end /* Update merge joibd for this pull subscription */ UPDATE MSmerge_replinfo set merge_jobid = @merge_jobid WHERE repid = @repid /* Conditional support for MobileSync */ if LOWER(@enabled_for_syncmgr) = 'true' BEGIN /* Call sp_MSregistersubscription so that the subscription can be synchronized via MobileSync etc. */ exec @retcode = dbo.sp_MSregistersubscription @replication_type = 2, @publisher = @publisher, @publisher_db = @publisher_db, @publication = @publication, @subscriber = @subscriber, @subscriber_db = @subscriber_db, @subscriber_security_mode = @subscriber_security_mode, @subscriber_login = @subscriber_login, @subscriber_password = @subscriber_password, @distributor = @distributor, @subscription_id = @repid, @subscription_type = @subscription_type_id IF @@ERROR <> 0 or @retcode <> 0 BEGIN goto undo END END commit tran RETURN (0) undo: IF @@TRANCOUNT = 1 ROLLBACK TRAN ELSE COMMIT TRAN GO exec dbo.sp_MS_marksystemobject sp_addmergepullsubscription_agent go raiserror('Creating procedure sp_MSget_mergepullsubsagent_owner', 0,1) GO CREATE PROCEDURE sp_MSget_mergepullsubsagent_owner( @publication sysname = NULL, /* Publication name */ @publisher sysname = NULL, /* Publisher server */ @publisher_db sysname = NULL, /* Publication database */ @owner_sid varbinary(85) OUTPUT )AS declare @srvid int declare @pubid uniqueidentifier declare @subid uniqueidentifier declare @job_id uniqueidentifier set nocount on select @owner_sid = NULL if exists (select * from sysobjects where type = 'U' and name = 'sysmergesubscriptions') -- Get the server id of the current server (subscriber) begin -- Get the srvid of the current subscriber database select @srvid = srvid from master.dbo.sysservers where upper(@@servername) = upper(srvname) -- Get the pubid from sysmergepublications using @publisher, -- @publisher_db, @publication select @pubid = pubid from sysmergepublications where @publication = name -- Get the subid from sysmergesubscriptions using @pubid and @srvid select @subid = subid from sysmergesubscriptions where @pubid = pubid and @srvid = srvid and pubid <> subid -- Get the merge_jobid from MSreplication_info using @subid select @job_id = merge_jobid from MSmerge_replinfo where @subid = repid -- Finally, get the owner_sid from msdb..sysjobs using @job_id select @owner_sid = owner_sid from msdb..sysjobs where @job_id = job_id end go exec dbo.sp_MS_marksystemobject 'sp_MSget_mergepullsubsagent_owner' raiserror('Creating procedure sp_dropmergepullsubscription', 0,1) GO CREATE PROCEDURE sp_dropmergepullsubscription( @publication sysname = NULL, /* Publication name */ @publisher sysname = NULL, /* Publisher server */ @publisher_db sysname = NULL, /* Publication database */ @reserved bit = 0 )AS SET NOCOUNT ON /* ** Declarations. */ declare @retcode int declare @subscriber_srvid int declare @publisher_srvid int declare @pubid uniqueidentifier declare @subid uniqueidentifier declare @partnerid uniqueidentifier declare @local_server sysname declare @local_db sysname declare @merge_jobid binary(16) declare @cmd nvarchar(255) declare @pubidstr nvarchar(38) declare @subscriber sysname declare @subscriber_db sysname declare @subscriber_type int declare @local_job bit declare @implicit_transaction int declare @close_cursor_at_commit int declare @owner_sid varbinary(85) declare @owner_name sysname declare @qualified_publication_name nvarchar(512) select @close_cursor_at_commit = 0 select @implicit_transaction = 0 /* ** Get original setting values before setting them to false for recursive calling */ IF (@reserved = 0) BEGIN SELECT @implicit_transaction = @@options & 2 SELECT @close_cursor_at_commit = @@options & 4 SET IMPLICIT_TRANSACTIONS OFF SET CURSOR_CLOSE_ON_COMMIT OFF END /* ** Security Check. */ exec @retcode = dbo.sp_MSreplcheck_subscribe if @@ERROR <> 0 or @retcode <> 0 return(1) /* ** Initializations. */ set @local_db = DB_NAME() set @local_server = @@SERVERNAME set @subscriber = @@SERVERNAME set @subscriber_db = DB_NAME() /* ** Assign parameter values appropriately */ select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber) IF @subscriber_srvid IS NULL BEGIN RAISERROR (14010, 16, -1) RETURN (1) END IF not exists (select name from sysobjects where name='sysmergesubscriptions') BEGIN RAISERROR (14055, 16, -1) RETURN (1) END /* ** Parameter Check: @publisher ** Check to make sure that the publisher is defined */ IF @publisher IS NULL BEGIN RAISERROR (14043, 16, -1, '@publisher') RETURN (1) END EXECUTE @retcode = dbo.sp_validname @publisher IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1) /* ** Parameter Check: @publisher_db */ IF @publisher_db IS NULL BEGIN RAISERROR (14043, 16, -1, '@publisher_db') RETURN (1) END /* ** Parameter Check: @publication. ** If the publication name is specified, check to make sure that it ** conforms to the rules for identifiers and that the publication ** actually exists. Disallow NULL. */ if @publication IS NULL BEGIN RAISERROR (14043, 16, -1, '@publication') RETURN (1) END IF LOWER(@publication) = 'all' BEGIN declare hC1 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT name FROM sysmergepublications FOR READ ONLY OPEN hC1 FETCH hC1 INTO @publication if @@fetch_status = -1 begin CLOSE hC1 DEALLOCATE hC1 RETURN (0) --- It's OK to have no publication when 'ALL' end WHILE (@@fetch_status <> -1) BEGIN EXECUTE dbo.sp_dropmergepullsubscription @publication = @publication, @publisher = @publisher, @publisher_db = @publisher_db, @reserved = 1 FETCH hC1 INTO @publication END CLOSE hC1 DEALLOCATE hC1 RETURN (0) END IF LOWER(@publisher) = 'all' BEGIN declare hC4 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT srvname FROM master..sysservers FOR READ ONLY OPEN hC4 FETCH hC4 INTO @publisher WHILE (@@fetch_status <> -1) BEGIN EXECUTE dbo.sp_dropmergepullsubscription @publication = @publication, @publisher = @publisher, @publisher_db = @publisher_db, @reserved = 1 FETCH hC4 INTO @publisher END CLOSE hC4 DEALLOCATE hC4 RETURN (0) END /* ** Validate that the publisher is a valid server */ select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher) IF @publisher_srvid IS NULL BEGIN --RAISERROR (14010, 16, -1) RETURN (1) END /* Previously the condition is set as 'AND subid<>pubid' which is fatally errorous */ IF LOWER(@publisher_db) = 'all' BEGIN declare hC5 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT db_name FROM sysmergesubscriptions WHERE subid = pubid and pubid in (select pubid from sysmergepublications where UPPER(publisher)=UPPER(@publisher) and name=@publication) FOR READ ONLY OPEN hC5 FETCH hC5 INTO @publisher_db WHILE (@@fetch_status <> -1) BEGIN EXECUTE dbo.sp_dropmergepullsubscription @publication = @publication, @publisher = @publisher, @publisher_db = @publisher_db, @reserved = 1 FETCH hC5 INTO @publisher_db END CLOSE hC5 DEALLOCATE hC5 RETURN (0) END /* ** return error if only there is no 'ALL'. Same is true for the rest of error handling. */ if NOT EXISTS (select * FROM sysmergepublications WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db) BEGIN if @reserved = 0 RAISERROR (20026, 16, -1, @publication) RETURN (1) END select @pubid = pubid from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db set @pubidstr = '''' + convert(nchar(36), @pubid) + '''' if @pubid is null BEGIN if @reserved = 0 RAISERROR (20026, 16, -1, @publication) RETURN (1) END /* ** Only members of the sysadmin group and the creator of the distribution ** agent can drop a pull subscription successfully. This behavior matches ** the behavior of the sysjobs_view. DBO of the subscriber database, ** sysadmins (owner is undefined) can drop a subscription if the owner_sid ** is null. */ EXEC sp_MSget_mergepullsubsagent_owner @publisher = @publisher, @publisher_db = @publisher_db, @publication = @publication, @owner_sid = @owner_sid OUTPUT IF (@owner_sid is not null AND (SUSER_SID() <> @owner_sid) AND (ISNULL(IS_SRVROLEMEMBER('sysadmin'),0) = 0)) BEGIN SELECT @owner_name = SUSER_SNAME(@owner_sid) SELECT @qualified_publication_name = @publisher + N':' + @publisher_db + N':' + @publication RAISERROR(21121,16,-1,@owner_name, @qualified_publication_name) RETURN (1) END /* ** Get subscriptions from either local replicas or global replicas */ select @subid = subs1.subid, @subscriber_type = subs1.subscriber_type, @partnerid = subs2.subid from sysmergesubscriptions subs1, sysmergesubscriptions subs2, sysmergepublications pubs where subs1.srvid = @subscriber_srvid and subs1.db_name = @subscriber_db and subs2.srvid = @publisher_srvid and subs2.db_name = @publisher_db and subs1.pubid = subs2.subid and subs2.pubid = pubs.pubid and pubs.name = @publication and UPPER(pubs.publisher)=UPPER(@publisher) and pubs.publisher_db=@publisher_db if @subid IS NULL begin if @reserved = 0 raiserror (14050, 16, -1) RETURN (0) end begin tran save TRAN dropmergepullsubscription /* ** Drop the local merge task */ select @merge_jobid = merge_jobid from MSmerge_replinfo WHERE repid = @subid if (@merge_jobid IS NOT NULL) BEGIN IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @merge_jobid) BEGIN EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @merge_jobid IF @@ERROR <> 0 or @retcode <> 0 GOTO FAILURE END END if @subid <> @partnerid BEGIN IF (@subscriber_type<>1) begin DELETE MSmerge_replinfo WHERE repid = @subid IF @@ERROR <> 0 GOTO FAILURE delete from sysmergesubscriptions where subid = @subid if @@ERROR <> 0 GOTO FAILURE end ELSE update sysmergesubscriptions set status = 2 where subid =@subid /* Call sp_MSunregistersubscription so that the reg entries get deleted */ exec @retcode = dbo.sp_MSunregistersubscription @publisher = @publisher, @publisher_db = @publisher_db, @publication = @publication, @subscriber = @@SERVERNAME, @subscriber_db = @subscriber_db IF @retcode<>0 or @@ERROR<>0 GOTO FAILURE exec dbo.sp_MSpublicationcleanup @publisher=@publisher, @publisher_db = @publisher_db, @publication = @publication IF @@ERROR <> 0 BEGIN RAISERROR (20025, 16, -1, @publication) GOTO FAILURE END END IF EXISTS(select * from sysobjects where type='U' and name = 'MSsubscription_properties') BEGIN DELETE FROM MSsubscription_properties WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db = @publisher_db AND publication = @publication IF @@ERROR <> 0 GOTO FAILURE IF NOT EXISTS (SELECT * FROM MSsubscription_properties) BEGIN DROP TABLE MSsubscription_properties IF @@ERROR <> 0 GOTO FAILURE END END /* ** If last subscription is dropped and the DB is not enabled for publishing, ** then remove the merge system tables */ IF (not exists (select * from sysmergesubscriptions )) AND (select category & 4 FROM master..sysdatabases WHERE name = DB_NAME())=0 BEGIN execute @retcode = dbo.sp_MSdrop_mergesystables if @@ERROR <> 0 or @retcode <> 0 begin return (1) end END COMMIT TRAN /* ** Set back original settings */ IF @reserved = 0 BEGIN IF @implicit_transaction <>0 SET IMPLICIT_TRANSACTIONS ON IF @close_cursor_at_commit <>0 SET CURSOR_CLOSE_ON_COMMIT ON END RETURN(0) FAILURE: RAISERROR (14056, 16, -1) if @@trancount > 0 begin ROLLBACK TRANSACTION dropmergepullsubscription COMMIT TRANSACTION end /* ** Set back original settings */ IF @reserved = 0 BEGIN IF @implicit_transaction <>0 SET IMPLICIT_TRANSACTIONS ON IF @close_cursor_at_commit <>0 SET CURSOR_CLOSE_ON_COMMIT ON END return 1 go exec dbo.sp_MS_marksystemobject sp_dropmergepullsubscription go grant execute on dbo.sp_dropmergepullsubscription to public go -- synctran supporting sprocs raiserror('Creating procedure sp_MSreplraiserror', 0,1) go create proc sp_MSreplraiserror @errorid int, @param1 sysname = null, @param2 sysname= null as if @errorid = 20508 raiserror (20508, 16, 1) else if @errorid = 20509 raiserror (20509, 16, 1) else if @errorid = 20510 raiserror (20510, 16, 1) else if @errorid = 20511 raiserror (20511, 16, 1) else if @errorid = 20512 raiserror (20512, 16, 1) else if @errorid = 20515 raiserror (20515, 16, 1) else if @errorid = 20516 raiserror (20516, 16, 1) else if @errorid = 20517 raiserror (20517, 16, 1) else if @errorid = 20518 raiserror (20518, 16, 1) else if @errorid = 20519 raiserror (20519, 16, 1) else if @errorid = 20520 raiserror (20520, 16, 1) else if @errorid = 21034 raiserror (21034, 16, 1) else if @errorid = 21054 raiserror (21054, 16, 1) go raiserror('Creating procedure sp_check_sync_trigger', 0,1) go create proc sp_check_sync_trigger @trigger_procid int, @trigger_op char(10) OUTPUT as select @trigger_op = NULL -- debug -- select 'Entered sp_check_synctrigger', 'calling trigger' = object_name(@trigger_procid) -- debug declare @trigid int select @trigid = so1.id from sysobjects so1, sysobjects so2 where so1.type = N'TR' and so1.name like N'trg_MSsync_ins_%' and so1.parent_obj = so2.parent_obj and so2.id = @trigger_procid -- if nestlevel of insert trigger on same table > 0 then bail if trigger_nestlevel( @trigid ) > 0 begin -- debug -- select 'sp_check_synctrigger: synctran insert trigger is active, so do nothing' -- debug return 1 end else return 0 go raiserror('Creating procedure sp_check_for_sync_trigger', 0,1) go create proc sp_check_for_sync_trigger @tabid int, @trigger_op char(10) = NULL OUTPUT as select @trigger_op = NULL -- debug -- select 'Entered sp_check_for_sync_trigger', 'calling trigger' = object_name(@trigger_procid) -- debug declare @ins_trigid int declare @upd_trigid int declare @del_trigid int select @ins_trigid = id from sysobjects where type = N'TR' and name like N'trg_MSsync_ins_%' and parent_obj = @tabid select @upd_trigid = id from sysobjects where type = N'TR' and name like N'trg_MSsync_upd_%' and parent_obj = @tabid select @del_trigid = id from sysobjects where type = N'TR' and name like N'trg_MSsync_del_%' and parent_obj = @tabid if trigger_nestlevel( @ins_trigid ) > 0 begin -- debug -- select 'sp_check_for_sync_trigger: synctran insert trigger is active' -- debug select @trigger_op = 'ins' return 1 end else -- if nestlevel of insert trigger on same table > 0 then bail if trigger_nestlevel( @upd_trigid ) > 0 begin -- debug -- select 'sp_check_for_sync_trigger: synctran update trigger is active' -- debug select @trigger_op = 'upd' return 1 end else if trigger_nestlevel( @del_trigid ) > 0 begin -- debug -- select 'sp_check_for_sync_trigger: synctran update trigger is active' -- debug select @trigger_op = 'del' return 1 end else return 0 go raiserror('Creating procedure sp_MSpad_command', 0,1) go create proc sp_MSpad_command @cmd nvarchar(4000) output, @indent int = 0 -- indent for command buffer (for pretty formatting as declare @cnt int select @cmd = N'' select @cnt = 0 while (@cnt < @indent) begin select @cmd = @cmd + N' ' select @cnt = @cnt + 1 end go raiserror('Creating procedure sp_MSflush_command', 0,1) go create proc sp_MSflush_command @cmd nvarchar(4000) output, @force int, -- 0 = flush if necesssary, 1 = flush always @indent int = 0 -- indent for command buffer (for pretty formatting as -- debug -- if len(@cmd) >= 4000 -- begin -- raiserror("buffer overflow!", 16, 1) -- select @cmd -- end -- debug if @force = 1 or len( @cmd ) > 3000 begin insert into #proctext(procedure_text) values( @cmd ) select @cmd = N'' if @indent > 0 exec dbo.sp_MSpad_command @cmd output, @indent end go raiserror('Creating procedure sp_MSget_colinfo', 0,1) go create proc sp_MSget_colinfo @objid int, @colid int, @columns binary(32), @bGetTextImageInfo tinyint = 0, -- boolean for returning text/image info @colname sysname output, @ccoltype sysname output as declare @isset int if @columns is not NULL -- this code path for synctran procs exec @isset = dbo.sp_isarticlecolbitset @colid, @columns else -- this code path for synctran triggers select @isset = 1 if @isset != 0 begin select @colname = c.name, @ccoltype= t.name from syscolumns c, systypes t where id = @objid and colid = @colid and c.xtype = t.xusertype -- when checking replicated columns, text/image datatypes cannot be declared or used locally if (@bGetTextImageInfo = 0) and (@ccoltype in (N'text',N'ntext',N'image')) return 1 end else begin select @colname = null, @ccoltype = null return 1 end return 0 go raiserror('Creating procedure sp_MSget_col_position ', 0,1) go create procedure sp_MSget_col_position @objid int, @columns binary(32), @key sysname, @colpos sysname output, @art_col int = NULL output, @get_num_col bit = 0, @num_col int = NULL output, @this_col int = null output as declare @colname sysname declare @ccoltype sysname declare @src_cols int declare @rc int select @src_cols = count(*) from syscolumns where id = @objid select @this_col = 1 select @num_col = 0 while @this_col <= @src_cols begin exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, @columns, 0, @colname output, @ccoltype output if @rc = 0 begin set @num_col = @num_col + 1 -- If @get_num_col is 1, we just need the number of columns in the partition. if @get_num_col = 0 and @colname = @key begin select @colpos = 'c' + convert(varchar(4), @this_col) set @art_col = @num_col break end end set @this_col = @this_col + 1 end return 0 go raiserror('Creating procedure sp_MSget_type', 0,1) go create proc sp_MSget_type @tabid int, @colid int, @colname sysname output, @typestring nvarchar(4000) output as declare @ccolchar nvarchar(5) declare @coltype tinyint declare @prec smallint declare @scale int declare @ccoltype sysname declare @xtype int select @colname = c.name, @xtype = c.xtype, @prec = c.prec, @scale = c.scale, @ccoltype = t.name from syscolumns c, systypes t where c.id = @tabid and c.colid = @colid and c.xtype = t.xusertype select @typestring = @ccoltype -- datatypes requiring precision (nchar, nvarchar, binary, varbinary) -- format: @var