elect @frequency_relative_interval = @frequencyrelativeinterval if @frequency_recurrence_factor is null select @frequency_recurrence_factor = @frequencyrecurrencefactor if @frequency_subday is null select @frequency_subday = @frequencysubday if @frequency_subday_interval is null select @frequency_subday_interval = @frequencysubdayinterval if @active_start_time_of_day is null select @active_start_time_of_day = @activestarttimeofday if @active_end_time_of_day is null select @active_end_time_of_day = @activeendtimeofday if @active_start_date is null select @active_start_date = @activestartdate if @active_end_date is null select @active_end_date = @activeenddate begin transaction -- If push and agent name is not passed in, create local job. if @subscription_type = @push select @local_job = 1 else select @local_job = 0 insert into MSmerge_subscriptions values (@publisher_id, @publisher_db, @publication_id, @subscriber_id, @subscriber_db, @subscription_type, @sync_type, @status, getdate()) -- need to store GUID? if @@error <> 0 begin goto FAILURE end -- Create Merge Agent exec @retcode = dbo.sp_MSadd_merge_agent @name = @agent_name, @publisher = @publisher, @publisher_db = @publisher_db, @publication = @publication, @subscriber = @subscriber, @subscriber_db = @subscriber_db, @local_job = @local_job, @frequency_type = @frequency_type, @frequency_interval = @frequency_interval, @frequency_relative_interval = @frequency_relative_interval, @frequency_recurrence_factor = @frequency_recurrence_factor, @frequency_subday = @frequency_subday, @frequency_subday_interval = @frequency_subday_interval, @active_start_time_of_day = @active_start_time_of_day, @active_end_time_of_day = @active_end_time_of_day, @active_start_date = @active_start_date, @active_end_date = @active_end_date, @optional_command_line = @optional_command_line, @merge_jobid = @merge_jobid OUTPUT, @offloadagent = @offloadagent, @offloadserver = @offloadserver, @subscription_type = @subscription_type if @retcode <> 0 or @@error <> 0 begin goto FAILURE end commit transaction return (0) FAILURE: /* UNDONE : This code is specific to 6.X nested transaction semantics */ if @@TRANCOUNT = 1 ROLLBACK TRANSACTION else COMMIT TRANSACTION RETURN (1) ') if @@error <> 0 return 1 exec(' raiserror(15339,-1,-1,''sp_MSenum_merge_subscriptions'') ') if @@error <> 0 return 1 exec('create procedure sp_MSenum_merge_subscriptions @publisher sysname, @publisher_db sysname, @publication sysname, @exclude_anonymous bit = 0 as declare @subscriber sysname declare @subscriber_db sysname declare @subscriber_name sysname declare @type int declare @status int declare @agent_name nvarchar(100) declare @subscriber_id smallint declare @publisher_id smallint declare @start_time nvarchar(24) declare @time nvarchar(24) declare @duration int declare @comments nvarchar(255) declare @delivery_rate float declare @error_id int declare @publication_id int declare @publisher_insertcount int declare @publisher_updatecount int declare @publisher_deletecount int declare @publisher_conflictcount int declare @subscriber_insertcount int declare @subscriber_updatecount int declare @subscriber_deletecount int declare @subscriber_conflictcount int declare @job_id binary(16) declare @local_job bit declare @profile_id int declare @agent_id int declare @last_timestamp binary(8) declare @offload_enabled bit declare @offload_server sysname ,@subscriber_type tinyint set nocount on select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher) select @publication_id = publication_id from MSpublications where publisher_id = @publisher_id and publisher_db = @publisher_db and publication = @publication and publication_type = 2 -- Merge create table #merge_subscriptions (subscriber sysname NOT NULL, status int NOT NULL, subscriber_db sysname NOT NULL, type int NOT NULL, agent_name nvarchar(100) NOT NULL, last_action nvarchar(255) NULL, action_time nvarchar(24) NULL, start_time nvarchar(24) NULL, duration int NULL, delivery_rate float NULL, publisher_insertcount int NULL, publisher_updatecount int NULL, publisher_deletecount int NULL, publisher_conficts int NULL, subscriber_insertcount int NULL, subscriber_updatecount int NULL, subscriber_deletecount int NULL, subscriber_conficts int NULL, error_id int NULL, job_id binary(16) NULL, local_job bit NULL, profile_id int NOT NULL, agent_id int NOT NULL, last_timestamp binary(8) NOT NULL, offload_enabled bit NOT NULL, offload_server sysname NULL, subscriber_type tinyint NULL) -- This is to force all queries to return rows ordered by job_id create unique clustered index ucmerge_subscriptions ON #merge_subscriptions (agent_id) declare hC CURSOR LOCAL FAST_FORWARD FOR select subscriber_id, subscriber_db, name, job_id, local_job, profile_id, id, subscriber_name, offload_enabled, offload_server from MSmerge_agents where publisher_id = @publisher_id and publisher_db = @publisher_db and publication = @publication and (@exclude_anonymous = 0 or subscriber_name is null) for read only open hC fetch hC into @subscriber_id, @subscriber_db, @agent_name, @job_id, @local_job, @profile_id, @agent_id, @subscriber_name, @offload_enabled, @offload_server while (@@fetch_status <> -1) begin if @subscriber_name is not NULL begin select @subscriber = @subscriber_name select @subscriber_db = @subscriber_db + ''-'' + convert(nvarchar(12), @agent_id) select @type = 2 --anonymous subscription end else begin select @subscriber = srvname from master..sysservers where srvid=@subscriber_id select @type = subscription_type from MSmerge_subscriptions where publisher_id = @publisher_id and publisher_db = @publisher_db and publication_id = @publication_id and subscriber_id = @subscriber_id and subscriber_db = @subscriber_db select @subscriber_type = type from MSsubscriber_info where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) end -- Get the status of the agent select @status = 0 select @start_time = NULL, @time = NULL, @duration = NULL, @comments = NULL, @publisher_insertcount = NULL, @publisher_deletecount = NULL, @publisher_updatecount = NULL, @publisher_conflictcount = NULL, @subscriber_insertcount = NULL, @subscriber_deletecount = NULL, @subscriber_updatecount = NULL, @subscriber_conflictcount = NULL, @delivery_rate = NULL, @error_id = NULL, @last_timestamp = 0x00000000 select @status = isnull(runstatus,0), @start_time = convert(nvarchar(12), start_time, 112) + substring(convert(nvarchar(24), start_time, 121), 11, 13), @time = convert(nvarchar(12), time, 112) + substring(convert(nvarchar(24), time, 121), 11, 13), @duration = duration, @comments = comments, @publisher_insertcount = publisher_insertcount, @publisher_deletecount = publisher_deletecount, @publisher_updatecount = publisher_updatecount, @publisher_conflictcount = publisher_conflictcount, @subscriber_insertcount = subscriber_insertcount, @subscriber_deletecount = subscriber_deletecount, @subscriber_updatecount = subscriber_updatecount, @subscriber_conflictcount = subscriber_conflictcount, -- Note: return average rate here !!! delivery_rate column is current rate @delivery_rate = case when duration <> 0 then (publisher_insertcount + publisher_updatecount + publisher_deletecount + subscriber_insertcount + subscriber_updatecount + subscriber_deletecount)/duration when duration = 0 then 0 end, @error_id = error_id, @last_timestamp = timestamp from MSmerge_history where agent_id = @agent_id and timestamp = (select max(timestamp) from MSmerge_history where agent_id = @agent_id) /* Not currently working Build 351 timestamp = (select top 1 timestamp from MSmerge_history where agent_id = @agent_id order by timestamp DESC) */ insert into #merge_subscriptions values ( @subscriber, @status, @subscriber_db, @type, @agent_name, @comments, @time, @start_time, @duration, @delivery_rate, @publisher_insertcount, @publisher_updatecount, @publisher_deletecount, @publisher_conflictcount, @subscriber_insertcount, @subscriber_updatecount, @subscriber_deletecount, @subscriber_conflictcount, @error_id, @job_id, @local_job, @profile_id, @agent_id, @last_timestamp, @offload_enabled, @offload_server, @subscriber_type) fetch hC into @subscriber_id, @subscriber_db, @agent_name, @job_id, @local_job, @profile_id, @agent_id, @subscriber_name, @offload_enabled, @offload_server end select * from #merge_subscriptions order by job_id asc drop table #merge_subscriptions close hC deallocate hC ') if @@error <> 0 return 1 exec(' raiserror(15339,-1,-1,''sp_update_agent_profile'') ') if @@error <> 0 return 1 exec(' -- Update the profile for an agent CREATE PROCEDURE sp_update_agent_profile ( @agent_type int, @agent_id int, @profile_id int ) AS SET NOCOUNT ON DECLARE @proc nvarchar(255) DECLARE @snapshot_type int DECLARE @logreader_type int DECLARE @distribution_type int DECLARE @merge_type int DECLARE @qreader_type int SELECT @snapshot_type = 1 SELECT @logreader_type = 2 SELECT @distribution_type = 3 SELECT @merge_type = 4 SELECT @qreader_type = 9 IF @agent_type NOT IN (@snapshot_type, @logreader_type, @distribution_type, @merge_type, @qreader_type) RETURN (1) /* The profile must be defined for the agent type in MSagent_profiles table */ IF NOT EXISTS ( select * from msdb..MSagent_profiles where profile_id = @profile_id and agent_type = @agent_type ) RETURN (1) -- The system ''SkipErrors'' profile is for sql subscribers only. if @distribution_type = @agent_type and @profile_id = 14 begin declare @subscriber_id int, @publisher_id int select top 1 @publisher_id = publisher_id, @subscriber_id = subscriber_id from MSsubscriptions where agent_id = @agent_id declare @subscriber sysname, @publisher sysname select @publisher = srvname from master..sysservers where srvid = @publisher_id select @subscriber = srvname from master..sysservers where srvid = @subscriber_id -- Use ''exists'' not ''not exists'' to take care null @publisher or @subscriber if exists (select * from MSsubscriber_info where upper(publisher) = upper(@publisher) and upper(subscriber) = upper(@subscriber) and type <> 0) begin raiserror(20603, 16, -1) return 1 end end SELECT @proc = ''UPDATE '' + CASE @agent_type WHEN @snapshot_type THEN ''MSsnapshot_agents'' WHEN @logreader_type THEN ''MSlogreader_agents'' WHEN @distribution_type THEN ''MSdistribution_agents'' WHEN @merge_type THEN ''MSmerge_agents'' WHEN @qreader_type THEN ''MSqreader_agents'' END + '' SET profile_id = '' + convert(nvarchar(10), @profile_id) + '' WHERE id = '' + convert(nvarchar(10), @agent_id) EXECUTE (@proc) IF @@ERROR <> 0 RETURN (1) ') if @@error <> 0 return 1 exec(' raiserror(15339,-1,-1,''sp_MSprofile_in_use'') ') if @@error <> 0 return 1 exec(' CREATE PROCEDURE sp_MSprofile_in_use ( @tablename nvarchar(255), @profile_id int ) AS DECLARE @usage_count int IF @tablename IS NULL OR @profile_id IS NULL return 1 ; IF @tablename = ''MSsnapshot_agents'' SELECT @usage_count = count(*) FROM MSsnapshot_agents WHERE profile_id = @profile_id ELSE IF @tablename = ''MSlogreader_agents'' SELECT @usage_count = count(*) FROM MSlogreader_agents WHERE profile_id = @profile_id ELSE IF @tablename = ''MSdistribution_agents'' SELECT @usage_count = count(*) FROM MSdistribution_agents WHERE profile_id = @profile_id ELSE IF @tablename = ''MSmerge_agents'' SELECT @usage_count = count(*) FROM MSmerge_agents WHERE profile_id = @profile_id ELSE SELECT @usage_count = 0 IF @usage_count = 0 RETURN -1 ELSE RETURN 0 ') if @@error <> 0 return 1 exec(' raiserror(15339,-1,-1,''sp_MSreset_subscription'') ') if @@error <> 0 return 1 exec('CREATE PROCEDURE sp_MSreset_subscription ( @publisher sysname, @publisher_db sysname, @publication sysname, @subscriber sysname, @subscriber_db sysname, @subscription_type int -- have to have it to identify a distribution agent. ) AS SET NOCOUNT ON /* ** Declarations. */ DECLARE @retcode int DECLARE @publisher_id smallint DECLARE @subscriber_id smallint DECLARE @virtual smallint declare @publication_id int declare @immediate_sync bit /* ** Initializations */ select @virtual = -1 select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher) select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber) select @publication_id = publication_id, @immediate_sync = immediate_sync from MSpublications where publisher_id = @publisher_id AND publisher_db = @publisher_db AND publication = @publication if @subscriber is NULL select @subscriber_id = @virtual -- No need to have 2 updates in one transaction. if @immediate_sync = 1 begin UPDATE MSdistribution_agents SET subscription_guid = newid() WHERE publisher_id = @publisher_id AND publisher_db = @publisher_db AND publication = @publication and subscriber_id = @subscriber_id and subscriber_db = @subscriber_db and subscription_type = @subscription_type IF @@ERROR <> 0 GOTO UNDO end UPDATE MSsubscriptions set subscription_time = getdate() WHERE publisher_id = @publisher_id AND publisher_db = @publisher_db AND publication_id = @publication_id and subscriber_id = @subscriber_id and subscriber_db = @subscriber_db and subscription_type = @subscription_type IF @@ERROR <> 0 GOTO UNDO RETURN(0) UNDO: return(1) ') if @@error <> 0 return 1 exec(' raiserror(15339,-1,-1,''sp_MSget_subscription_guid'') ') if @@error <> 0 return 1 exec('CREATE PROCEDURE sp_MSget_subscription_guid ( @agent_id int ) as begin set nocount on -- You need to make change to sp_MShelp_distribution_agentid when changing -- this. -- Get subscription_guid select a1.subscription_guid from MSdistribution_agents a1 where -- for non anonymous agents ((a1.virtual_agent_id is null and a1.id = @agent_id) or ( -- for anonymous agents a1.id = (select virtual_agent_id from MSdistribution_agents a2 where a2.id = @agent_id)) -- virtual account ) end ') if @@error <> 0 return 1 exec(' raiserror(15339,-1,-1,''sp_MSreset_subscription_seqno'') ') if @@error <> 0 return 1 exec('CREATE PROCEDURE sp_MSreset_subscription_seqno ( @agent_id int, @get_snapshot bit ) as set nocount on declare @publication_id int declare @sub_agent_id int declare @virtual_anonymous smallint declare @virtual smallint declare @retcode int declare @automatic tinyint select @automatic = 1 select @virtual = -1 select @virtual_anonymous = -2 -- Security Check exec @retcode = dbo.sp_MScheck_pull_access @agent_id = @agent_id, @agent_type = 0 -- distribution agent if @@error <> 0 or @retcode <> 0 return (1) -- Get version agent_id select top 1 @sub_agent_id = s2.agent_id from MSsubscriptions s1, MSsubscriptions s2 where s1.publisher_id = s2.publisher_id and s1.publisher_db = s2.publisher_db and s1.publication_id = s2.publication_id and s1.agent_id = @agent_id and s2.subscriber_id = case @get_snapshot when 0 then @virtual_anonymous else @virtual end -- If there are no virtual subscriptions defined. Don''t reset. -- This might happen when the distribution agent tries to -- reset an subscription on a non immediate_sync publication -- (this can -- only happen when the publication is changed from immediate_sync to non -- immdiate_sync after the distribution agent has queried the immediate_sync -- property) if @sub_agent_id = 0 return 0 -- ''no_sync'' subscriptions are handled differently if exists (select * from MSsubscriptions where agent_id = @agent_id and sync_type <> @automatic) begin -- If @get_snapshot = 0, the distribution agent is process the attached -- subscription for the first time. Set subscription_seqno to zero so that -- all changes that are not in the subscription copy will be picked up. -- Otherwise, do noting. if @get_snapshot = 0 begin update MSsubscriptions set -- Use current date rather than virtual sub date for the -- calculation in cleanup subscription_time = getdate(), -- lsn should be ten bytes long. We will not be here -- if the publisher is 6.x since 6x publisher does not -- support immediate_sync (thus does not support subscription copy as well) subscription_seqno = 0x00000000000000000000, publisher_seqno = 0x00000000000000000000, ss_cplt_seqno = 0x00000000000000000000 from MSsubscriptions rs1 where agent_id = @agent_id end return 0 end -- Reset the subscription status to be that of the virtual_anonymous subscription. -- Thus, only the snapshot transactions that are later than the subscriber transaction -- timestamp will be picked up (i.e., new article or schema change article.) update MSsubscriptions set snapshot_seqno_flag = (select snapshot_seqno_flag from MSsubscriptions rs2 where rs2.agent_id = @sub_agent_id and rs2.article_id = rs1.article_id), status = (select status from MSsubscriptions rs2 where rs2.agent_id = @sub_agent_id and rs2.article_id = rs1.article_id), -- Use current date rather than virtual sub date for the -- calculation in cleanup subscription_time = getdate(), subscription_seqno = (select subscription_seqno from MSsubscriptions rs2 where rs2.agent_id = @sub_agent_id and rs2.article_id = rs1.article_id), publisher_seqno = (select publisher_seqno from MSsubscriptions rs2 where rs2.agent_id = @sub_agent_id and rs2.article_id = rs1.article_id), ss_cplt_seqno = (select ss_cplt_seqno from MSsubscriptions rs2 where rs2.agent_id = @sub_agent_id and rs2.article_id = rs1.article_id) from MSsubscriptions rs1 where agent_id = @agent_id if @@ERROR <> 0 return 1 ') if @@error <> 0 return 1 exec(' raiserror(15339,-1,-1,''sp_MShelp_profile'') ') if @@error <> 0 return 1 exec(' CREATE PROCEDURE sp_MShelp_profile ( @agent_id int, @agent_type int, @profile_name sysname = NULL ) as declare @profile_id int declare @snapshot_type int declare @logreader_type int declare @distribution_type int declare @merge_type int declare @qreader_type int select @snapshot_type = 1 select @logreader_type = 2 select @distribution_type = 3 select @merge_type = 4 select @qreader_type = 9 select @profile_id = NULL if (@profile_name is not null) and (rtrim(ltrim(@profile_name)) <> '''') begin select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = @agent_type and profile_name = @profile_name /* raise error if profile not found */ if (@profile_id is null) begin raiserror(21123, 16, -1, @profile_name) return (1) end end -- if profile name not specified, use default. if (@profile_id is null) begin if @agent_type = @snapshot_type begin if @agent_id = 0 select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = @agent_type and def_profile = 1 else select @profile_id = profile_id from MSsnapshot_agents where id = @agent_id end else if @agent_type = @logreader_type begin if @agent_id = 0 select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = @agent_type and def_profile = 1 else select @profile_id = profile_id from MSlogreader_agents where id = @agent_id end else if @agent_type = @distribution_type begin if @agent_id = 0 select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = @agent_type and def_profile = 1 else select @profile_id = profile_id from MSdistribution_agents where id = @agent_id end else if @agent_type = @merge_type begin if @agent_id = 0 select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = @agent_type and def_profile = 1 else select @profile_id = profile_id from MSmerge_agents where id = @agent_id end else if @agent_type = @qreader_type begin if @agent_id = 0 select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = @agent_type and def_profile = 1 else select @profile_id = profile_id from MSqreader_agents where id = @agent_id end end select profile_id, parameter_name, value from msdb..MSagent_parameters where profile_id = @profile_id ') if @@error <> 0 return 1 exec(' raiserror(15339,-1,-1,''sp_MShelp_snapshot_agentid'') ') if @@error <> 0 return 1 exec(' CREATE PROCEDURE sp_MShelp_snapshot_agentid ( @publisher_id smallint, @publisher_db sysname, @publication sysname, @job_id binary(16) = NULL ) AS set nocount on declare @retcode int declare @publisher sysname declare @description nvarchar(255) -- Check if agent exists, if not and there is an 6.x tasks then create one if @publication is not null and @publication <> '''' and not exists (select * from MSsnapshot_agents where publisher_id = @publisher_id and publisher_db = @publisher_db and publication = @publication) begin -- Do it only if the agent name is valid. It will be the case if -- the agent is launched by SQL Server Agent if exists (select * from msdb..sysjobs_view where job_id = @job_id) begin select @publisher = srvname from master..sysservers where srvid = @publisher_id begin tran exec @retcode = dbo.sp_MSadd_snapshot_agent @publisher = @publisher, @publisher_db = @publisher_db, @publication = @publication, @local_job = 1, @job_existing = 1, @snapshot_jobid = @job_id if @@ERROR<> 0 or @retcode <> 0 goto UNDO -- Add a publication definition so it shows up in monitoring procs set @description = formatmessage(20555) exec @retcode = dbo.sp_MSadd_publication @publisher = @publisher, @publisher_db = @publisher_db, @publication = @publication, @publication_type = 1, -- Make all 6.x pubs transactional @description = @description -- 6.x publication description if @@ERROR<> 0 or @retcode <> 0 goto UNDO commit tran end end select id, name from MSsnapshot_agents where publisher_id = @publisher_id and publisher_db = @publisher_db and publication = @publication return(0) UNDO: if @@TRANCOUNT = 1 ROLLBACK TRAN else COMMIT TRAN return(1) ') if @@error <> 0 return 1 exec(' raiserror(15339,-1,-1,''sp_MShelp_logreader_agentid'') ') if @@error <> 0 return 1 exec(' CREATE PROCEDURE sp_MShelp_logreader_agentid ( @publisher_id smallint, @publisher_db sysname ) AS set nocount on declare @retcode int declare @publisher sysname declare @job_id binary(16) declare @qv_package varchar(20) declare @desk_top int declare @license_value int declare @qv_value_package int select @qv_package = ''845129433'' select @license_value = 0 select @desk_top = 3 exec @qv_value_package = master.dbo.sp_MSinstance_qv @qv_package if @@ERROR<>0 begin raiserror(20089, 16, -1) return (1) end if @qv_value_package = 1 --- 1 means desktop select @license_value = @desk_top -- to be consistent with all other compenents. -- Check if agent exists, if not and there is an 6.x tasks then create one if not exists (select * from MSlogreader_agents where publisher_id = @publisher_id and publisher_db = @publisher_db) begin select @publisher = srvname from master..sysservers where srvid = @publisher_id -- Do it only if the agent name is valid. It will be the case if -- the agent is launched by SQL Server Agent select @job_id = id.job_id from msdb..systasks_view v, msdb..systaskids id where v.server = @publisher and v.databasename = @publisher_db and v.subsystem = ''LogReader'' and v.id = id.task_id if @job_id is not NULL begin exec @retcode = dbo.sp_MSadd_logreader_agent @publisher = @publisher, @publisher_db = @publisher_db, -- ''ALL'' is Used in sp_addpublication as well @publication = ''ALL'', @local_job = 1, @job_existing = 1, @job_id = @job_id if @@ERROR<> 0 or @retcode <> 0 return(1) end end select id, name, @license_value from MSlogreader_agents where publisher_id = @publisher_id and publisher_db = @publisher_db return(0) ') if @@error <> 0 return 1 exec(' /* ** This procedure is to add an agent row in MSmerge_agents for an anonymous subscription, ** if it is not already there. If it is, return the agentid and agent name for monitoring ** purpose. */ raiserror(15339,-1,-1,''sp_MSadd_merge_anonymous_agent'') ') if @@error <> 0 return 1 exec(' CREATE PROCEDURE sp_MSadd_merge_anonymous_agent ( @publisher_id smallint, @publisher_db sysname, @publication sysname, @subscriber_db sysname, @subscriber_name sysname, @subid uniqueidentifier, @first_anonymous int -- 0 means this is the first time for this anonymous agent being ran. ) AS declare @min_valid_day datetime declare @merge_type int declare @profile_id int declare @subscriber_id smallint declare @agent_name sysname declare @agent_id int declare @retcode int declare @publication_id int declare @not_exist bit declare @last_status int declare @last_history datetime declare @merge_jobid uniqueidentifier declare @by_pass bit declare @retention int declare @success int declare @expired int declare @dropped int declare @allow_anonymous bit select @dropped = 0 select @expired = 0 select @success = 2 select @by_pass = 0 /* ** This stored procedure does not really add a job at distribution database; ** if add a row in MSmerge_agent table for anonymous subscription for the ** purpose of history logging */ -- Check to see if the publication is valid and allow anonymous select @publication_id = publication_id, @allow_anonymous = allow_anonymous, @retention = retention from MSpublications where publisher_id = @publisher_id and publisher_db = @publisher_db and publication = @publication if @publication_id is null begin RAISERROR (21040, 16, -1, @publication) return 1 end if @allow_anonymous = 0 begin RAISERROR (21084, 16, -1, @publication) return 1 end if @subscriber_name is null select @subscriber_name = N'''' if @retention is NULL or @retention =0 select @by_pass = 1 -- Security check exec @retcode = dbo.sp_MScheck_pull_access @publication_id = @publication_id, @agent_type = 1 if @retcode <> 0 or @@error <> 0 return (1) select @not_exist = 0 SELECT @merge_type = 4 select @subscriber_id = 0 -- For anonymous subscribers, ID is always 0 SELECT @profile_id = profile_id FROM msdb..MSagent_profiles WHERE agent_type = @merge_type AND def_profile = 1 IF @profile_id IS NULL RETURN (1) /* ** This is to handle Jet only */ IF @subid = ''00000000-0000-0000-0000-000000000000'' begin select @subid = anonymous_subid from MSmerge_agents where publisher_id=@publisher_id and publisher_db = @publisher_db and publication = @publication and subscriber_name = @subscriber_name and subscriber_db = @subscriber_db if @subid = ''00000000-0000-0000-0000-000000000000'' select @subid = newid() else select @first_anonymous = 1 -- for Jet, schemaversion should not be 0 in this path. end IF NOT EXISTS (select * from MSmerge_agents where anonymous_subid=@subid) begin if @first_anonymous <= 0 --only add agent entry for initial subscription only. begin select @not_exist = 1 -- Generate a job GUID for remote agents. This will be used by the UI to uniquely -- identify rows returned by the enums set @merge_jobid = newid(); insert into MSmerge_agents (name, publisher_id, publisher_db, publication, subscriber_id, subscriber_db, anonymous_subid, job_id, profile_id, subscriber_name) VALUES (convert(nvarchar(40), @subid), @publisher_id, @publisher_db, @publication, @subscriber_id, @subscriber_db, @subid, @merge_jobid, @profile_id, @subscriber_name) end else select @dropped =1 end select @agent_id = id, @agent_name = name from MSmerge_agents where anonymous_subid=@subid -- subid guarantees uniqueness if @by_pass = 0 --by pass the checking if retention is NULL or 0 begin select @min_valid_day = dateadd(day, -@retention, getdate()) select Top 1 @last_status = runstatus, @last_history = time from MSmerge_history where agent_id = @agent_id order by time DESC --failures and in-progress messages do not count, if there were previous successes. if (@last_status = 6 or @last_status = 3) and EXISTS (select * from MSmerge_history where agent_id = @agent_id and runstatus = 2) select Top 1 @last_history = time from MSmerge_history where agent_id = @agent_id and runstatus = 2 order by time DESC /* ** This anonymous subscription is gone for too long to be efficiently reconciled. Either reinitialization or ** re-deployment of this subscription is needed. Merge agent will fail. */ if @last_history < @min_valid_day and @first_anonymous <> 0 --do not check for re-initialized replicas. select @expired = 1 end select @agent_id, @agent_name, @expired where @dropped = 0 --return empty result set ') if @@error <> 0 return 1 exec(' raiserror(15339,-1,-1,''sp_MShelp_merge_agentid'') ') if @@error <> 0 return 1 exec(' CREATE PROCEDURE sp_MShelp_merge_agentid ( @publisher_id smallint, @publisher_db sysname, @publication sysname, @subscriber_id smallint, @subscriber_db sysname ) AS declare @publisher sysname declare @subscriber sysname declare @expired int declare @agent_id int declare @name sysname declare @retention int declare @last_status int declare @last_history datetime declare @min_valid_day datetime declare @reinited int declare @status int declare @success int declare @publication_id int declare @subscriber_datasource_type int declare @sql_subscriber int select @expired = 0 select @reinited = 4 select @success = 2 select @subscriber_datasource_type = 0 select @sql_subscriber = 0 if not EXISTS (select * from MSpublications where publisher_id=@publisher_id and publisher_db = @publisher_db and publication = @publication and publication_type = 2) -- merge publication is gone begin select 1, @publication, 1, 0 --third column = 1 means publication is gone, making the other values meanningless. return (1) end select @publication_id = publication_id from MSpublications where publisher_id = @publisher_id and publisher_db = @publisher_db and publication = @publication -- Get subscriber info select @subscriber = srvname from master..sysservers where srvid = @subscriber_id select @publisher = srvname from master..sysservers where srvid = @publisher_id select @subscriber_datasource_type = type from MSsubscriber_info where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) if (@subscriber_datasource_type = @sql_subscriber) begin select @status = status from MSmerge_subscriptions where publisher_id = @publisher_id and publisher_db = @publisher_db and publication_id = @publication_id and subscriber_id = @subscriber_id and subscriber_db = @subscriber_db select @agent_id = id, @name = name from MSmerge_agents where publisher_id = @publisher_id and publisher_db = @publisher_db and publication = @publication and subscriber_id = @subscriber_id and subscriber_db = @subscriber_db end else begin select @status = status from MSmerge_subscriptions where publisher_id = @publisher_id and publisher_db = @publisher_db and publication_id = @publication_id and subscriber_id = @subscriber_id select @agent_id = id, @name = name from MSmerge_agents where publisher_id = @publisher_id and publisher_db = @publisher_db and publication = @publication and subscriber_id = @subscriber_id end -- Security check. Do it here to let the agent fail at the beginning if @agent_id is not null begin exec dbo.sp_MScheck_pull_access @agent_id = @agent_id, @agent_type = 1 -- merge agent select @retention = retention from MSpublications where publisher_id=@publisher_id and publisher_db=@publisher_db and publication=@publication if @retention is not NULL and @retention > 0 begin select @min_valid_day = dateadd(day, @retention * (-1), getdate()) select Top 1 @last_status = runstatus, @last_history = time from MSmerge_history where agent_id = @agent_id order by time DESC if @last_status = 6 and EXISTS (select * from MSmerge_history where agent_id = @agent_id and runstatus = 2) select Top 1 @last_history = time from MSmerge_history where agent_id = @agent_id and runstatus = 2 order by time DESC if @last_history < @min_valid_day and @status <> @reinited select @expired = 1 end end select @agent_id, @name, 0, @expired where @agent_id is not NULL ') if @@error <> 0 return 1 exec(' raiserror(15339,-1,-1,''sp_MSdistpublisher_cleanup'') ') if @@error <> 0 return 1 exec(' CREATE PROCEDURE sp_MSdistpublisher_cleanup @publisher sysname as set nocount on declare @publisher_id smallint declare @job_id binary(16) declare @retcode int -- Delete agents -- Get the publisher id -- Check if publisher is a defined as a distribution publisher in the current database exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT if @retcode <> 0 begin return(1) end -- Dropping local jobs -- Use union in ''select''. Insensitive cursor will be used automatically. DECLARE hCagents CURSOR LOCAL FAST_FORWARD FOR SELECT job_id FROM MSsnapshot_agents WHERE publisher_id = @publisher_id and local_job = 1 UNION SELECT job_id FROM MSlogreader_agents WHERE publisher_id = @publisher_id and local_job = 1 UNION SELECT job_id FROM MSdistribution_agents WHERE publisher_id = @publisher_id and local_job = 1 UNION SELECT job_id FROM MSmerge_agents WHERE publisher_id = @publisher_id and local_job = 1 FOR READ ONLY OPEN hCagents FETCH hCagents INTO @job_id WHILE (@@fetch_status <> -1) BEGIN IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id) BEGIN exec @retcode = msdb.dbo.sp_delete_job @job_id = @job_id if @retcode <> 0 or @@error <> 0 return(1) END FETCH hCagents INTO @job_id end -- Clean up the tables, including -- 4 Agent tables -- 2 subscription tables -- article table -- publication table -- 2 subscriber table -- The order is to avoid breaking monitoring delete MSpublisher_databases where publisher_id = @publisher_id if @@error <> 0 return (1) delete MSpublications where publisher_id = @publisher_id if @@error <> 0 return