home *** CD-ROM | disk | FTP | other *** search
/ 95.86.62.111 / 95.86.62.111.tar / 95.86.62.111 / sql2000 / INSTALL / instdist.sql < prev    next >
Text File  |  2000-07-25  |  757KB  |  21,309 lines

  1. /*
  2. ** InstDist.SQL   
  3. **
  4. **
  5. ** Copyright Microsoft, Inc. 1998-2000
  6. ** All Rights Reserved.
  7. */
  8.  
  9.  
  10. if (    (db_id()     = 1)  -- 'master' db
  11.     OR
  12.         is_srvrolemember('sysadmin') <> 1  -- SA
  13.    )
  14.     begin
  15.     raiserror('Error, the ''master'' database cannot be the distribution database.  This ISQL run will terminate now.'
  16.                  ,11,127)  -- State=127 should halt ISQL.EXE
  17.     end
  18.  
  19. if (    (db_id()     = 1)  -- 'master' db
  20.     OR
  21.         is_srvrolemember('sysadmin') <> 1 -- SA
  22.    )
  23.     begin
  24.     raiserror('Minor error, because previous attempt to gently terminate ISQL failed.  Harshly killing spid.'
  25.                  ,22,127) with log   -- SeverityLevel>=19 kills spid.
  26.     end
  27. select 'At top, db_name()=',db_name()
  28.  
  29. go
  30.  
  31.  
  32. declare @dbname sysname
  33. select  @dbname = db_name()
  34. execute('dump transaction ' +@dbname+ ' with no_log')
  35. go
  36. checkpoint
  37.  
  38. go
  39. EXEC dbo.sp_configure 'allow updates', 1
  40. GO
  41. reconfigure with override
  42. GO
  43.  
  44. set ANSI_NULLS off
  45. go
  46.  
  47. --
  48. -- Check and make sure the database has the correct compatibility level
  49. --
  50. declare @dbname sysname
  51.         ,@cmptlevelmaster tinyint
  52.         ,@cmptlevel tinyint
  53.         
  54. select  @dbname = db_name()
  55. select     @cmptlevelmaster = cmptlevel from master.dbo.sysdatabases where name = 'master'
  56. select     @cmptlevel = cmptlevel from master.dbo.sysdatabases where name = @dbname
  57. if (@cmptlevel != @cmptlevelmaster)
  58. begin
  59.     raiserror('Warning: Distribution database ''%s'' has compatibility level of %d. Changing it to %d.'
  60.         ,10, 1, @dbname, @cmptlevel, @cmptlevelmaster)
  61.     exec dbo.sp_dbcmptlevel @dbname, @cmptlevelmaster
  62. end
  63. go
  64.  
  65. /****************************************************************************/
  66. PRINT ''
  67. PRINT 'Creating distribution tables'
  68. PRINT ''
  69. /****************************************************************************/
  70. EXEC dbo.sp_MScreate_dist_tables
  71. go
  72.  
  73. declare @dbname sysname
  74. select  @dbname = db_name()
  75. execute('dump transaction ' +@dbname+ ' with no_log')
  76. go
  77.  
  78. exec dbo.sp_MS_upd_sysobj_category 1  --Capture now_datetime for use below.
  79.  
  80. /****************************************************************************/
  81. PRINT ''
  82. PRINT 'Dropping all distribution stored procedures'
  83. PRINT ''
  84. /****************************************************************************/
  85. IF EXISTS (SELECT * FROM sysobjects WHERE
  86.    name = 'sp_MSadd_repl_command' and type = 'P')
  87.       DROP PROCEDURE sp_MSadd_repl_command
  88.  
  89. IF EXISTS (SELECT * FROM sysobjects WHERE
  90.    name = 'sp_MScheckretention' and type = 'P')
  91.       DROP PROCEDURE sp_MScheckretention
  92.  
  93. IF EXISTS (SELECT * FROM sysobjects WHERE
  94.    name = 'sp_MScheck_Jet_Subscriber' and type = 'P')
  95.       DROP PROCEDURE sp_MScheck_Jet_Subscriber
  96.  
  97. IF EXISTS (SELECT * FROM sysobjects WHERE
  98.    name = 'sp_MSadd_repl_commands27' and type = 'P')
  99.       DROP PROCEDURE sp_MSadd_repl_commands27
  100.  
  101. IF EXISTS (SELECT * FROM sysobjects WHERE
  102.    name = 'sp_MSadd_repl_commands27hp' and type = 'P')
  103.       DROP PROCEDURE sp_MSadd_repl_commands27hp
  104.  
  105. IF EXISTS (SELECT * FROM sysobjects WHERE
  106.    name = 'sp_MSadd_repl_commands27hp6x' and type = 'P')
  107.       DROP PROCEDURE sp_MSadd_repl_commands27hp6x
  108.  
  109. IF EXISTS (SELECT * FROM sysobjects WHERE
  110.    name = 'sp_MSrefresh_anonymous' and type = 'P')
  111.       DROP PROCEDURE sp_MSrefresh_anonymous
  112.       
  113. IF EXISTS (SELECT * FROM sysobjects WHERE
  114.    name = 'sp_MSadd_subscription' and type = 'P')
  115.       DROP PROCEDURE sp_MSadd_subscription
  116.  
  117. IF EXISTS (SELECT * FROM sysobjects WHERE                    
  118.    name = 'sp_MSdrop_subscription' and type = 'P')
  119.       DROP PROCEDURE sp_MSdrop_subscription
  120.  
  121. if exists (select * from sysobjects where 
  122.     type = 'P' and name = 'sp_MSfetchAdjustidentityrange')
  123.     drop procedure sp_MSfetchAdjustidentityrange
  124.  
  125. IF EXISTS (SELECT * FROM sysobjects WHERE   
  126.     name = 'sp_MSupdate_subscription' and type = 'P')
  127.        DROP PROCEDURE sp_MSupdate_subscription
  128.  
  129. IF EXISTS (SELECT * FROM sysobjects WHERE
  130.     name = 'sp_MSget_repl_commands' and type = 'P')
  131.        DROP PROCEDURE sp_MSget_repl_commands
  132.  
  133. IF EXISTS (SELECT * FROM sysobjects WHERE
  134.     name = 'sp_MSget_repl_cmds_anonymous' and type = 'P')
  135.        DROP PROCEDURE sp_MSget_repl_cmds_anonymous
  136.  
  137. IF EXISTS (select * from sysobjects where
  138.    name = 'sp_MSdrop_agent_entry' and type = 'P')
  139.       DROP PROCEDURE sp_MSdrop_agent_entry
  140.       
  141. IF EXISTS (SELECT * FROM sysobjects WHERE
  142.     name = 'sp_MSadd_anonymous_agent' and type = 'P')
  143.        DROP PROCEDURE sp_MSadd_anonymous_agent
  144.  
  145. -- SyncTran
  146.  
  147.  
  148. IF EXISTS (SELECT * FROM sysobjects WHERE
  149.     name = 'sp_MSget_undelivered_commands' and type = 'P')
  150.        DROP PROCEDURE sp_MSget_undelivered_commands
  151.  
  152. IF EXISTS (SELECT * FROM sysobjects WHERE
  153.     name = 'sp_MSget_anonymous_cmds' and type = 'P')
  154.        DROP PROCEDURE sp_MSget_anonymous_cmds
  155.  
  156. IF EXISTS (SELECT * FROM sysobjects WHERE
  157.     name = 'sp_MSget_loopback_cmds' and type = 'P')
  158.        DROP PROCEDURE sp_MSget_loopback_cmds
  159.  
  160. IF EXISTS (SELECT * FROM sysobjects WHERE
  161.     name = 'sp_MSanonymous_status' and type = 'P')
  162.        DROP PROCEDURE sp_MSanonymous_status
  163.  
  164. IF EXISTS (SELECT * FROM sysobjects WHERE
  165.     name = 'sp_MSsubscription_status' and type = 'P')
  166.        DROP PROCEDURE sp_MSsubscription_status
  167. GO    
  168.  
  169. declare @dbname sysname
  170. select  @dbname = db_name()
  171. execute('dump transaction ' +@dbname+ ' with no_log')
  172.  
  173. go
  174.  
  175. IF EXISTS (SELECT * FROM sysobjects WHERE
  176.    name = 'sp_MSget_last_transaction' and type = 'P')
  177.       DROP PROCEDURE sp_MSget_last_transaction
  178.     
  179.  
  180. IF EXISTS (SELECT * FROM sysobjects WHERE
  181.    name = 'sp_MSadd_subscriber_info' and type = 'P')
  182.       DROP PROCEDURE sp_MSadd_subscriber_info
  183.  
  184. IF EXISTS (SELECT * FROM sysobjects WHERE
  185.    name = 'sp_MSadd_subscriber_schedule' and type = 'P')
  186.       DROP PROCEDURE sp_MSadd_subscriber_schedule
  187.  
  188. IF EXISTS (SELECT * FROM sysobjects WHERE
  189.    name = 'sp_MSupdate_subscriber_info' and type = 'P')
  190.       DROP PROCEDURE sp_MSupdate_subscriber_info
  191.  
  192. IF EXISTS (SELECT * FROM sysobjects WHERE
  193.    name = 'sp_MSupdate_subscriber_schedule' and type = 'P')
  194.       DROP PROCEDURE sp_MSupdate_subscriber_schedule
  195.  
  196. IF EXISTS (SELECT * FROM sysobjects WHERE
  197.    name = 'sp_MSdrop_subscriber_info' and type = 'P')
  198.       DROP PROCEDURE sp_MSdrop_subscriber_info
  199.  
  200. IF EXISTS (SELECT * FROM sysobjects WHERE
  201.    name = 'sp_MShelp_subscriber_info' and type = 'P')
  202.       DROP PROCEDURE sp_MShelp_subscriber_info
  203.  
  204. IF EXISTS (select * from sysobjects where
  205.    name = 'sp_MSdistribution_counters' and type = 'P')
  206.       DROP PROCEDURE sp_MSdistribution_counters
  207.  
  208. IF EXISTS (select * from sysobjects where
  209.    name = 'sp_MSremove_published_jobs' and type = 'P')
  210.       DROP PROCEDURE sp_MSremove_published_jobs
  211.  
  212. IF EXISTS (select * from sysobjects where
  213.    name = 'sp_MSset_snapshot_xact_seqno' and type = 'P')
  214.       DROP PROCEDURE sp_MSset_snapshot_xact_seqno
  215.  
  216. IF EXISTS (select * from sysobjects where
  217.    name = 'sp_MSadd_snapshot_history' and type = 'P')
  218.       DROP PROCEDURE sp_MSadd_snapshot_history
  219.  
  220. IF EXISTS (select * from sysobjects where
  221.    name = 'sp_MSadd_logreader_history' and type = 'P')
  222.       DROP PROCEDURE sp_MSadd_logreader_history
  223.  
  224. IF EXISTS (select * from sysobjects where
  225.    name = 'sp_MSadd_distribution_history' and type = 'P')
  226.       DROP PROCEDURE sp_MSadd_distribution_history
  227.  
  228. IF EXISTS (select * from sysobjects where
  229.    name = 'sp_MSdistribution_cleanup' and type = 'P')
  230.       DROP PROCEDURE sp_MSdistribution_cleanup
  231.  
  232. IF EXISTS (select * from sysobjects where
  233.    name = 'sp_MSsubscription_cleanup' and type = 'P')
  234.       DROP PROCEDURE sp_MSsubscription_cleanup
  235.  
  236. IF EXISTS (select * from sysobjects where
  237.    name = 'sp_MSdistribution_delete' and type = 'P')
  238.       DROP PROCEDURE sp_MSdistribution_delete
  239.  
  240. IF EXISTS (select * from sysobjects where
  241.    name = 'sp_MSmaximum_cleanup_seqno' and type = 'P')
  242.       DROP PROCEDURE sp_MSmaximum_cleanup_seqno
  243.  
  244. IF EXISTS (select * from sysobjects where
  245.    name = 'sp_MSreplremoveuncdir' and type = 'P')
  246.       DROP PROCEDURE sp_MSreplremoveuncdir
  247.  
  248. IF EXISTS (select * from sysobjects where
  249.    name = 'sp_MSdrop_snapshot_dirs' and type = 'P')
  250.       DROP PROCEDURE sp_MSdrop_snapshot_dirs
  251.  
  252. IF EXISTS (select * from sysobjects where
  253.    name = 'sp_MSfast_delete_trans' and type = 'P')
  254.       DROP PROCEDURE sp_MSfast_delete_trans
  255.  
  256. IF EXISTS (select * from sysobjects where
  257.    name = 'sp_MSdelete_dodelete' and type = 'P')
  258.       DROP PROCEDURE sp_MSdelete_dodelete
  259.  
  260. IF EXISTS (select * from sysobjects where
  261.    name = 'sp_MSdelete_publisherdb_trans' and type = 'P')
  262.       DROP PROCEDURE sp_MSdelete_publisherdb_trans
  263.  
  264. IF EXISTS (select * from sysobjects where
  265.    name = 'sp_MShistory_cleanup' and type = 'P')
  266.       DROP PROCEDURE sp_MShistory_cleanup
  267.  
  268. IF EXISTS (select * from sysobjects where
  269.    name = 'sp_MSget_repl_version' and type = 'P')
  270.       DROP PROCEDURE sp_MSget_repl_version
  271.  
  272. IF EXISTS (select * from sysobjects where
  273.    name = 'sp_MSenum_subscriptions' and type = 'P')
  274.       DROP PROCEDURE sp_MSenum_subscriptions
  275.  
  276. IF EXISTS (select * from sysobjects where
  277.    name = 'sp_MSIfExistsSubscription' and type = 'P')
  278.       DROP PROCEDURE sp_MSIfExistsSubscription
  279.  
  280. IF EXISTS (select * from sysobjects where
  281.    name = 'sp_MSenum_snapshot' and type = 'P')
  282.       DROP PROCEDURE sp_MSenum_snapshot
  283.       
  284. IF EXISTS (select * from sysobjects where
  285.    name = 'sp_MSadd_merge_anonymous_agent' and type = 'P')
  286.       DROP PROCEDURE sp_MSadd_merge_anonymous_agent
  287.     
  288. IF EXISTS (select * from sysobjects where
  289.    name = 'sp_MSenum_snapshot_s' and type = 'P')
  290.       DROP PROCEDURE sp_MSenum_snapshot_s
  291.  
  292. IF EXISTS (select * from sysobjects where
  293.    name = 'sp_MSenum_snapshot_sd' and type = 'P')
  294.       DROP PROCEDURE sp_MSenum_snapshot_sd
  295.  
  296. IF EXISTS (select * from sysobjects where
  297.    name = 'sp_MSenum_logreader' and type = 'P')
  298.       DROP PROCEDURE sp_MSenum_logreader
  299.  
  300. IF EXISTS (select * from sysobjects where
  301.    name = 'sp_MSenum_logreader_s' and type = 'P')
  302.       DROP PROCEDURE sp_MSenum_logreader_s
  303.  
  304. IF EXISTS (select * from sysobjects where
  305.    name = 'sp_MSenum_logreader_sd' and type = 'P')
  306.       DROP PROCEDURE sp_MSenum_logreader_sd
  307.  
  308. IF EXISTS (select * from sysobjects where
  309.    name = 'sp_MSenum_qreader' and type = 'P')
  310.       DROP PROCEDURE sp_MSenum_qreader
  311.  
  312. IF EXISTS (select * from sysobjects where
  313.    name = 'sp_MSenum_qreader_s' and type = 'P')
  314.       DROP PROCEDURE sp_MSenum_qreader_s
  315.  
  316. IF EXISTS (select * from sysobjects where
  317.    name = 'sp_MSenum_qreader_sd' and type = 'P')
  318.       DROP PROCEDURE sp_MSenum_qreader_sd
  319.  
  320. IF EXISTS (select * from sysobjects where
  321.    name = 'sp_MSenum_distribution' and type = 'P')
  322.       DROP PROCEDURE sp_MSenum_distribution
  323.  
  324. IF EXISTS (select * from sysobjects where
  325.    name = 'sp_MSenum_distribution_s' and type = 'P')
  326.       DROP PROCEDURE sp_MSenum_distribution_s
  327.  
  328. IF EXISTS (SELECT * FROM sysobjects WHERE
  329.    name = 'sp_MShelp_subscription_status' and type = 'P')
  330.       DROP PROCEDURE sp_MShelp_subscription_status
  331.  
  332. IF EXISTS (SELECT * FROM sysobjects WHERE
  333.    name = 'sp_MScleanup_agent_entry' and type = 'P')
  334.       DROP PROCEDURE sp_MScleanup_agent_entry
  335.  
  336. IF EXISTS (select * from sysobjects where
  337.    name = 'sp_MSenum_distribution_sd' and type = 'P')
  338.       DROP PROCEDURE sp_MSenum_distribution_sd
  339.  
  340. IF EXISTS (select * from sysobjects where
  341.    name = 'sp_MSenum_merge' and type = 'P')
  342.       DROP PROCEDURE sp_MSenum_merge
  343.  
  344. IF EXISTS (select * from sysobjects where
  345.    name = 'sp_MSenum_merge_s' and type = 'P')
  346.       DROP PROCEDURE sp_MSenum_merge_s
  347.  
  348. IF EXISTS (select * from sysobjects where
  349.    name = 'sp_MSenum_merge_sd' and type = 'P')
  350.       DROP PROCEDURE sp_MSenum_merge_sd
  351.  
  352. IF EXISTS (select * from sysobjects where
  353.    name = 'sp_MSgetagentoffloadinfo' and type = 'P')
  354.       DROP PROCEDURE sp_MSgetagentoffloadinfo
  355.  
  356. IF EXISTS (select * from sysobjects where
  357.    name = 'sp_MSenableagentoffload' and type = 'P')
  358.       DROP PROCEDURE sp_MSenableagentoffload
  359.  
  360. IF EXISTS (select * from sysobjects where
  361.    name = 'sp_MSdisableagentoffload' and type = 'P')
  362.       DROP PROCEDURE sp_MSdisableagentoffload 
  363.  
  364. IF EXISTS (select * from sysobjects where
  365.    name = 'sp_MSadd_repl_error' and type = 'P')
  366.       DROP PROCEDURE sp_MSadd_repl_error
  367.  
  368. IF EXISTS (select * from sysobjects where
  369.    name = 'sp_MSadd_repl_alert' and type = 'P')
  370.       DROP PROCEDURE sp_MSadd_repl_alert
  371.  
  372. IF EXISTS (select * from sysobjects where
  373.    name = 'sp_MSadd_replmergealert' and type = 'P')
  374.       DROP PROCEDURE sp_MSadd_replmergealert
  375.  
  376. IF EXISTS (select * from sysobjects where
  377.    name = 'sp_MSget_new_errorid' and type = 'P')
  378.       DROP PROCEDURE sp_MSget_new_errorid
  379.  
  380. IF EXISTS (select * from sysobjects where
  381.    name = 'sp_MSget_repl_error' and type = 'P')
  382.       DROP PROCEDURE sp_MSget_repl_error
  383.  
  384. IF EXISTS (select * from sysobjects where
  385.    name = 'sp_MSadd_merge_history' and type = 'P')
  386.       DROP PROCEDURE sp_MSadd_merge_history
  387.  
  388. IF EXISTS (select * from sysobjects where
  389.    name = 'sp_MSdist_activate_auto_sub' and type = 'P')
  390.       DROP PROCEDURE sp_MSdist_activate_auto_sub
  391.  
  392. IF EXISTS (select * from sysobjects where
  393.    name = 'sp_MSlock_auto_sub' and type = 'P')
  394.       DROP PROCEDURE sp_MSlock_auto_sub
  395.  
  396. IF EXISTS (select * from sysobjects where
  397.    name = 'sp_MSget_new_xact_seqno' and type = 'P')
  398.       DROP PROCEDURE sp_MSget_new_xact_seqno
  399.  
  400. IF EXISTS (select * from sysobjects where
  401.    name = 'sp_MSvalidate_distpublisher' and type = 'P')
  402.       DROP PROCEDURE sp_MSvalidate_distpublisher
  403.  
  404. IF EXISTS (select * from sysobjects where
  405.    name = 'sp_MSadd_publication' and type = 'P')
  406.       DROP PROCEDURE sp_MSadd_publication
  407.  
  408. IF EXISTS (select * from sysobjects where
  409.    name = 'sp_MSchange_publication' and type = 'P')
  410.       DROP PROCEDURE sp_MSchange_publication
  411.  
  412. IF EXISTS (select * from sysobjects where
  413.    name = 'sp_MSadd_article' and type = 'P')
  414.       DROP PROCEDURE sp_MSadd_article
  415.  
  416. IF EXISTS (select * from sysobjects where
  417.    name = 'sp_MSchange_article' and type = 'P')
  418.       DROP PROCEDURE sp_MSchange_article
  419.  
  420. IF EXISTS (select * from sysobjects where
  421.    name = 'sp_MSdrop_publication' and type = 'P')
  422.       DROP PROCEDURE sp_MSdrop_publication
  423.  
  424. IF EXISTS (select * from sysobjects where
  425.    name = 'sp_MSdrop_article' and type = 'P')
  426.       DROP PROCEDURE sp_MSdrop_article
  427.  
  428. IF EXISTS (select * from sysobjects where
  429.    name = 'sp_MShelp_publication' and type = 'P')
  430.       DROP PROCEDURE sp_MShelp_publication
  431.  
  432. IF EXISTS (select * from sysobjects where
  433.    name = 'sp_MShelp_article' and type = 'P')
  434.       DROP PROCEDURE sp_MShelp_article
  435.  
  436. IF EXISTS (select * from sysobjects where
  437.    name = 'sp_MShelp_subscription' and type = 'P')
  438.       DROP PROCEDURE sp_MShelp_subscription
  439.  
  440. IF EXISTS (select * from sysobjects where
  441.    name = 'sp_MSadd_subscription_3rd' and type = 'P')
  442.       DROP PROCEDURE sp_MSadd_subscription_3rd
  443.  
  444. IF EXISTS (select * from sysobjects where
  445.    name = 'sp_MSdrop_subscription_3rd' and type = 'P')
  446.       DROP PROCEDURE sp_MSdrop_subscription_3rd
  447.  
  448. IF EXISTS (select * from sysobjects where
  449.    name = 'sp_MSactivate_subscriptions' and type = 'P')
  450.       DROP PROCEDURE sp_MSactivate_subscriptions
  451.  
  452. IF EXISTS (select * from sysobjects where
  453.    name = 'sp_MSrepl_raiserror' and type = 'P')
  454.       DROP PROCEDURE sp_MSrepl_raiserror
  455.  
  456. IF EXISTS (select * from sysobjects where
  457.    name = 'sp_MSadd_merge_subscription' and type = 'P')
  458.       DROP PROCEDURE sp_MSadd_merge_subscription
  459.  
  460. IF EXISTS (select * from sysobjects where
  461.    name = 'sp_MSdrop_merge_subscription' and type = 'P')
  462.       DROP PROCEDURE sp_MSdrop_merge_subscription
  463.  
  464. IF EXISTS (select * from sysobjects where
  465.    name = 'sp_MSenum_merge_subscriptions' and type = 'P')
  466.       DROP PROCEDURE sp_MSenum_merge_subscriptions
  467.  
  468. IF EXISTS (select * from sysobjects where
  469.    name = 'sp_MSadd_snapshot_agent' and type = 'P')
  470.       DROP PROCEDURE sp_MSadd_snapshot_agent
  471.  
  472. IF EXISTS (select * from sysobjects where
  473.    name = 'sp_MSdrop_snapshot_agent' and type = 'P')
  474.       DROP PROCEDURE sp_MSdrop_snapshot_agent
  475.  
  476. IF EXISTS (select * from sysobjects where
  477.    name = 'sp_MSadd_logreader_agent' and type = 'P')
  478.       DROP PROCEDURE sp_MSadd_logreader_agent
  479.  
  480. IF EXISTS (select * from sysobjects where
  481.    name = 'sp_MSdrop_logreader_agent' and type = 'P')
  482.       DROP PROCEDURE sp_MSdrop_logreader_agent
  483.  
  484. IF EXISTS (select * from sysobjects where
  485.    name = 'sp_MSadd_distribution_agent' and type = 'P')
  486.       DROP PROCEDURE sp_MSadd_distribution_agent
  487.  
  488. IF EXISTS (select * from sysobjects where
  489.    name = 'sp_MSdrop_distribution_agent' and type = 'P')
  490.       DROP PROCEDURE sp_MSdrop_distribution_agent
  491.  
  492. IF EXISTS (select * from sysobjects where
  493.    name = 'sp_MSdrop_distribution_agentid' and type = 'P')
  494.       DROP PROCEDURE sp_MSdrop_distribution_agentid
  495.  
  496. IF EXISTS (select * from sysobjects where
  497.    name = 'sp_MSdrop_merge_agentid' and type = 'P')
  498.       DROP PROCEDURE sp_MSdrop_merge_agentid
  499.  
  500. IF EXISTS (select * from sysobjects where
  501.    name = 'sp_MSadd_merge_agent' and type = 'P')
  502.       DROP PROCEDURE sp_MSadd_merge_agent
  503.  
  504. IF EXISTS (select * from sysobjects where
  505.    name = 'sp_MSdrop_merge_agent' and type = 'P')
  506.       DROP PROCEDURE sp_MSdrop_merge_agent
  507.  
  508. IF EXISTS (select * from sysobjects where
  509.    name = 'sp_MSadd_qreader_agent' and type = 'P')
  510.       DROP PROCEDURE sp_MSadd_qreader_agent
  511.  
  512. IF EXISTS (select * from sysobjects where
  513.    name = 'sp_MSadd_qreader_history' and type = 'P')
  514.       DROP PROCEDURE sp_MSadd_qreader_history
  515.  
  516. IF EXISTS (select * from sysobjects where
  517.    name = 'sp_MSdrop_qreader_agent' and type = 'P')
  518.       DROP PROCEDURE sp_MSdrop_qreader_agent
  519.  
  520. IF EXISTS (select * from sysobjects where
  521.    name = 'sp_MSdrop_qreader_history' and type = 'P')
  522.       DROP PROCEDURE sp_MSdrop_qreader_history
  523.  
  524. IF EXISTS (select name from sysobjects where 
  525.    name = 'sp_update_agent_profile' and type = 'P')
  526.     DROP PROCEDURE sp_update_agent_profile
  527.  
  528. IF EXISTS (select name from sysobjects where 
  529.    name = 'sp_MSprofile_in_use' and type = 'P')
  530.     DROP PROCEDURE sp_MSprofile_in_use
  531.  
  532. IF EXISTS (select * from sysobjects where
  533.    name = 'sp_MSreset_subscription' and type = 'P')
  534.       DROP PROCEDURE sp_MSreset_subscription
  535.  
  536. IF EXISTS (select * from sysobjects where
  537.    name = 'sp_MSget_subscription_guid' and type = 'P')
  538.       DROP PROCEDURE sp_MSget_subscription_guid
  539.  
  540. IF EXISTS (select * from sysobjects where
  541.    name = 'sp_MSreset_subscription_seqno' and type = 'P')
  542.       DROP PROCEDURE sp_MSreset_subscription_seqno
  543.  
  544. IF EXISTS (select * from sysobjects where
  545.    name = 'sp_MShelp_profile' and type = 'P')
  546.       DROP PROCEDURE sp_MShelp_profile
  547.  
  548. IF EXISTS (select * from sysobjects where
  549.    name = 'sp_MShelp_snapshot_agentid' and type = 'P')
  550.       DROP PROCEDURE sp_MShelp_snapshot_agentid
  551.  
  552. IF EXISTS (select * from sysobjects where
  553.    name = 'sp_MShelp_logreader_agentid' and type = 'P')
  554.       DROP PROCEDURE sp_MShelp_logreader_agentid
  555.  
  556. IF EXISTS (select * from sysobjects where
  557.    name = 'sp_MShelp_merge_agentid' and type = 'P')
  558.       DROP PROCEDURE sp_MShelp_merge_agentid
  559.  
  560. IF EXISTS (select * from sysobjects where
  561.    name = 'sp_MSenum_replication_status' and type = 'P')
  562.       DROP PROCEDURE sp_MSenum_replication_status
  563.  
  564. IF EXISTS (select * from sysobjects where
  565.    name = 'sp_MSagent_stethoscope' and type = 'P')
  566.       DROP PROCEDURE sp_MSagent_stethoscope
  567.  
  568. IF EXISTS (select * from sysobjects where
  569.    name = 'sp_MSlock_distribution_agent' and type = 'P')
  570.       DROP PROCEDURE sp_MSlock_distribution_agent
  571.  
  572. IF EXISTS (select * from sysobjects where
  573.    name = 'sp_MSdetect_nonlogged_shutdown' and type = 'P')
  574.       DROP PROCEDURE sp_MSdetect_nonlogged_shutdown
  575.  
  576. IF EXISTS (select * from sysobjects where
  577.    name = 'sp_MSdistpublisher_cleanup' and type = 'P')
  578.       DROP PROCEDURE sp_MSdistpublisher_cleanup
  579.  
  580. IF EXISTS (select * from sysobjects where
  581.    name = 'sp_MSpublication_access' and type = 'P')
  582.       DROP PROCEDURE sp_MSpublication_access
  583.  
  584. IF EXISTS (select * from sysobjects where
  585.    name = 'sp_MScheck_pull_access' and type = 'P')
  586.       DROP PROCEDURE sp_MScheck_pull_access
  587.  
  588. GO
  589. IF EXISTS (select * from sysobjects where
  590.    name = 'sp_MSdrop_6x_publication' and type = 'P')
  591.       DROP PROCEDURE sp_MSdrop_6x_publication
  592.  
  593. IF EXISTS (select * from sysobjects where
  594.    name = 'sp_MShelp_distribution_agentid' and type = 'P')
  595.       DROP PROCEDURE sp_MShelp_distribution_agentid
  596. GO
  597.  
  598. IF EXISTS (select * from sysobjects where
  599.    name = 'sp_MScheck_tran_retention' and type = 'P')
  600.       DROP PROCEDURE sp_MScheck_tran_retention
  601. GO
  602.  
  603. IF EXISTS (select * from sysobjects where
  604.    name = 'sp_MSreinit_subscription' and type = 'P')
  605.       DROP PROCEDURE sp_MSreinit_subscription
  606. go
  607.  
  608. IF EXISTS (select * from sysobjects where
  609.    name = 'sp_MSmarkreinit' and type = 'P')
  610.       DROP PROCEDURE sp_MSmarkreinit
  611. go
  612.  
  613. IF EXISTS (select * from sysobjects where
  614.    name = 'sp_browsereplcmds' and type = 'P')
  615.       DROP PROCEDURE sp_browsereplcmds
  616. go
  617.  
  618. IF EXISTS (select * from sysobjects where
  619.    name = 'sp_dumpparamcmd' and type = 'P')
  620.       DROP PROCEDURE sp_dumpparamcmd
  621. go
  622.  
  623. IF EXISTS (select * from sysobjects where
  624.    name = 'sp_MSbrowsesnapshotfolder' and type = 'P')
  625.       DROP PROCEDURE sp_MSbrowsesnapshotfolder
  626. go
  627.  
  628. IF EXISTS (select * from sysobjects where
  629.    name = 'sp_MSquery_syncstates' and type = 'P')
  630.       DROP PROCEDURE sp_MSquery_syncstates
  631. go
  632.  
  633. IF EXISTS (select * from sysobjects where
  634.    name = 'sp_MSset_syncstate' and type = 'P')
  635.       DROP PROCEDURE sp_MSset_syncstate
  636.  
  637. IF EXISTS (select * from sysobjects where
  638.    name = 'sp_MSdist_adjust_identity' and type = 'P')
  639.       DROP PROCEDURE sp_MSdist_adjust_identity
  640.  
  641. IF EXISTS (select * from sysobjects where
  642.    name = 'sp_MSchange_subscription_dts_info' and type = 'P')
  643.       DROP PROCEDURE sp_MSchange_subscription_dts_info
  644.  
  645. IF EXISTS (select * from sysobjects where
  646.    name = 'sp_MSget_subscription_dts_info' and type = 'P')
  647.       DROP PROCEDURE sp_MSget_subscription_dts_info
  648. go
  649.  
  650. IF EXISTS (select * from sysobjects where
  651.    name = 'sp_MSenumdistributionagentproperties' and type = 'P')
  652.       DROP PROCEDURE sp_MSenumdistributionagentproperties
  653.  
  654. IF EXISTS (select * from sysobjects where
  655.    name = 'sp_MSenum_merge_agent_properties' and type = 'P')
  656.       DROP PROCEDURE sp_MSenum_merge_agent_properties
  657.  
  658. IF EXISTS (select * from sysobjects where
  659.    name = 'sp_MSinsert_identity' and type = 'P')
  660.       DROP PROCEDURE sp_MSinsert_identity
  661.  
  662. IF EXISTS (select * from sysobjects where
  663.    name = 'sp_MSadjust_pub_identity' and type = 'P')
  664.       DROP PROCEDURE sp_MSadjust_pub_identity    
  665.  
  666. IF EXISTS (select * from sysobjects where
  667.    name = 'sp_MScheck_pub_identity' and type = 'P')
  668.       DROP PROCEDURE sp_MScheck_pub_identity    
  669.  
  670. IF EXISTS (select * from sysobjects where
  671.    name = 'sp_dropanonymoussubscription' and type = 'P')
  672.       DROP PROCEDURE sp_dropanonymoussubscription
  673.  
  674. IF EXISTS (select * from sysobjects where
  675.    name = 'sp_MSdrop_anonymous_entry' and type = 'P')
  676.       DROP PROCEDURE sp_MSdrop_anonymous_entry
  677.  
  678. IF EXISTS (select * from sysobjects where
  679.    name = 'sp_MSadddynamicsnapshotjobatdistributor' and type = 'P')
  680.       DROP PROCEDURE sp_MSadddynamicsnapshotjobatdistributor
  681.  
  682. IF EXISTS (select * from sysobjects where
  683.    name = 'sp_MSdeleterepljob' and type = 'P')
  684.       DROP PROCEDURE sp_MSdeleterepljob
  685.  
  686. IF EXISTS (select * from sysobjects where
  687.    name = 'sp_MSdeletefoldercontents' and type = 'P')
  688.       DROP PROCEDURE sp_MSdeletefoldercontents
  689.  
  690. IF EXISTS (select * from sysobjects where
  691.    name = 'sp_MSinvalidate_snapshot' and type = 'P')
  692.       DROP PROCEDURE sp_MSinvalidate_snapshot
  693.  
  694. IF EXISTS (select * from sysobjects where
  695.    name = 'sp_MSrepl_init_backup_lsns' and type = 'P')
  696.       DROP PROCEDURE sp_MSrepl_init_backup_lsns
  697.  
  698. IF EXISTS (select * from sysobjects where
  699.    name = 'sp_MSispublicationqueued' and type = 'P')
  700.       DROP PROCEDURE sp_MSispublicationqueued
  701.  
  702. if exists (select * from sysobjects
  703.      where type = 'FN'
  704.             and name = 'fn_MSmask_agent_type')
  705.      drop function dbo.fn_MSmask_agent_type
  706.  
  707. if exists (select * from sysobjects 
  708.         where type = 'P' and
  709.         name = 'sp_MSwritemergeperfcounter')
  710.         drop procedure sp_MSwritemergeperfcounter
  711.  
  712. if exists (select * from sysobjects 
  713.         where type = 'P' and
  714.         name = 'sp_MSlog_agent_cancel')
  715.         drop procedure sp_MSlog_agent_cancel
  716.  
  717. go
  718.  
  719.  
  720. declare @dbname sysname
  721. select  @dbname = db_name()
  722. execute('dump transaction ' +@dbname+ ' with no_log')
  723. go
  724.  
  725. -- This function is used internally by other stored procedures to mark the agent type
  726. -- for anonymous agent before passing it to sp_MSupdate_replication_status, so anonymous
  727. -- agent status can be filtered out from repl monitor. Only distribution agents and merge
  728. -- agents should use this function. 
  729. raiserror(15339,-1,-1,'fn_MSmask_agent_type')
  730. go
  731. create function dbo.fn_MSmask_agent_type(
  732.     @agent_id int,
  733.     @agent_type int
  734.     ) returns int
  735. as
  736. begin
  737.     declare @anonymous_mask int
  738.     select @anonymous_mask = 0x80000000
  739.     if @agent_type = 3 -- If dist agent
  740.     begin
  741.         if exists (select * from MSdistribution_agents where id = @agent_id and 
  742.             subscriber_name is not null)
  743.             select @agent_type = 3 | @anonymous_mask
  744.         else
  745.             select @agent_type = 3 
  746.     end
  747.     else if @agent_type = 4 -- if merge agent
  748.     begin
  749.         if exists (select * from MSmerge_agents where id = @agent_id and 
  750.             subscriber_name is not null)
  751.             select @agent_type = 4 | @anonymous_mask
  752.         else
  753.             select @agent_type = 4 
  754.     end
  755.     -- if other agents, @agent_type will not change.
  756.     return @agent_type
  757. end
  758. go
  759.  
  760. raiserror(15339,-1,-1,'sp_MScheck_pull_access')
  761. GO
  762.  
  763. CREATE PROCEDURE sp_MScheck_pull_access (
  764.     @agent_id int = 0,
  765.     @agent_type int = 0, -- 0 is tran; 1 is merge
  766.     @publication_id int = 0
  767.         ) AS
  768.  
  769.     declare @retcode int
  770.  
  771.     -- sysadmin or db_owner have access
  772.     if is_srvrolemember('sysadmin') = 1 or 
  773.         is_member('db_owner') = 1
  774.         return 0
  775.  
  776.     -- Need login_time to uniquely identify a connection.
  777.     declare @login_time datetime
  778.     select @login_time = login_time from master..sysprocesses where spid = @@spid
  779.  
  780.     -- For merge change to use publication_id
  781.     if @agent_id <> 0 and @agent_type = 1
  782.     begin
  783.         select @publication_id = p.publication_id from
  784.                 MSmerge_agents a, MSpublications p where
  785.                 a.id = @agent_id and
  786.                 a.publisher_id = p.publisher_id and
  787.                 a.publisher_db = p.publisher_db and
  788.                 a.publication = p.publication
  789.         select @agent_id = 0
  790.     end
  791.  
  792.     -- In cache, return success
  793.     if exists (select * from tempdb.dbo.MSdistributor_access where 
  794.         spid = @@spid and
  795.         login_time = @login_time and
  796.         db_id = db_id() and
  797.         (publication_id = @publication_id and
  798.         agent_id = @agent_id and
  799.         agent_type = @agent_type) or
  800.         -- All 0s is used by sp_MSadd_repl_error, which just require the 
  801.         -- login to be in cache regardless of the publication id and agent_id.
  802.         -- This means that once a agent get into the distribution db, it
  803.         -- can add any error.
  804.         (@publication_id = 0 and @agent_id = 0 and @agent_type = 0))
  805.         return (0)
  806.  
  807.     -- Cover sp_MSadd_repl_error case
  808.     if @publication_id = 0 and @agent_id = 0 and @agent_type = 0
  809.     begin
  810.         RAISERROR (14126, 11, -1)
  811.         return (1)
  812.     end
  813.  
  814.     declare @isntname bit
  815.     declare @offensive_pub_id int
  816.  
  817.     -- Check to see if the login is NT login
  818.     select @isntname = isntname from master..syslogins where
  819.         sid = suser_sid()
  820.     -- If the login does not exists, check to see if the login is a NT login that
  821.     -- has access to the server.
  822.     if @isntname is null
  823.     begin
  824.         -- If it is an NT login
  825.         if suser_sid() is not null
  826.             select @isntname = 1
  827.         -- If it is not an NT login
  828.         else
  829.             select @isntname = 0
  830.     end
  831.  
  832.     -- Check security based on agent_id
  833.     -- We know it is distribution agent. See above.
  834.     if @agent_id <> 0 
  835.     begin
  836.         select top 1 @offensive_pub_id = s.publication_id from MSsubscriptions s where 
  837.             s.agent_id = @agent_id and
  838.             not exists (select * from MSpublication_access l where
  839.                 l.publication_id = s.publication_id and
  840.             -- Current login has no access
  841.             (suser_sid(l.login) = suser_sid() or (@isntname = 1 and exists 
  842.                 (select * from master..syslogins where 
  843.                     sid = suser_sid(l.login) and isntgroup = 1 and is_member(l.login) = 1))))
  844.         
  845.         if @offensive_pub_id is not null
  846.             goto NO_ACCESS
  847.     end
  848.     -- Check security based on publication_id
  849.     else
  850.     begin
  851.         declare @publisher_id smallint
  852.     
  853.         if not exists (select * from MSpublication_access l where
  854.             l.publication_id = @publication_id and
  855.             (suser_sid(l.login) = suser_sid() or (@isntname = 1 and exists 
  856.                 (select * from master..syslogins where 
  857.                     sid = suser_sid(l.login) and isntgroup = 1 and is_member(l.login) = 1))))
  858.         begin
  859.             select @offensive_pub_id = @publication_id
  860.             goto NO_ACCESS
  861.         end
  862.     end
  863.  
  864.     -- If we are here, we know that the connection has access and is not in the cache
  865.     -- add it in to the cache.
  866.         
  867.     -- Clear the cache to keep it small.
  868.     exec @retcode = dbo.sp_MSflush_access_cache
  869.     if @retcode <> 0 or @@error <> 0
  870.         return (1)
  871.         
  872.  
  873.     insert tempdb.dbo.MSdistributor_access
  874.         (spid, db_id, agent_id, agent_type, publication_id, login_time) values
  875.         (@@spid, db_id(), @agent_id, @agent_type, @publication_id, @login_time)
  876.  
  877.     if @@error <> 0
  878.         return (1)
  879.  
  880.     return (0)
  881.  
  882. NO_ACCESS:
  883.  
  884.     -- We don't have access if we reach here, return error
  885.     declare @login sysname
  886.     select @login = suser_sname(suser_sid())
  887.     declare @publication sysname
  888.     select @publication = publication from MSpublications where publication_id = @offensive_pub_id
  889.     raiserror(21049, 16, -1, @login, @publication);
  890.     return(1)
  891.  
  892. GO
  893.  
  894.  
  895. raiserror(15339,-1,-1,'sp_MSquery_syncstates')
  896. GO
  897. create procedure sp_MSquery_syncstates
  898. @publisher_id smallint, 
  899. @publisher_db sysname
  900. as
  901.     declare @retcode int
  902.  
  903.     -- note:  obtain publisher_id via call to sp_MSvalidate_distpublisher
  904.  
  905.     select publication_id from MSsync_states 
  906.     where publisher_id = @publisher_id 
  907.     and publisher_db = @publisher_db
  908.  
  909. go
  910.  
  911.  
  912. raiserror(15339,-1,-1,'sp_MSset_syncstate')
  913. GO
  914. create procedure sp_MSset_syncstate
  915. @publisher_id smallint, 
  916. @publisher_db sysname, 
  917. @article_id int, 
  918. @sync_state int,  
  919. @xact_seqno varbinary(16)
  920. as
  921.  
  922. declare @publication_id int
  923.  
  924. select top 1 @publication_id = s.publication_id 
  925. from MSsubscriptions s
  926. where 
  927. s.publisher_id = @publisher_id and
  928. s.publisher_db = @publisher_db and
  929. s.article_id = @article_id     and
  930. s.subscription_seqno < @xact_seqno
  931.  
  932.  
  933. if @publication_id is not null
  934. begin
  935.     if( @sync_state = 1 )
  936.     begin
  937.         if not exists( select * from MSsync_states 
  938.                        where publisher_id = @publisher_id and
  939.                        publisher_db = @publisher_db and
  940.                        publication_id = @publication_id )
  941.         begin
  942.             insert into MSsync_states( publisher_id, publisher_db, publication_id )
  943.             values( @publisher_id, @publisher_db, @publication_id )
  944.         end
  945.     end
  946.     else if @sync_state = 0 
  947.     begin
  948.         
  949.         delete MSsync_states 
  950.         where 
  951.         publisher_id = @publisher_id and
  952.         publisher_db = @publisher_db and
  953.         publication_id = @publication_id 
  954.  
  955.         -- activate the subscription(s) so the distribution agent can start processing
  956.         declare @automatic int
  957.         declare @active int    
  958.         declare @initiated int
  959.  
  960.         select @automatic = 1
  961.         select @active = 2
  962.         select @initiated = 3
  963.  
  964.         -- set status to active, ss_cplt_seqno = commit LSN of xact containing
  965.         -- syncdone token.  
  966.         --
  967.         -- VERY IMPORTANT:  We can only do this because we know that the publisher
  968.         -- tables are locked in the same transaction that writes the SYNCDONE token.
  969.         -- If the tables were NOT locked, we could get into a situation where data
  970.         -- in the table was changed and committed between the time the SYNCDONE token was
  971.         -- written and the time the SYNCDONE xact was committed.  This would cause the
  972.         -- logreader to replicate the xact with no compensation records, but the advance
  973.         -- of the ss_cplt_seqno would cause the dist to skip that command since only commands
  974.         -- with the snapshot bit set will be processed if they are <= ss_cplt_seqno.
  975.         --
  976.         update MSsubscriptions 
  977.         set status = @active,
  978.             subscription_time = getdate(),
  979.             ss_cplt_seqno = @xact_seqno        
  980.         where
  981.             publisher_id = @publisher_id and
  982.             publisher_db = @publisher_db and
  983.             publication_id = @publication_id and
  984.             sync_type = @automatic and
  985.             status in( @initiated )
  986.     end
  987. end
  988. go
  989.  
  990. raiserror(15339,-1,-1,'sp_MSadd_repl_command')
  991. go
  992. CREATE PROCEDURE sp_MSadd_repl_command
  993. @publisher_id smallint = NULL,
  994. @publisher_db sysname,
  995. @xact_id varbinary(16) = 0x0,
  996. @xact_seqno varbinary(16) = 0x0,
  997. @originator sysname = NULL,
  998. @originator_db sysname = NULL,
  999. @article_id int = NULL,
  1000. @command_id int = 1,
  1001. @type int = NULL,
  1002. @partial_command bit = NULL,
  1003. @command varbinary(1024) = NULL,
  1004. @publisher sysname = NULL
  1005.  
  1006.  
  1007. AS
  1008.  
  1009.    SET NOCOUNT ON
  1010.  
  1011.    DECLARE @date datetime
  1012.    DECLARE @publisher_database_id int
  1013.    declare @originator_id int
  1014.  
  1015.    SELECT @date = GETDATE()
  1016.  
  1017.    if @publisher_id is NULL
  1018.         select @publisher_id = srvid from master..sysservers where
  1019.             UPPER(srvname) = UPPER(@publisher)
  1020.  
  1021.     -- Get publisher database id.
  1022.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  1023.         publisher_db = @publisher_db
  1024.     
  1025.    /* 
  1026.    ** To minimize contention, snapshot does not include this SP call
  1027.    ** inside a transaction. We have to insert to MSrepl_transactions table
  1028.    ** first to ensure clean up stored precedures to work, which only use 
  1029.    ** MSrepl_transactions table but NOT MSrepl_commands table to find transactions
  1030.    ** to be deleted.
  1031.    */
  1032.  
  1033.    IF @command_id = 1
  1034.    BEGIN
  1035.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1036.          @xact_id,  @xact_seqno, @date)
  1037.       IF @@ERROR <> 0
  1038.          RETURN 1
  1039.    END
  1040.  
  1041.    IF @command IS NOT NULL
  1042.    begin
  1043.       if @originator <> N'' and @originator_db <> N'' and @originator is not null and @originator_db is not null 
  1044.       begin
  1045.         set @originator_id = null select @originator_id = id from MSrepl_originators where
  1046.             publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@originator) and
  1047.             dbname = @originator_db
  1048.         if @originator_id is null
  1049.         begin
  1050.             insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1051.                 (@publisher_database_id, @originator, @originator_db)
  1052.             select @originator_id = @@identity
  1053.         end
  1054.       end
  1055.       else
  1056.         select @originator_id = 0
  1057.       
  1058.  
  1059.       if( @type in( 37,38 ) )
  1060.       begin
  1061.             declare @syncstat int
  1062.           select @syncstat = 38 - @type
  1063.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @article_id, @syncstat, @xact_seqno 
  1064.       end
  1065.  
  1066.       INSERT INTO MSrepl_commands VALUES (@publisher_database_id, @xact_seqno,
  1067.         @type, @article_id, @originator_id, @command_id, @partial_command, @command)
  1068.     end
  1069.  
  1070.     IF @@ERROR <> 0
  1071.       RETURN (1)
  1072.  
  1073. GO  
  1074.  
  1075.  
  1076. raiserror(15339,-1,-1,'sp_MSadd_repl_commands27')
  1077. GO
  1078. CREATE PROCEDURE sp_MSadd_repl_commands27
  1079. @publisher_id smallint,
  1080. @publisher_db sysname,
  1081. @xact_id varbinary(16) = 0x0,
  1082. @xact_seqno varbinary(16) = 0x0,
  1083. @originator sysname,
  1084. @originator_db sysname,
  1085. @article_id int,
  1086. @command_id int,
  1087. @type int = 0,
  1088. @partial_command bit,
  1089. @command varbinary(1024),
  1090.  
  1091. @1xact_id varbinary(16) = 0x0,
  1092.  
  1093. @1xact_seqno varbinary(16) = 0x0,
  1094. @1originator sysname = NULL,
  1095. @1originator_db sysname = NULL,
  1096. @1article_id int = 0,
  1097. @1command_id int = 0,
  1098. @1type int = 0,
  1099. @1partial_command bit = 0,
  1100. @1command varbinary(1024) = NULL,
  1101.  
  1102. @2xact_id varbinary(16) = 0x0,
  1103.  
  1104. @2xact_seqno varbinary(16) = 0x0,
  1105. @2originator sysname = NULL,
  1106. @2originator_db sysname = NULL,
  1107. @2article_id int = 0,
  1108. @2command_id int = 0,
  1109. @2type int = 0,
  1110. @2partial_command bit = 0,
  1111. @2command varbinary(1024) = NULL,
  1112.  
  1113. @3xact_id varbinary(16) = 0x0,
  1114.  
  1115. @3xact_seqno varbinary(16) = 0x0,
  1116. @3originator sysname = NULL,
  1117. @3originator_db sysname = NULL,
  1118. @3article_id int = 0,
  1119. @3command_id int = 0,
  1120. @3type int = 0,
  1121. @3partial_command bit = 0,
  1122. @3command varbinary(1024) = NULL,
  1123.  
  1124. @4xact_id varbinary(16) = 0x0,
  1125.  
  1126. @4xact_seqno varbinary(16) = 0x0,
  1127. @4originator sysname = NULL,
  1128. @4originator_db sysname = NULL,
  1129. @4article_id int = 0,
  1130. @4command_id int = 0,
  1131. @4type int = 0,
  1132. @4partial_command bit = 0,
  1133. @4command varbinary(1024) = NULL,
  1134.  
  1135. @5xact_id varbinary(16) = 0x0,
  1136.  
  1137. @5xact_seqno varbinary(16) = 0x0,
  1138. @5originator sysname = NULL,
  1139. @5originator_db sysname = NULL,
  1140. @5article_id int = 0,
  1141. @5command_id int = 0,
  1142. @5type int = 0,
  1143. @5partial_command bit = 0,
  1144. @5command varbinary(1024) = NULL,
  1145.  
  1146. @6xact_id varbinary(16) = 0x0,
  1147.  
  1148. @6xact_seqno varbinary(16) = 0x0,
  1149. @6originator sysname = NULL,
  1150. @6originator_db sysname = NULL,
  1151. @6article_id int = 0,
  1152. @6command_id int = 0,
  1153. @6type int = 0,
  1154. @6partial_command bit = 0,
  1155. @6command varbinary(1024) = NULL,
  1156.  
  1157. @7xact_id varbinary(16) = 0x0,
  1158.  
  1159. @7xact_seqno varbinary(16) = 0x0,
  1160. @7originator sysname = NULL,
  1161. @7originator_db sysname = NULL,
  1162. @7article_id int = 0,
  1163. @7command_id int = 0,
  1164. @7type int = 0,
  1165. @7partial_command bit = 0,
  1166. @7command varbinary(1024) = NULL,
  1167.  
  1168. @8xact_id varbinary(16) = 0x0,
  1169.  
  1170. @8xact_seqno varbinary(16) = 0x0,
  1171. @8originator sysname = NULL,
  1172. @8originator_db sysname = NULL,
  1173. @8article_id int = 0,
  1174. @8command_id int = 0,
  1175. @8type int = 0,
  1176. @8partial_command bit = 0,
  1177. @8command varbinary(1024) = NULL,
  1178.  
  1179. @9xact_id varbinary(16) = 0x0,
  1180.  
  1181. @9xact_seqno varbinary(16) = 0x0,
  1182. @9originator sysname = NULL,
  1183. @9originator_db sysname = NULL,
  1184. @9article_id int = 0,
  1185. @9command_id int = 0,
  1186. @9type int = 0,
  1187. @9partial_command bit = 0,
  1188. @9command varbinary(1024) = NULL,
  1189.  
  1190. @10xact_id varbinary(16) = 0x0,
  1191.  
  1192. @10xact_seqno varbinary(16) = 0x0,
  1193. @10originator sysname = NULL,
  1194. @10originator_db sysname = NULL,
  1195. @10article_id int = 0,
  1196. @10command_id int = 0,
  1197. @10type int = 0,
  1198. @10partial_command bit = 0,
  1199. @10command varbinary(1024) = NULL,
  1200.  
  1201. @11xact_id varbinary(16) = 0x0,
  1202.  
  1203. @11xact_seqno varbinary(16) = 0x0,
  1204. @11originator sysname = NULL,
  1205. @11originator_db sysname = NULL,
  1206. @11article_id int = 0,
  1207. @11command_id int = 0,
  1208. @11type int = 0,
  1209. @11partial_command bit = 0,
  1210. @11command varbinary(1024) = NULL,
  1211.  
  1212. @12xact_id varbinary(16) = 0x0,
  1213.  
  1214. @12xact_seqno varbinary(16) = 0x0,
  1215. @12originator sysname = NULL,
  1216. @12originator_db sysname = NULL,
  1217. @12article_id int = 0,
  1218. @12command_id int = 0,
  1219. @12type int = 0,
  1220. @12partial_command bit = 0,
  1221. @12command varbinary(1024) = NULL,
  1222.  
  1223. @13xact_id varbinary(16) = 0x0,
  1224.  
  1225. @13xact_seqno varbinary(16) = 0x0,
  1226. @13originator sysname = NULL,
  1227. @13originator_db sysname = NULL,
  1228. @13article_id int = 0,
  1229. @13command_id int = 0,
  1230. @13type int = 0,
  1231. @13partial_command bit = 0,
  1232. @13command varbinary(1024) = NULL,
  1233.  
  1234. @14xact_id varbinary(16) = 0x0,
  1235.  
  1236. @14xact_seqno varbinary(16) = 0x0,
  1237. @14originator sysname = NULL,
  1238. @14originator_db sysname = NULL,
  1239. @14article_id int = 0,
  1240. @14command_id int = 0,
  1241. @14type int = 0,
  1242. @14partial_command bit = 0,
  1243. @14command varbinary(1024) = NULL,
  1244.  
  1245. @15xact_id varbinary(16) = 0x0,
  1246.  
  1247. @15xact_seqno varbinary(16) = 0x0,
  1248. @15originator sysname = NULL,
  1249. @15originator_db sysname = NULL,
  1250. @15article_id int = 0,
  1251. @15command_id int = 0,
  1252. @15type int = 0,
  1253. @15partial_command bit = 0,
  1254. @15command varbinary(1024) = NULL,
  1255.  
  1256. @16xact_id varbinary(16) = 0x0,
  1257.  
  1258. @16xact_seqno varbinary(16) = 0x0,
  1259. @16originator sysname = NULL,
  1260. @16originator_db sysname = NULL,
  1261. @16article_id int = 0,
  1262. @16command_id int = 0,
  1263. @16type int = 0,
  1264. @16partial_command bit = 0,
  1265. @16command varbinary(1024) = NULL,
  1266.  
  1267. @17xact_id varbinary(16) = 0x0,
  1268.  
  1269. @17xact_seqno varbinary(16) = 0x0,
  1270. @17originator sysname = NULL,
  1271. @17originator_db sysname = NULL,
  1272. @17article_id int = 0,
  1273. @17command_id int = 0,
  1274. @17type int = 0,
  1275. @17partial_command bit = 0,
  1276. @17command varbinary(1024) = NULL,
  1277.  
  1278. @18xact_id varbinary(16) = 0x0,
  1279.  
  1280. @18xact_seqno varbinary(16) = 0x0,
  1281. @18originator sysname = NULL,
  1282. @18originator_db sysname = NULL,
  1283. @18article_id int = 0,
  1284. @18command_id int = 0,
  1285. @18type int = 0,
  1286. @18partial_command bit = 0,
  1287. @18command varbinary(1024) = NULL,
  1288.  
  1289. @19xact_id varbinary(16) = 0x0,
  1290.  
  1291. @19xact_seqno varbinary(16) = 0x0,
  1292. @19originator sysname = NULL,
  1293. @19originator_db sysname = NULL,
  1294. @19article_id int = 0,
  1295. @19command_id int = 0,
  1296. @19type int = 0,
  1297. @19partial_command bit = 0,
  1298. @19command varbinary(1024) = NULL,
  1299.  
  1300. @20xact_id varbinary(16) = 0x0,
  1301.  
  1302. @20xact_seqno varbinary(16) = 0x0,
  1303. @20originator sysname = NULL,
  1304. @20originator_db sysname = NULL,
  1305. @20article_id int = 0,
  1306. @20command_id int = 0,
  1307. @20type int = 0,
  1308. @20partial_command bit = 0,
  1309. @20command varbinary(1024) = NULL,
  1310.  
  1311. @21xact_id varbinary(16) = 0x0,
  1312.  
  1313. @21xact_seqno varbinary(16) = 0x0,
  1314. @21originator sysname = NULL,
  1315. @21originator_db sysname = NULL,
  1316. @21article_id int = 0,
  1317. @21command_id int = 0,
  1318. @21type int = 0,
  1319. @21partial_command bit = 0,
  1320. @21command varbinary(1024) = NULL,
  1321.  
  1322. @22xact_id varbinary(16) = 0x0,
  1323.  
  1324. @22xact_seqno varbinary(16) = 0x0,
  1325. @22originator sysname = NULL,
  1326. @22originator_db sysname = NULL,
  1327. @22article_id int = 0,
  1328. @22command_id int = 0,
  1329. @22type int = 0,
  1330. @22partial_command bit = 0,
  1331. @22command varbinary(1024) = NULL,
  1332.  
  1333. @23xact_id varbinary(16) = 0x0,
  1334.  
  1335. @23xact_seqno varbinary(16) = 0x0,
  1336. @23originator sysname = NULL,
  1337. @23originator_db sysname = NULL,
  1338. @23article_id int = 0,
  1339. @23command_id int = 0,
  1340. @23type int = 0,
  1341. @23partial_command bit = 0,
  1342. @23command varbinary(1024) = NULL,
  1343.  
  1344. @24xact_id varbinary(16) = 0x0,
  1345.  
  1346. @24xact_seqno varbinary(16) = 0x0,
  1347. @24originator sysname = NULL,
  1348. @24originator_db sysname = NULL,
  1349. @24article_id int = 0,
  1350. @24command_id int = 0,
  1351. @24type int = 0,
  1352. @24partial_command bit = 0,
  1353. @24command varbinary(1024) = NULL,
  1354.  
  1355. @25xact_id varbinary(16) = 0x0,
  1356.  
  1357. @25xact_seqno varbinary(16) = 0x0,
  1358. @25originator sysname = NULL,
  1359. @25originator_db sysname = NULL,
  1360. @25article_id int = 0,
  1361. @25command_id int = 0,
  1362. @25type int = 0,
  1363. @25partial_command bit = 0,
  1364. @25command varbinary(1024) = NULL,
  1365.  
  1366. @26xact_id varbinary(16) = 0x0,
  1367.  
  1368. @26xact_seqno varbinary(16) = 0x0,
  1369. @26originator sysname = NULL,
  1370. @26originator_db sysname = NULL,
  1371. @26article_id int = 0,
  1372. @26command_id int = 0,
  1373. @26type int = 0,
  1374. @26partial_command bit = 0,
  1375. @26command varbinary(1024) = NULL
  1376.  
  1377. AS
  1378.  
  1379.     SET NOCOUNT ON
  1380.  
  1381.     DECLARE @publisher_database_id int
  1382.     DECLARE @date datetime
  1383.     declare @originator_id int
  1384.     declare @syncstat int
  1385.  
  1386.     SELECT @date = GETDATE()
  1387.  
  1388.     -- Get publisher database id.
  1389.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  1390.         publisher_db = @publisher_db
  1391.     
  1392.     -- First insert into MS_repl_transactions
  1393.     IF @command_id = 1
  1394.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1395.          @xact_id,  @xact_seqno, @date)
  1396.  
  1397.     IF @1xact_id = 0x0
  1398.       goto INSERT_CMDS
  1399.     IF @1command_id = 1
  1400.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1401.          @1xact_id,  @1xact_seqno, @date)
  1402.  
  1403.     IF @2xact_id = 0x0
  1404.       goto INSERT_CMDS
  1405.     IF @2command_id = 1
  1406.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1407.          @2xact_id,  @2xact_seqno, @date)
  1408.     
  1409.     IF @3xact_id = 0x0
  1410.       goto INSERT_CMDS
  1411.     IF @3command_id = 1
  1412.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1413.          @3xact_id,  @3xact_seqno, @date)
  1414.  
  1415.     IF @4xact_id = 0x0
  1416.       goto INSERT_CMDS
  1417.     IF @4command_id = 1
  1418.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1419.         @4xact_id,  @4xact_seqno, @date)
  1420.  
  1421.     IF @5xact_id = 0x0
  1422.       goto INSERT_CMDS
  1423.  
  1424.     IF @5command_id = 1
  1425.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1426.          @5xact_id,  @5xact_seqno, @date)
  1427.  
  1428.     IF @6xact_id = 0x0
  1429.       goto INSERT_CMDS
  1430.     IF @6command_id = 1
  1431.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1432.          @6xact_id,  @6xact_seqno, @date)
  1433.  
  1434.     IF @7xact_id = 0x0
  1435.       goto INSERT_CMDS
  1436.     IF @7command_id = 1
  1437.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1438.          @7xact_id,  @7xact_seqno, @date)
  1439.  
  1440.     IF @8xact_id = 0x0
  1441.       goto INSERT_CMDS
  1442.     IF @8command_id = 1
  1443.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1444.          @8xact_id,  @8xact_seqno, @date)
  1445.  
  1446.     IF @9xact_id = 0x0
  1447.       goto INSERT_CMDS
  1448.     IF @9command_id = 1
  1449.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1450.          @9xact_id,  @9xact_seqno, @date)
  1451.  
  1452.     IF @10xact_id = 0x0
  1453.       goto INSERT_CMDS
  1454.     IF @10command_id = 1
  1455.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1456.          @10xact_id,  @10xact_seqno, @date)
  1457.  
  1458.     IF @11xact_id = 0x0
  1459.       goto INSERT_CMDS
  1460.     IF @11command_id = 1
  1461.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1462.          @11xact_id,  @11xact_seqno, @date)
  1463.  
  1464.     IF @12xact_id = 0x0
  1465.       goto INSERT_CMDS
  1466.     IF @12command_id = 1
  1467.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1468.          @12xact_id,  @12xact_seqno, @date)
  1469.  
  1470.     IF @13xact_id = 0x0
  1471.       goto INSERT_CMDS
  1472.     IF @13command_id = 1
  1473.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1474.          @13xact_id,  @13xact_seqno, @date)
  1475.  
  1476.     IF @14xact_id = 0x0
  1477.       goto INSERT_CMDS
  1478.     IF @14command_id = 1
  1479.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1480.          @14xact_id,  @14xact_seqno, @date)
  1481.  
  1482.     IF @15xact_id = 0x0
  1483.       goto INSERT_CMDS
  1484.     IF @15command_id = 1
  1485.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1486.          @15xact_id,  @15xact_seqno, @date)
  1487.  
  1488.     IF @16xact_id = 0x0
  1489.       goto INSERT_CMDS
  1490.     IF @16command_id = 1
  1491.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1492.          @16xact_id,  @16xact_seqno, @date)
  1493.  
  1494.     IF @17xact_id = 0x0
  1495.       goto INSERT_CMDS
  1496.     IF @17command_id = 1
  1497.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1498.          @17xact_id,  @17xact_seqno, @date)
  1499.  
  1500.     IF @18xact_id = 0x0
  1501.       goto INSERT_CMDS
  1502.     IF @18command_id = 1
  1503.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1504.          @18xact_id,  @18xact_seqno, @date)
  1505.  
  1506.     IF @19xact_id = 0x0
  1507.       goto INSERT_CMDS
  1508.     IF @19command_id = 1
  1509.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1510.          @19xact_id,  @19xact_seqno, @date)
  1511.  
  1512.     IF @20xact_id = 0x0
  1513.       goto INSERT_CMDS
  1514.     IF @20command_id = 1
  1515.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1516.          @20xact_id,  @20xact_seqno, @date)
  1517.  
  1518.     IF @21xact_id = 0x0
  1519.       goto INSERT_CMDS
  1520.     IF @21command_id = 1
  1521.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1522.          @21xact_id,  @21xact_seqno, @date)
  1523.  
  1524.     IF @22xact_id = 0x0
  1525.       goto INSERT_CMDS
  1526.     IF @22command_id = 1
  1527.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1528.          @22xact_id,  @22xact_seqno, @date)
  1529.  
  1530.     IF @23xact_id = 0x0
  1531.       goto INSERT_CMDS
  1532.     IF @23command_id = 1
  1533.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1534.          @23xact_id,  @23xact_seqno, @date)
  1535.  
  1536.     IF @24xact_id = 0x0
  1537.       goto INSERT_CMDS
  1538.     IF @24command_id = 1
  1539.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1540.          @24xact_id,  @24xact_seqno, @date)
  1541.  
  1542.     IF @25xact_id = 0x0
  1543.       goto INSERT_CMDS
  1544.     IF @25command_id = 1
  1545.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1546.          @25xact_id,  @25xact_seqno, @date)
  1547.  
  1548.     IF @26xact_id = 0x0
  1549.       goto INSERT_CMDS
  1550.     IF @26command_id = 1
  1551.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  1552.          @26xact_id,  @26xact_seqno, @date)
  1553.  
  1554. INSERT_CMDS:
  1555.  
  1556.     -- Get the originator_id for the first command 
  1557.     if @originator <> N'' and @originator_db <> N'' and @originator is not null and @originator_db is not null 
  1558.     begin 
  1559.         set @originator_id = null select @originator_id = id from MSrepl_originators where
  1560.             publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@originator) and
  1561.             dbname = @originator_db
  1562.         if @originator_id is null
  1563.         begin
  1564.             insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1565.                 (@publisher_database_id, @originator, @originator_db)
  1566.             select @originator_id = @@identity
  1567.         end
  1568.     end
  1569.     else
  1570.         select @originator_id = 0
  1571.  
  1572.     -- Now insert into MSrepl_commands
  1573.     IF @command IS NOT NULL
  1574.     begin
  1575.         if( @type in( 37,38 ) )
  1576.         begin
  1577.           select @syncstat = 38 - @type
  1578.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @article_id, @syncstat, @xact_seqno
  1579.         end
  1580.  
  1581.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1582.             @xact_seqno,@type, @article_id, 
  1583.             @originator_id, 
  1584.             @command_id, @partial_command, @command)
  1585.     end
  1586.  
  1587.     IF @1xact_id = 0x0
  1588.       return
  1589.  
  1590.     IF @1command IS NOT NULL
  1591.     begin
  1592.             if @1originator <> N'' and @1originator_db <> N'' and @1originator is not null and @1originator_db is not null 
  1593.             begin 
  1594.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1595.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@1originator) and
  1596.                     dbname = @1originator_db
  1597.                 if @originator_id is null
  1598.                 begin
  1599.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1600.                         (@publisher_database_id, @1originator, @1originator_db)
  1601.                     select @originator_id = @@identity
  1602.                 end
  1603.             end
  1604.             else
  1605.                 select @originator_id = 0
  1606.     
  1607.         if( @type in( 37,38 ) )
  1608.         begin
  1609.           select @syncstat = 38 - @1type
  1610.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @1article_id, @syncstat, @1xact_seqno
  1611.         end
  1612.  
  1613.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1614.             @1xact_seqno,@1type, @1article_id, 
  1615.             @originator_id, 
  1616.             @1command_id, @1partial_command, @1command)
  1617.     end
  1618.  
  1619.     IF @2xact_id = 0x0
  1620.       return
  1621.     IF @2command IS NOT NULL
  1622.     begin
  1623.             if @2originator <> N'' and @2originator_db <> N'' and @2originator is not null and @2originator_db is not null 
  1624.             begin 
  1625.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1626.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@2originator) and
  1627.                     dbname = @2originator_db
  1628.                 if @originator_id is null
  1629.                 begin
  1630.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1631.                         (@publisher_database_id, @2originator, @2originator_db)
  1632.                     select @originator_id = @@identity
  1633.                 end
  1634.             end
  1635.             else
  1636.                 select @originator_id = 0
  1637.     
  1638.         if( @type in( 37,38 ) )
  1639.         begin
  1640.           select @syncstat = 38 - @2type
  1641.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @2article_id, @syncstat, @2xact_seqno 
  1642.         end
  1643.  
  1644.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1645.             @2xact_seqno,@2type, @2article_id, 
  1646.             @originator_id, 
  1647.             @2command_id, @2partial_command, @2command)
  1648.     end
  1649.  
  1650.     IF @3xact_id = 0x0
  1651.       return
  1652.     IF @3command IS NOT NULL
  1653.     begin
  1654.             if @3originator <> N'' and @3originator_db <> N'' and @3originator is not null and @3originator_db is not null 
  1655.             begin 
  1656.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1657.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@3originator) and
  1658.                     dbname = @3originator_db
  1659.                 if @originator_id is null
  1660.                 begin
  1661.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1662.                         (@publisher_database_id, @3originator, @3originator_db)
  1663.                     select @originator_id = @@identity
  1664.                 end
  1665.             end
  1666.             else
  1667.                 select @originator_id = 0
  1668.  
  1669.         if( @type in( 37,38 ) )
  1670.         begin
  1671.           select @syncstat = 38 - @3type
  1672.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @3article_id, @syncstat, @3xact_seqno 
  1673.         end
  1674.     
  1675.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1676.             @3xact_seqno,@3type, @3article_id, 
  1677.             @originator_id, 
  1678.             @3command_id, @3partial_command, @3command)
  1679.     end
  1680.  
  1681.     IF @4xact_id = 0x0
  1682.       return
  1683.     IF @4command IS NOT NULL
  1684.     begin
  1685.             if @4originator <> N'' and @4originator_db <> N'' and @4originator is not null and @4originator_db is not null 
  1686.             begin 
  1687.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1688.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@4originator) and
  1689.                     dbname = @4originator_db
  1690.                 if @originator_id is null
  1691.                 begin
  1692.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1693.                         (@publisher_database_id, @4originator, @4originator_db)
  1694.                     select @originator_id = @@identity
  1695.                 end
  1696.             end
  1697.             else
  1698.                 select @originator_id = 0
  1699.  
  1700.         if( @type in( 37,38 ) )
  1701.         begin
  1702.           select @syncstat = 38 - @4type
  1703.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @4article_id, @syncstat, @4xact_seqno 
  1704.         end
  1705.     
  1706.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1707.             @4xact_seqno,@4type, @4article_id, 
  1708.             @originator_id, 
  1709.             @4command_id, @4partial_command, @4command)
  1710.     end
  1711.  
  1712.     IF @5xact_id = 0x0
  1713.       return
  1714.     IF @5command IS NOT NULL
  1715.     begin
  1716.             if @5originator <> N'' and @5originator_db <> N'' and @5originator is not null and @5originator_db is not null 
  1717.             begin 
  1718.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1719.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@5originator) and
  1720.                     dbname = @5originator_db
  1721.                 if @originator_id is null
  1722.                 begin
  1723.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1724.                         (@publisher_database_id, @5originator, @5originator_db)
  1725.                     select @originator_id = @@identity
  1726.                 end
  1727.             end
  1728.             else
  1729.                 select @originator_id = 0
  1730.     
  1731.         if( @type in( 37,38 ) )
  1732.         begin
  1733.           select @syncstat = 38 - @5type
  1734.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @5article_id, @syncstat, @5xact_seqno 
  1735.         end
  1736.  
  1737.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1738.             @5xact_seqno,@5type, @5article_id, 
  1739.             @originator_id, 
  1740.             @5command_id, @5partial_command, @5command)
  1741.     end
  1742.  
  1743.     IF @6xact_id = 0x0
  1744.       return
  1745.     IF @6command IS NOT NULL
  1746.     begin
  1747.             if @6originator <> N'' and @6originator_db <> N'' and @6originator is not null and @6originator_db is not null 
  1748.             begin 
  1749.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1750.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@6originator) and
  1751.                     dbname = @6originator_db
  1752.                 if @originator_id is null
  1753.                 begin
  1754.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1755.                         (@publisher_database_id, @6originator, @6originator_db)
  1756.                     select @originator_id = @@identity
  1757.                 end
  1758.             end
  1759.             else
  1760.                 select @originator_id = 0
  1761.  
  1762.         if( @type in( 37,38 ) )
  1763.         begin
  1764.           select @syncstat = 38 - @6type
  1765.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @6article_id, @syncstat, @6xact_seqno 
  1766.         end
  1767.     
  1768.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1769.             @6xact_seqno,@6type, @6article_id, 
  1770.             @originator_id, 
  1771.             @6command_id, @6partial_command, @6command)
  1772.     end
  1773.  
  1774.     IF @7xact_id = 0x0
  1775.       return
  1776.     IF @7command IS NOT NULL
  1777.     begin
  1778.             if @7originator <> N'' and @7originator_db <> N'' and @7originator is not null and @7originator_db is not null 
  1779.             begin 
  1780.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1781.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@7originator) and
  1782.                     dbname = @7originator_db
  1783.                 if @originator_id is null
  1784.                 begin
  1785.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1786.                         (@publisher_database_id, @7originator, @7originator_db)
  1787.                     select @originator_id = @@identity
  1788.                 end
  1789.             end
  1790.             else
  1791.                 select @originator_id = 0
  1792.     
  1793.         if( @type in( 37,38 ) )
  1794.         begin
  1795.           select @syncstat = 38 - @7type
  1796.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @7article_id, @syncstat, @7xact_seqno 
  1797.         end
  1798.  
  1799.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1800.             @7xact_seqno,@7type, @7article_id, 
  1801.             @originator_id, 
  1802.             @7command_id, @7partial_command, @7command)
  1803.     end
  1804.  
  1805.     IF @8xact_id = 0x0
  1806.       return
  1807.     IF @8command IS NOT NULL
  1808.     begin
  1809.             if @8originator <> N'' and @8originator_db <> N'' and @8originator is not null and @8originator_db is not null 
  1810.             begin 
  1811.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1812.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@8originator) and
  1813.                     dbname = @8originator_db
  1814.                 if @originator_id is null
  1815.                 begin
  1816.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1817.                         (@publisher_database_id, @8originator, @8originator_db)
  1818.                     select @originator_id = @@identity
  1819.                 end
  1820.             end
  1821.             else
  1822.                 select @originator_id = 0
  1823.     
  1824.         if( @type in( 37,38 ) )
  1825.         begin
  1826.           select @syncstat = 38 - @8type
  1827.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @8article_id, @syncstat, @8xact_seqno 
  1828.         end
  1829.  
  1830.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1831.             @8xact_seqno,@8type, @8article_id, 
  1832.             @originator_id, 
  1833.             @8command_id, @8partial_command, @8command)
  1834.     end
  1835.  
  1836.     IF @9xact_id = 0x0
  1837.       return
  1838.     IF @9command IS NOT NULL
  1839.     begin
  1840.             if @9originator <> N'' and @9originator_db <> N'' and @9originator is not null and @9originator_db is not null 
  1841.             begin 
  1842.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1843.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@9originator) and
  1844.                     dbname = @9originator_db
  1845.                 if @originator_id is null
  1846.                 begin
  1847.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1848.                         (@publisher_database_id, @9originator, @9originator_db)
  1849.                     select @originator_id = @@identity
  1850.                 end
  1851.             end
  1852.             else
  1853.                 select @originator_id = 0
  1854.     
  1855.         if( @type in( 37,38 ) )
  1856.         begin
  1857.           select @syncstat = 38 - @9type
  1858.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @9article_id, @syncstat, @9xact_seqno 
  1859.         end
  1860.  
  1861.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1862.             @9xact_seqno,@9type, @9article_id, 
  1863.             @originator_id, 
  1864.             @9command_id, @9partial_command, @9command)
  1865.     end
  1866.  
  1867.     IF @10xact_id = 0x0
  1868.       return
  1869.     IF @10command IS NOT NULL
  1870.     begin
  1871.             if @10originator <> N'' and @10originator_db <> N'' and @10originator is not null and @10originator_db is not null 
  1872.             begin 
  1873.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1874.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@10originator) and
  1875.                     dbname = @10originator_db
  1876.                 if @originator_id is null
  1877.                 begin
  1878.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1879.                         (@publisher_database_id, @10originator, @10originator_db)
  1880.                     select @originator_id = @@identity
  1881.                 end
  1882.             end
  1883.             else
  1884.                 select @originator_id = 0
  1885.     
  1886.         if( @type in( 37,38 ) )
  1887.         begin
  1888.           select @syncstat = 38 - @10type
  1889.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @10article_id, @syncstat, @10xact_seqno 
  1890.         end
  1891.  
  1892.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1893.             @10xact_seqno,@10type, @10article_id, 
  1894.             @originator_id, 
  1895.             @10command_id, @10partial_command, @10command)
  1896.     end
  1897.  
  1898.     IF @11xact_id = 0x0
  1899.       return
  1900.     IF @11command IS NOT NULL
  1901.     begin
  1902.             if @11originator <> N'' and @11originator_db <> N'' and @11originator is not null and @11originator_db is not null 
  1903.             begin 
  1904.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1905.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@11originator) and
  1906.                     dbname = @11originator_db
  1907.                 if @originator_id is null
  1908.                 begin
  1909.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1910.                         (@publisher_database_id, @11originator, @11originator_db)
  1911.                     select @originator_id = @@identity
  1912.                 end
  1913.             end
  1914.             else
  1915.                 select @originator_id = 0
  1916.     
  1917.         if( @type in( 37,38 ) )
  1918.         begin
  1919.           select @syncstat = 38 - @11type
  1920.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @11article_id, @syncstat, @11xact_seqno 
  1921.         end
  1922.  
  1923.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1924.             @11xact_seqno,@11type, @11article_id, 
  1925.             @originator_id, 
  1926.             @11command_id, @11partial_command, @11command)
  1927.     end
  1928.  
  1929.     IF @12xact_id = 0x0
  1930.       return
  1931.     IF @12command IS NOT NULL
  1932.     begin
  1933.             if @12originator <> N'' and @12originator_db <> N'' and @12originator is not null and @12originator_db is not null 
  1934.             begin 
  1935.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1936.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@12originator) and
  1937.                     dbname = @12originator_db
  1938.                 if @originator_id is null
  1939.                 begin
  1940.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1941.                         (@publisher_database_id, @12originator, @12originator_db)
  1942.                     select @originator_id = @@identity
  1943.                 end
  1944.             end
  1945.             else
  1946.                 select @originator_id = 0
  1947.     
  1948.         if( @type in( 37,38 ) )
  1949.         begin
  1950.           select @syncstat = 38 - @12type
  1951.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @12article_id, @syncstat, @12xact_seqno 
  1952.         end
  1953.  
  1954.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1955.             @12xact_seqno,@12type, @12article_id, 
  1956.             @originator_id, 
  1957.             @12command_id, @12partial_command, @12command)
  1958.     end
  1959.  
  1960.  
  1961.     IF @13xact_id = 0x0
  1962.       return
  1963.     IF @13command IS NOT NULL
  1964.     begin
  1965.             if @13originator <> N'' and @13originator_db <> N'' and @13originator is not null and @13originator_db is not null 
  1966.             begin 
  1967.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1968.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@13originator) and
  1969.                     dbname = @13originator_db
  1970.                 if @originator_id is null
  1971.                 begin
  1972.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  1973.                         (@publisher_database_id, @13originator, @13originator_db)
  1974.                     select @originator_id = @@identity
  1975.                 end
  1976.             end
  1977.             else
  1978.                 select @originator_id = 0
  1979.     
  1980.         if( @type in( 37,38 ) )
  1981.         begin
  1982.           select @syncstat = 38 - @13type
  1983.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @13article_id, @syncstat, @13xact_seqno 
  1984.         end
  1985.  
  1986.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  1987.             @13xact_seqno,@13type, @13article_id, 
  1988.             @originator_id, 
  1989.             @13command_id, @13partial_command, @13command)
  1990.     end
  1991.  
  1992.     IF @14xact_id = 0x0
  1993.       return
  1994.     IF @14command IS NOT NULL
  1995.     begin
  1996.             if @14originator <> N'' and @14originator_db <> N'' and @14originator is not null and @14originator_db is not null 
  1997.             begin 
  1998.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  1999.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@14originator) and
  2000.                     dbname = @14originator_db
  2001.                 if @originator_id is null
  2002.                 begin
  2003.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2004.                         (@publisher_database_id, @14originator, @14originator_db)
  2005.                     select @originator_id = @@identity
  2006.                 end
  2007.             end
  2008.             else
  2009.                 select @originator_id = 0
  2010.     
  2011.         if( @type in( 37,38 ) )
  2012.         begin
  2013.           select @syncstat = 38 - @14type
  2014.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @14article_id, @syncstat, @14xact_seqno 
  2015.         end
  2016.  
  2017.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2018.             @14xact_seqno,@14type, @14article_id, 
  2019.             @originator_id, 
  2020.             @14command_id, @14partial_command, @14command)
  2021.     end
  2022.  
  2023.  
  2024.     IF @15xact_id = 0x0
  2025.       return
  2026.     IF @15command IS NOT NULL
  2027.     begin
  2028.             if @15originator <> N'' and @15originator_db <> N'' and @15originator is not null and @15originator_db is not null 
  2029.             begin 
  2030.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2031.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@15originator) and
  2032.                     dbname = @15originator_db
  2033.                 if @originator_id is null
  2034.                 begin
  2035.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2036.                         (@publisher_database_id, @15originator, @15originator_db)
  2037.                     select @originator_id = @@identity
  2038.                 end
  2039.             end
  2040.             else
  2041.                 select @originator_id = 0
  2042.     
  2043.         if( @type in( 37,38 ) )
  2044.         begin
  2045.           select @syncstat = 38 - @15type
  2046.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @15article_id, @syncstat, @15xact_seqno 
  2047.         end
  2048.  
  2049.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2050.             @15xact_seqno,@15type, @15article_id, 
  2051.             @originator_id, 
  2052.             @15command_id, @15partial_command, @15command)
  2053.     end
  2054.  
  2055.     IF @16xact_id = 0x0
  2056.       return
  2057.     IF @16command IS NOT NULL
  2058.     begin
  2059.             if @16originator <> N'' and @16originator_db <> N'' and @16originator is not null and @16originator_db is not null 
  2060.             begin 
  2061.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2062.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@16originator) and
  2063.                     dbname = @16originator_db
  2064.                 if @originator_id is null
  2065.                 begin
  2066.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2067.                         (@publisher_database_id, @16originator, @16originator_db)
  2068.                     select @originator_id = @@identity
  2069.                 end
  2070.             end
  2071.             else
  2072.                 select @originator_id = 0
  2073.     
  2074.         if( @type in( 37,38 ) )
  2075.         begin
  2076.           select @syncstat = 38 - @16type
  2077.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @16article_id, @syncstat, @16xact_seqno 
  2078.         end
  2079.  
  2080.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2081.             @16xact_seqno,@16type, @16article_id, 
  2082.             @originator_id, 
  2083.             @16command_id, @16partial_command, @16command)
  2084.     end
  2085.  
  2086.  
  2087.     IF @17xact_id = 0x0
  2088.       return
  2089.     IF @17command IS NOT NULL
  2090.     begin
  2091.             if @17originator <> N'' and @17originator_db <> N'' and @17originator is not null and @17originator_db is not null 
  2092.             begin 
  2093.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2094.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@17originator) and
  2095.                     dbname = @17originator_db
  2096.                 if @originator_id is null
  2097.                 begin
  2098.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2099.                         (@publisher_database_id, @17originator, @17originator_db)
  2100.                     select @originator_id = @@identity
  2101.                 end
  2102.             end
  2103.             else
  2104.                 select @originator_id = 0
  2105.     
  2106.         if( @type in( 37,38 ) )
  2107.         begin
  2108.           select @syncstat = 38 - @17type
  2109.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @17article_id, @syncstat, @17xact_seqno 
  2110.         end
  2111.  
  2112.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2113.             @17xact_seqno,@17type, @17article_id, 
  2114.             @originator_id, 
  2115.             @17command_id, @17partial_command, @17command)
  2116.     end
  2117.  
  2118.  
  2119.     IF @18xact_id = 0x0
  2120.       return
  2121.     IF @18command IS NOT NULL
  2122.     begin
  2123.             if @18originator <> N'' and @18originator_db <> N'' and @18originator is not null and @18originator_db is not null 
  2124.             begin 
  2125.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2126.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@18originator) and
  2127.                     dbname = @18originator_db
  2128.                 if @originator_id is null
  2129.                 begin
  2130.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2131.                         (@publisher_database_id, @18originator, @18originator_db)
  2132.                     select @originator_id = @@identity
  2133.                 end
  2134.             end
  2135.             else
  2136.                 select @originator_id = 0
  2137.     
  2138.         if( @type in( 37,38 ) )
  2139.         begin
  2140.           select @syncstat = 38 - @18type
  2141.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @18article_id, @syncstat, @18xact_seqno 
  2142.         end
  2143.  
  2144.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2145.             @18xact_seqno,@18type, @18article_id, 
  2146.             @originator_id, 
  2147.             @18command_id, @18partial_command, @18command)
  2148.     end
  2149.  
  2150.  
  2151.     IF @19xact_id = 0x0
  2152.       return
  2153.     IF @19command IS NOT NULL
  2154.     begin
  2155.             if @19originator <> N'' and @19originator_db <> N'' and @19originator is not null and @19originator_db is not null 
  2156.             begin 
  2157.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2158.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@19originator) and
  2159.                     dbname = @19originator_db
  2160.                 if @originator_id is null
  2161.                 begin
  2162.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2163.                         (@publisher_database_id, @19originator, @19originator_db)
  2164.                     select @originator_id = @@identity
  2165.                 end
  2166.             end
  2167.             else
  2168.                 select @originator_id = 0
  2169.     
  2170.         if( @type in( 37,38 ) )
  2171.         begin
  2172.           select @syncstat = 38 - @19type
  2173.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @19article_id, @syncstat, @19xact_seqno 
  2174.         end
  2175.  
  2176.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2177.             @19xact_seqno,@19type, @19article_id, 
  2178.             @originator_id, 
  2179.             @19command_id, @19partial_command, @19command)
  2180.     end
  2181.  
  2182.  
  2183.     IF @20xact_id = 0x0
  2184.       return
  2185.     IF @20command IS NOT NULL
  2186.     begin
  2187.             if @20originator <> N'' and @20originator_db <> N'' and @20originator is not null and @20originator_db is not null 
  2188.             begin 
  2189.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2190.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@20originator) and
  2191.                     dbname = @20originator_db
  2192.                 if @originator_id is null
  2193.                 begin
  2194.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2195.                         (@publisher_database_id, @20originator, @20originator_db)
  2196.                     select @originator_id = @@identity
  2197.                 end
  2198.             end
  2199.             else
  2200.                 select @originator_id = 0
  2201.     
  2202.         if( @type in( 37,38 ) )
  2203.         begin
  2204.           select @syncstat = 38 - @20type
  2205.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @20article_id, @syncstat, @20xact_seqno 
  2206.         end
  2207.  
  2208.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2209.             @20xact_seqno,@20type, @20article_id, 
  2210.             @originator_id, 
  2211.             @20command_id, @20partial_command, @20command)
  2212.     end
  2213.  
  2214.     IF @21xact_id = 0x0
  2215.       return
  2216.     IF @21command IS NOT NULL
  2217.     begin
  2218.             if @21originator <> N'' and @21originator_db <> N'' and @21originator is not null and @21originator_db is not null 
  2219.             begin 
  2220.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2221.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@21originator) and
  2222.                     dbname = @21originator_db
  2223.                 if @originator_id is null
  2224.                 begin
  2225.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2226.                         (@publisher_database_id, @21originator, @21originator_db)
  2227.                     select @originator_id = @@identity
  2228.                 end
  2229.             end
  2230.             else
  2231.                 select @originator_id = 0
  2232.     
  2233.         if( @type in( 37,38 ) )
  2234.         begin
  2235.           select @syncstat = 38 - @21type
  2236.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @21article_id, @syncstat, @21xact_seqno 
  2237.         end
  2238.  
  2239.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2240.             @21xact_seqno,@21type, @21article_id, 
  2241.             @originator_id, 
  2242.             @21command_id, @21partial_command, @21command)
  2243.     end
  2244.  
  2245.     IF @22xact_id = 0x0
  2246.       return
  2247.     IF @22command IS NOT NULL
  2248.     begin
  2249.             if @22originator <> N'' and @22originator_db <> N'' and @22originator is not null and @22originator_db is not null 
  2250.             begin 
  2251.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2252.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@22originator) and
  2253.                     dbname = @22originator_db
  2254.                 if @originator_id is null
  2255.                 begin
  2256.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2257.                         (@publisher_database_id, @22originator, @22originator_db)
  2258.                     select @originator_id = @@identity
  2259.                 end
  2260.             end
  2261.             else
  2262.                 select @originator_id = 0
  2263.         end
  2264.     
  2265.         if( @type in( 37,38 ) )
  2266.         begin
  2267.           select @syncstat = 38 - @22type
  2268.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @22article_id, @syncstat, @22xact_seqno 
  2269.         end
  2270.  
  2271.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2272.             @22xact_seqno,@22type, @22article_id, 
  2273.             @originator_id, 
  2274.             @22command_id, @22partial_command, @22command)
  2275.  
  2276.  
  2277.     IF @23xact_id = 0x0
  2278.       return
  2279.     IF @23command IS NOT NULL
  2280.     begin
  2281.             if @23originator <> N'' and @23originator_db <> N'' and @23originator is not null and @23originator_db is not null 
  2282.             begin 
  2283.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2284.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@23originator) and
  2285.                     dbname = @23originator_db
  2286.                 if @originator_id is null
  2287.                 begin
  2288.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2289.                         (@publisher_database_id, @23originator, @23originator_db)
  2290.                     select @originator_id = @@identity
  2291.                 end
  2292.             end
  2293.             else
  2294.                 select @originator_id = 0
  2295.     
  2296.         if( @type in( 37,38 ) )
  2297.         begin
  2298.           select @syncstat = 38 - @23type
  2299.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @23article_id, @syncstat, @23xact_seqno 
  2300.         end
  2301.  
  2302.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2303.             @23xact_seqno,@23type, @23article_id, 
  2304.             @originator_id, 
  2305.             @23command_id, @23partial_command, @23command)
  2306.     end
  2307.  
  2308.     IF @24xact_id = 0x0
  2309.       return
  2310.     IF @24command IS NOT NULL
  2311.     begin
  2312.             if @24originator <> N'' and @24originator_db <> N'' and @24originator is not null and @24originator_db is not null 
  2313.             begin 
  2314.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2315.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@24originator) and
  2316.                     dbname = @24originator_db
  2317.                 if @originator_id is null
  2318.                 begin
  2319.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2320.                         (@publisher_database_id, @24originator, @24originator_db)
  2321.                     select @originator_id = @@identity
  2322.                 end
  2323.             end
  2324.             else
  2325.                 select @originator_id = 0
  2326.     
  2327.         if( @type in( 37,38 ) )
  2328.         begin
  2329.           select @syncstat = 38 - @24type
  2330.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @24article_id, @syncstat, @24xact_seqno 
  2331.         end
  2332.  
  2333.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2334.             @24xact_seqno,@24type, @24article_id, 
  2335.             @originator_id, 
  2336.             @24command_id, @24partial_command, @24command)
  2337.     end
  2338.  
  2339.  
  2340.     IF @25xact_id = 0x0
  2341.       return
  2342.     IF @25command IS NOT NULL
  2343.     begin
  2344.             if @25originator <> N'' and @25originator_db <> N'' and @25originator is not null and @25originator_db is not null 
  2345.             begin 
  2346.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2347.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@25originator) and
  2348.                     dbname = @25originator_db
  2349.                 if @originator_id is null
  2350.                 begin
  2351.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2352.                         (@publisher_database_id, @25originator, @25originator_db)
  2353.                     select @originator_id = @@identity
  2354.                 end
  2355.             end
  2356.             else
  2357.                 select @originator_id = 0
  2358.     
  2359.         if( @type in( 37,38 ) )
  2360.         begin
  2361.           select @syncstat = 38 - @25type
  2362.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @25article_id, @syncstat, @25xact_seqno 
  2363.         end
  2364.  
  2365.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2366.             @25xact_seqno,@25type, @25article_id, 
  2367.             @originator_id, 
  2368.             @25command_id, @25partial_command, @25command)
  2369.     end
  2370.  
  2371.  
  2372.     IF @26xact_id = 0x0
  2373.       return
  2374.     IF @26command IS NOT NULL
  2375.     begin
  2376.             if @26originator <> N'' and @26originator_db <> N'' and @26originator is not null and @26originator_db is not null 
  2377.             begin 
  2378.                 set @originator_id = null select @originator_id = id from MSrepl_originators where
  2379.                     publisher_database_id = @publisher_database_id and UPPER(srvname) = UPPER(@26originator) and
  2380.                     dbname = @26originator_db
  2381.                 if @originator_id is null
  2382.                 begin
  2383.                     insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2384.                         (@publisher_database_id, @26originator, @26originator_db)
  2385.                     select @originator_id = @@identity
  2386.                 end
  2387.             end
  2388.             else
  2389.                 select @originator_id = 0
  2390.     
  2391.         if( @type in( 37,38 ) )
  2392.         begin
  2393.           select @syncstat = 38 - @26type
  2394.           exec sp_MSset_syncstate @publisher_id, @publisher_db, @26article_id, @syncstat, @26xact_seqno 
  2395.         end
  2396.  
  2397.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2398.             @26xact_seqno,@26type, @26article_id, 
  2399.             @originator_id, 
  2400.             @26command_id, @26partial_command, @26command)
  2401.     end
  2402.  
  2403.  
  2404.     IF @@ERROR <> 0
  2405.       return (1)
  2406. GO
  2407.  
  2408. raiserror(15339,-1,-1,'sp_MSadd_repl_commands27hp6x')
  2409. GO
  2410.  
  2411. CREATE PROCEDURE sp_MSadd_repl_commands27hp6x
  2412. @publisher_id smallint,
  2413. @publisher_db sysname,
  2414. @data varbinary( 1575 ),
  2415. @1data varbinary(1575) = NULL,
  2416. @2data varbinary(1575) = NULL,
  2417. @3data varbinary(1575) = NULL,
  2418. @4data varbinary(1575) = NULL,
  2419. @5data varbinary(1575) = NULL,
  2420. @6data varbinary(1575) = NULL,
  2421. @7data varbinary(1575) = NULL,
  2422. @8data varbinary(1575) = NULL,
  2423. @9data varbinary(1575) = NULL,
  2424. @10data varbinary(1575) = NULL,
  2425. @11data varbinary(1575) = NULL,
  2426. @12data varbinary(1575) = NULL,
  2427. @13data varbinary(1575) = NULL,
  2428. @14data varbinary(1575) = NULL,
  2429. @15data varbinary(1575) = NULL,
  2430. @16data varbinary(1575) = NULL,
  2431. @17data varbinary(1575) = NULL,
  2432. @18data varbinary(1575) = NULL,
  2433. @19data varbinary(1575) = NULL,
  2434. @20data varbinary(1575) = NULL,
  2435. @21data varbinary(1575) = NULL,
  2436. @22data varbinary(1575) = NULL,
  2437. @23data varbinary(1575) = NULL,
  2438. @24data varbinary(1575) = NULL,
  2439. @25data varbinary(1575) = NULL,
  2440. @26data varbinary(1575) = NULL
  2441. AS
  2442.  
  2443.     SET NOCOUNT ON
  2444.  
  2445.     DECLARE @xact_id    varbinary(10)
  2446.     DECLARE @xact_seqno varbinary(10)
  2447.     DECLARE @article_id int
  2448.     DECLARE @command_id int
  2449.     DECLARE @type       int
  2450.     DECLARE @partial_command bit
  2451.     DECLARE @command    varbinary(1024)
  2452.  
  2453.     DECLARE @originator sysname
  2454.     DECLARE @originator_db sysname
  2455.  
  2456.     DECLARE @publisher_database_id int
  2457.     DECLARE @date datetime
  2458.     declare @originator_id int
  2459.  
  2460.     DECLARE @cmd_data_len  smallint
  2461.     DECLARE @orig_srv_len smallint
  2462.     DECLARE @orig_db_len  smallint
  2463.  
  2464.     SELECT @date = GETDATE()
  2465.  
  2466.     -- Get publisher database id.
  2467.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  2468.         publisher_db = @publisher_db
  2469.  
  2470.     -- First insert into MS_repl_transactions
  2471.     IF convert( int, substring( @data, 25, 4 ) ) = 1
  2472.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2473.          substring( @data, 1, 6 ), substring( @data, 11, 8 ), @date)
  2474.  
  2475.     IF @1data is null
  2476.       goto INSERT_CMDS
  2477.     IF convert( int, substring( @1data, 25, 4 ) ) = 1
  2478.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2479.          substring( @1data, 1, 6 ), substring( @1data, 11, 8 ), @date)
  2480.  
  2481.     IF @2data is null
  2482.       goto INSERT_CMDS
  2483.     IF convert( int, substring( @2data, 25, 4 ) ) = 1
  2484.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2485.          substring( @2data, 1, 6 ), substring( @2data, 11, 8 ), @date)
  2486.     
  2487.     IF @3data is null
  2488.       goto INSERT_CMDS
  2489.     IF convert( int, substring( @3data, 25, 4 ) ) = 1
  2490.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2491.          substring( @3data, 1, 6 ), substring( @3data, 11, 8 ), @date)
  2492.  
  2493.     IF @4data is null
  2494.       goto INSERT_CMDS
  2495.     IF convert( int, substring( @4data, 25, 4 ) ) = 1
  2496.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2497.          substring( @4data, 1, 6 ), substring( @4data, 11, 8 ), @date)
  2498.  
  2499.     IF @5data is null
  2500.       goto INSERT_CMDS
  2501.     IF convert( int, substring( @5data, 25, 4 ) ) = 1
  2502.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2503.          substring( @5data, 1, 6 ), substring( @5data, 11, 8 ), @date)
  2504.  
  2505.     IF @6data is null
  2506.       goto INSERT_CMDS
  2507.     IF convert( int, substring( @6data, 25, 4 ) ) = 1
  2508.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2509.          substring( @6data, 1, 6 ), substring( @6data, 11, 8 ), @date)
  2510.  
  2511.     IF @7data is null
  2512.       goto INSERT_CMDS
  2513.     IF convert( int, substring( @7data, 25, 4 ) ) = 1
  2514.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2515.          substring( @7data, 1, 6 ), substring( @7data, 11, 8 ), @date)
  2516.  
  2517.     IF @8data is null
  2518.       goto INSERT_CMDS
  2519.     IF convert( int, substring( @8data, 25, 4 ) ) = 1
  2520.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2521.          substring( @8data, 1, 6 ), substring( @8data, 11, 8 ), @date)
  2522.  
  2523.     IF @9data is null
  2524.       goto INSERT_CMDS
  2525.     IF convert( int, substring( @9data, 25, 4 ) ) = 1
  2526.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2527.          substring( @9data, 1, 6 ), substring( @9data, 11, 8 ), @date)
  2528.  
  2529.     IF @10data is null
  2530.       goto INSERT_CMDS
  2531.     IF convert( int, substring( @10data, 25, 4 ) ) = 1
  2532.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2533.          substring( @10data, 1, 6 ), substring( @10data, 11, 8 ), @date)
  2534.  
  2535.     IF @11data is null
  2536.       goto INSERT_CMDS
  2537.     IF convert( int, substring( @11data, 25, 4 ) ) = 1
  2538.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2539.          substring( @11data, 1, 6 ), substring( @11data, 11, 8 ), @date)
  2540.  
  2541.     IF @12data is null
  2542.       goto INSERT_CMDS
  2543.     IF convert( int, substring( @12data, 25, 4 ) ) = 1
  2544.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2545.          substring( @12data, 1, 6 ), substring( @12data, 11, 8 ), @date)
  2546.  
  2547.     IF @13data is null
  2548.       goto INSERT_CMDS
  2549.     IF convert( int, substring( @13data, 25, 4 ) ) = 1
  2550.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2551.          substring( @13data, 1, 6 ), substring( @13data, 11, 8 ), @date)
  2552.  
  2553.     IF @14data is null
  2554.       goto INSERT_CMDS
  2555.     IF convert( int, substring( @14data, 25, 4 ) ) = 1
  2556.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2557.          substring( @14data, 1, 6 ), substring( @14data, 11, 8 ), @date)
  2558.  
  2559.     IF @15data is null
  2560.       goto INSERT_CMDS
  2561.     IF convert( int, substring( @15data, 25, 4 ) ) = 1
  2562.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2563.          substring( @15data, 1, 6 ), substring( @15data, 11, 8 ), @date)
  2564.  
  2565.     IF @16data is null
  2566.       goto INSERT_CMDS
  2567.     IF convert( int, substring( @16data, 25, 4 ) ) = 1
  2568.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2569.          substring( @16data, 1, 6 ), substring( @16data, 11, 8 ), @date)
  2570.  
  2571.     IF @17data is null
  2572.       goto INSERT_CMDS
  2573.     IF convert( int, substring( @17data, 25, 4 ) ) = 1
  2574.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2575.          substring( @17data, 1, 6 ), substring( @17data, 11, 8 ), @date)
  2576.  
  2577.     IF @18data is null
  2578.       goto INSERT_CMDS
  2579.     IF convert( int, substring( @18data, 25, 4 ) ) = 1
  2580.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2581.          substring( @18data, 1, 6 ), substring( @18data, 11, 8 ), @date)
  2582.  
  2583.     IF @19data is null
  2584.       goto INSERT_CMDS
  2585.     IF convert( int, substring( @19data, 25, 4 ) ) = 1
  2586.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2587.          substring( @19data, 1, 6 ), substring( @19data, 11, 8 ), @date)
  2588.  
  2589.     IF @20data is null
  2590.       goto INSERT_CMDS
  2591.     IF convert( int, substring( @20data, 25, 4 ) ) = 1
  2592.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2593.          substring( @20data, 1, 6 ), substring( @20data, 11, 8 ), @date)
  2594.  
  2595.     IF @21data is null
  2596.       goto INSERT_CMDS
  2597.     IF convert( int, substring( @21data, 25, 4 ) ) = 1
  2598.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2599.          substring( @21data, 1, 6 ), substring( @21data, 11, 8 ), @date)
  2600.  
  2601.     IF @22data is null
  2602.       goto INSERT_CMDS
  2603.     IF convert( int, substring( @22data, 25, 4 ) ) = 1
  2604.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2605.          substring( @22data, 1, 6 ), substring( @22data, 11, 8 ), @date)
  2606.  
  2607.     IF @23data is null
  2608.       goto INSERT_CMDS
  2609.     IF convert( int, substring( @23data, 25, 4 ) ) = 1
  2610.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2611.          substring( @23data, 1, 6 ), substring( @23data, 11, 8 ), @date)
  2612.  
  2613.     IF @24data is null
  2614.       goto INSERT_CMDS
  2615.     IF convert( int, substring( @24data, 25, 4 ) ) = 1
  2616.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2617.          substring( @24data, 1, 6 ), substring( @24data, 11, 8 ), @date)
  2618.  
  2619.     IF @25data is null
  2620.       goto INSERT_CMDS
  2621.     IF convert( int, substring( @25data, 25, 4 ) ) = 1
  2622.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2623.          substring( @25data, 1, 6 ), substring( @25data, 11, 8 ), @date)
  2624.  
  2625.     IF @26data is null
  2626.       goto INSERT_CMDS
  2627.     IF convert( int, substring( @26data, 25, 4 ) ) = 1
  2628.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  2629.          substring( @26data, 1, 6 ), substring( @26data, 11, 8 ), @date)
  2630.  
  2631. INSERT_CMDS:
  2632.  
  2633.     if datalength( @data ) > 39
  2634.     begin
  2635.         -- Get the originator_id for the first command 
  2636.         select @cmd_data_len = substring( @data, 34, 2 )
  2637.         select @orig_srv_len = substring( @data, 36, 2 )
  2638.         select @orig_db_len = substring( @data, 38, 2 )
  2639.  
  2640.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2641.         begin 
  2642.             set @originator_id = null 
  2643.             select @originator_id = id from MSrepl_originators where
  2644.                 publisher_database_id = @publisher_database_id 
  2645.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @data, 40 + @cmd_data_len, @orig_srv_len )))
  2646.                 and dbname = substring( @data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2647.             if @originator_id is null
  2648.             begin
  2649.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2650.                     (@publisher_database_id, substring( @data, 40 + @cmd_data_len, @orig_srv_len ), substring( @data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2651.                 select @originator_id = @@identity
  2652.             end
  2653.         end
  2654.         else
  2655.             select @originator_id = 0
  2656.  
  2657.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2658.             substring(@data,11,8),
  2659.             substring(@data,29,4), 
  2660.             substring(@data,21,4), 
  2661.             @originator_id, 
  2662.             substring(@data,25,4), 
  2663.             convert(bit,substring(@data,33,1)), 
  2664.             substring(@data,40,@cmd_data_len) )
  2665.     end
  2666.     
  2667.     IF @1data is null
  2668.       return
  2669.     IF datalength( @1data ) > 39
  2670.     begin
  2671.         -- Get the originator_id for the first command 
  2672.         select @cmd_data_len = substring( @1data, 34, 2 )
  2673.         select @orig_srv_len = substring( @1data, 36, 2 )
  2674.         select @orig_db_len = substring( @1data, 38, 2 )
  2675.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2676.         begin 
  2677.             set @originator_id = null 
  2678.             select @originator_id = id from MSrepl_originators where
  2679.                 publisher_database_id = @publisher_database_id 
  2680.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @1data, 40 + @cmd_data_len, @orig_srv_len )))
  2681.                 and dbname = substring( @1data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2682.             if @originator_id is null
  2683.             begin
  2684.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2685.                     (@publisher_database_id, substring( @1data, 40 + @cmd_data_len, @orig_srv_len ), substring( @1data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2686.                 select @originator_id = @@identity
  2687.             end
  2688.         end
  2689.         else
  2690.             select @originator_id = 0
  2691.  
  2692.         -- Now insert into MSrepl_commands
  2693.  
  2694.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2695.             substring(@1data,11,8),
  2696.             substring(@1data,29,4), 
  2697.             substring(@1data,21,4), 
  2698.             @originator_id, 
  2699.             substring(@1data,25,4), 
  2700.             convert(bit,substring(@1data,33,1)), 
  2701.             substring(@1data,40,@cmd_data_len) )
  2702.     end
  2703.  
  2704.     IF @2data is null
  2705.       return
  2706.     IF datalength( @2data ) > 39
  2707.     begin
  2708.         -- Get the originator_id for the first command 
  2709.         select @cmd_data_len = substring( @2data, 34, 2 )
  2710.         select @orig_srv_len = substring( @2data, 36, 2 )
  2711.         select @orig_db_len = substring( @2data, 38, 2 )
  2712.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2713.         begin 
  2714.             set @originator_id = null 
  2715.             select @originator_id = id from MSrepl_originators where
  2716.                 publisher_database_id = @publisher_database_id 
  2717.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @2data, 40 + @cmd_data_len, @orig_srv_len )))
  2718.                 and dbname = substring( @2data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2719.             if @originator_id is null
  2720.             begin
  2721.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2722.                     (@publisher_database_id, substring( @2data, 40 + @cmd_data_len, @orig_srv_len ), substring( @2data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2723.                 select @originator_id = @@identity
  2724.             end
  2725.         end
  2726.         else
  2727.             select @originator_id = 0
  2728.  
  2729.         -- Now insert into MSrepl_commands
  2730.  
  2731.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2732.             substring(@2data,11 ,8),
  2733.             substring(@2data,29 ,4), 
  2734.             substring(@2data,21 ,4), 
  2735.             @originator_id, 
  2736.             substring(@2data,25 ,4), 
  2737.             convert(bit,substring(@2data,33 ,1)), 
  2738.             substring(@2data,40,@cmd_data_len) )
  2739.     end
  2740.  
  2741.     IF @3data is null
  2742.       return
  2743.     IF datalength( @3data ) > 39
  2744.     begin
  2745.         -- Get the originator_id for the first command 
  2746.         select @cmd_data_len = substring( @3data, 34, 2 )
  2747.         select @orig_srv_len = substring( @3data, 36, 2 )
  2748.         select @orig_db_len = substring( @3data, 38, 2 )
  2749.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2750.         begin 
  2751.             set @originator_id = null 
  2752.             select @originator_id = id from MSrepl_originators where
  2753.                 publisher_database_id = @publisher_database_id 
  2754.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @3data, 40 + @cmd_data_len, @orig_srv_len )))
  2755.                 and dbname = substring( @3data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2756.             if @originator_id is null
  2757.             begin
  2758.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2759.                     (@publisher_database_id, substring( @3data, 40 + @cmd_data_len, @orig_srv_len ), substring( @3data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2760.                 select @originator_id = @@identity
  2761.             end
  2762.         end
  2763.         else
  2764.             select @originator_id = 0
  2765.  
  2766.         -- Now insert into MSrepl_commands
  2767.  
  2768.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2769.             substring(@3data,11 ,8),
  2770.             substring(@3data,29 ,4), 
  2771.             substring(@3data,21 ,4), 
  2772.             @originator_id, 
  2773.             substring(@3data,25 ,4), 
  2774.             convert(bit,substring(@3data,33 ,1)), 
  2775.             substring(@3data,40,@cmd_data_len) )
  2776.     end
  2777.  
  2778.     IF @4data is null
  2779.       return
  2780.     IF datalength( @4data ) > 39
  2781.     begin
  2782.         -- Get the originator_id for the first command 
  2783.         select @cmd_data_len = substring( @4data, 34, 2 )
  2784.         select @orig_srv_len = substring( @4data, 36, 2 )
  2785.         select @orig_db_len = substring( @4data, 38, 2 )
  2786.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2787.         begin 
  2788.             set @originator_id = null 
  2789.             select @originator_id = id from MSrepl_originators where
  2790.                 publisher_database_id = @publisher_database_id 
  2791.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @4data, 40 + @cmd_data_len, @orig_srv_len )))
  2792.                 and dbname = substring( @4data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2793.             if @originator_id is null
  2794.             begin
  2795.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2796.                     (@publisher_database_id, substring( @4data, 40 + @cmd_data_len, @orig_srv_len ), substring( @4data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2797.                 select @originator_id = @@identity
  2798.             end
  2799.         end
  2800.         else
  2801.             select @originator_id = 0
  2802.  
  2803.         -- Now insert into MSrepl_commands
  2804.  
  2805.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2806.             substring(@4data,11 ,8),
  2807.             substring(@4data,29 ,4), 
  2808.             substring(@4data,21 ,4), 
  2809.             @originator_id, 
  2810.             substring(@4data,25 ,4), 
  2811.             convert(bit,substring(@4data,33 ,1)), 
  2812.             substring(@4data,40,@cmd_data_len) )
  2813.     end
  2814.  
  2815.     IF @5data is null
  2816.       return
  2817.     IF datalength( @5data ) > 39
  2818.     begin
  2819.         -- Get the originator_id for the first command 
  2820.         select @cmd_data_len = substring( @5data, 34, 2 )
  2821.         select @orig_srv_len = substring( @5data, 36, 2 )
  2822.         select @orig_db_len = substring( @5data, 38, 2 )
  2823.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2824.         begin 
  2825.             set @originator_id = null 
  2826.             select @originator_id = id from MSrepl_originators where
  2827.                 publisher_database_id = @publisher_database_id 
  2828.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @5data, 40 + @cmd_data_len, @orig_srv_len )))
  2829.                 and dbname = substring( @5data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2830.             if @originator_id is null
  2831.             begin
  2832.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2833.                     (@publisher_database_id, substring( @5data, 40 + @cmd_data_len, @orig_srv_len ), substring( @5data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2834.                 select @originator_id = @@identity
  2835.             end
  2836.         end
  2837.         else
  2838.             select @originator_id = 0
  2839.  
  2840.         -- Now insert into MSrepl_commands
  2841.  
  2842.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2843.             substring(@5data,11 ,8),
  2844.             substring(@5data,29 ,4), 
  2845.             substring(@5data,21 ,4), 
  2846.             @originator_id, 
  2847.             substring(@5data,25 ,4), 
  2848.             convert(bit,substring(@5data,33 ,1)), 
  2849.             substring(@5data,40,@cmd_data_len) )
  2850.     end
  2851.  
  2852.     IF @6data is null
  2853.       return
  2854.     IF datalength( @6data ) > 39
  2855.     begin
  2856.         -- Get the originator_id for the first command 
  2857.         select @cmd_data_len = substring( @6data, 34, 2 )
  2858.         select @orig_srv_len = substring( @6data, 36, 2 )
  2859.         select @orig_db_len = substring( @6data, 38, 2 )
  2860.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2861.         begin 
  2862.             set @originator_id = null 
  2863.             select @originator_id = id from MSrepl_originators where
  2864.                 publisher_database_id = @publisher_database_id 
  2865.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @6data, 40 + @cmd_data_len, @orig_srv_len )))
  2866.                 and dbname = substring( @6data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2867.             if @originator_id is null
  2868.             begin
  2869.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2870.                     (@publisher_database_id, substring( @6data, 40 + @cmd_data_len, @orig_srv_len ), substring( @6data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2871.                 select @originator_id = @@identity
  2872.             end
  2873.         end
  2874.         else
  2875.             select @originator_id = 0
  2876.  
  2877.         -- Now insert into MSrepl_commands
  2878.  
  2879.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2880.             substring(@6data,11 ,8),
  2881.             substring(@6data,29 ,4), 
  2882.             substring(@6data,21 ,4), 
  2883.             @originator_id, 
  2884.             substring(@6data,25 ,4), 
  2885.             convert(bit,substring(@6data,33 ,1)), 
  2886.             substring(@6data,40,@cmd_data_len) )
  2887.     end
  2888.  
  2889.     IF @7data is null
  2890.       return
  2891.     IF datalength( @7data ) > 39
  2892.     begin
  2893.         -- Get the originator_id for the first command 
  2894.         select @cmd_data_len = substring( @7data, 34, 2 )
  2895.         select @orig_srv_len = substring( @7data, 36, 2 )
  2896.         select @orig_db_len = substring( @7data, 38, 2 )
  2897.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2898.         begin 
  2899.             set @originator_id = null 
  2900.             select @originator_id = id from MSrepl_originators where
  2901.                 publisher_database_id = @publisher_database_id 
  2902.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @7data, 40 + @cmd_data_len, @orig_srv_len )))
  2903.                 and dbname = substring( @7data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2904.             if @originator_id is null
  2905.             begin
  2906.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2907.                     (@publisher_database_id, substring( @7data, 40 + @cmd_data_len, @orig_srv_len ), substring( @7data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2908.                 select @originator_id = @@identity
  2909.             end
  2910.         end
  2911.         else
  2912.             select @originator_id = 0
  2913.  
  2914.         -- Now insert into MSrepl_commands
  2915.  
  2916.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2917.             substring(@7data,11 ,8),
  2918.             substring(@7data,29 ,4), 
  2919.             substring(@7data,21 ,4), 
  2920.             @originator_id, 
  2921.             substring(@7data,25 ,4), 
  2922.             convert(bit,substring(@7data,33 ,1)), 
  2923.             substring(@7data,40,@cmd_data_len) )
  2924.     end
  2925.  
  2926.     IF @8data is null
  2927.       return
  2928.     IF datalength( @8data ) > 39
  2929.     begin
  2930.         -- Get the originator_id for the first command 
  2931.         select @cmd_data_len = substring( @8data, 34, 2 )
  2932.         select @orig_srv_len = substring( @8data, 36, 2 )
  2933.         select @orig_db_len = substring( @8data, 38, 2 )
  2934.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2935.         begin 
  2936.             set @originator_id = null 
  2937.             select @originator_id = id from MSrepl_originators where
  2938.                 publisher_database_id = @publisher_database_id 
  2939.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @8data, 40 + @cmd_data_len, @orig_srv_len )))
  2940.                 and dbname = substring( @8data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2941.             if @originator_id is null
  2942.             begin
  2943.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2944.                     (@publisher_database_id, substring( @8data, 40 + @cmd_data_len, @orig_srv_len ), substring( @8data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2945.                 select @originator_id = @@identity
  2946.             end
  2947.         end
  2948.         else
  2949.             select @originator_id = 0
  2950.  
  2951.         -- Now insert into MSrepl_commands
  2952.  
  2953.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2954.             substring(@8data,11 ,8),
  2955.             substring(@8data,29 ,4), 
  2956.             substring(@8data,21 ,4), 
  2957.             @originator_id, 
  2958.             substring(@8data,25 ,4), 
  2959.             convert(bit,substring(@8data,33 ,1)), 
  2960.             substring(@8data,40,@cmd_data_len) )
  2961.     end
  2962.  
  2963.     IF @9data is null
  2964.       return
  2965.     IF datalength( @9data ) > 39
  2966.     begin
  2967.         -- Get the originator_id for the first command 
  2968.         select @cmd_data_len = substring( @9data, 34, 2 )
  2969.         select @orig_srv_len = substring( @9data, 36, 2 )
  2970.         select @orig_db_len = substring( @9data, 38, 2 )
  2971.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  2972.         begin 
  2973.             set @originator_id = null 
  2974.             select @originator_id = id from MSrepl_originators where
  2975.                 publisher_database_id = @publisher_database_id 
  2976.                 and UPPER(srvname) = UPPER(convert(sysname, substring( @9data, 40 + @cmd_data_len, @orig_srv_len )))
  2977.                 and dbname = substring( @9data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  2978.             if @originator_id is null
  2979.             begin
  2980.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  2981.                     (@publisher_database_id, substring( @9data, 40 + @cmd_data_len, @orig_srv_len ), substring( @9data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  2982.                 select @originator_id = @@identity
  2983.             end
  2984.         end
  2985.         else
  2986.             select @originator_id = 0
  2987.  
  2988.         -- Now insert into MSrepl_commands
  2989.  
  2990.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  2991.             substring(@9data,11 ,8),
  2992.             substring(@9data,29 ,4), 
  2993.             substring(@9data,21 ,4), 
  2994.             @originator_id, 
  2995.             substring(@9data,25 ,4), 
  2996.             convert(bit,substring(@9data,33 ,1)), 
  2997.             substring(@9data,40,@cmd_data_len) )
  2998.     end
  2999.  
  3000.     IF @10data is null
  3001.       return
  3002.     IF datalength( @10data ) > 39
  3003.     begin
  3004.         -- Get the originator_id for the first command 
  3005.         select @cmd_data_len = substring( @10data, 34, 2 )
  3006.         select @orig_srv_len = substring( @10data, 36, 2 )
  3007.         select @orig_db_len = substring( @10data, 38, 2 )
  3008.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3009.         begin 
  3010.             set @originator_id = null 
  3011.             select @originator_id = id from MSrepl_originators where
  3012.                 publisher_database_id = @publisher_database_id 
  3013.                 and UPPER(srvname) = upper(convert(sysname, substring( @10data, 40 + @cmd_data_len, @orig_srv_len )))
  3014.                 and dbname = substring( @10data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3015.             if @originator_id is null
  3016.             begin
  3017.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3018.                     (@publisher_database_id, substring( @10data, 40 + @cmd_data_len, @orig_srv_len ), substring( @10data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3019.                 select @originator_id = @@identity
  3020.             end
  3021.         end
  3022.         else
  3023.             select @originator_id = 0
  3024.  
  3025.         -- Now insert into MSrepl_commands
  3026.  
  3027.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3028.             substring(@10data,11 ,8),
  3029.             substring(@10data,29 ,4), 
  3030.             substring(@10data,21 ,4), 
  3031.             @originator_id, 
  3032.             substring(@10data,25 ,4), 
  3033.             convert(bit,substring(@10data,33 ,1)), 
  3034.             substring(@10data,40,@cmd_data_len) )
  3035.     end
  3036.  
  3037.     IF @11data is null
  3038.       return
  3039.     IF datalength( @11data ) > 39
  3040.     begin
  3041.         -- Get the originator_id for the first command 
  3042.         select @cmd_data_len = substring( @11data, 34, 2 )
  3043.         select @orig_srv_len = substring( @11data, 36, 2 )
  3044.         select @orig_db_len = substring( @11data, 38, 2 )
  3045.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3046.         begin 
  3047.             set @originator_id = null 
  3048.             select @originator_id = id from MSrepl_originators where
  3049.                 publisher_database_id = @publisher_database_id 
  3050.                 and UPPER(srvname) = upper(convert(sysname, substring( @11data, 40 + @cmd_data_len, @orig_srv_len )))
  3051.                 and dbname = substring( @11data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3052.             if @originator_id is null
  3053.             begin
  3054.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3055.                     (@publisher_database_id, substring( @11data, 40 + @cmd_data_len, @orig_srv_len ), substring( @11data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3056.                 select @originator_id = @@identity
  3057.             end
  3058.         end
  3059.         else
  3060.             select @originator_id = 0
  3061.  
  3062.         -- Now insert into MSrepl_commands
  3063.  
  3064.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3065.             substring(@11data,11 ,8),
  3066.             substring(@11data,29 ,4), 
  3067.             substring(@11data,21 ,4), 
  3068.             @originator_id, 
  3069.             substring(@11data,25 ,4), 
  3070.             convert(bit,substring(@11data,33 ,1)), 
  3071.             substring(@11data,40,@cmd_data_len) )
  3072.     end
  3073.  
  3074.     IF @12data is null
  3075.       return
  3076.     IF datalength( @12data ) > 39
  3077.     begin
  3078.         -- Get the originator_id for the first command 
  3079.         select @cmd_data_len = substring( @12data, 34, 2 )
  3080.         select @orig_srv_len = substring( @12data, 36, 2 )
  3081.         select @orig_db_len = substring( @12data, 38, 2 )
  3082.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3083.         begin 
  3084.             set @originator_id = null 
  3085.             select @originator_id = id from MSrepl_originators where
  3086.                 publisher_database_id = @publisher_database_id 
  3087.                 and UPPER(srvname) = upper(convert(sysname, substring( @12data, 40 + @cmd_data_len, @orig_srv_len )))
  3088.                 and dbname = substring( @12data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3089.             if @originator_id is null
  3090.             begin
  3091.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3092.                     (@publisher_database_id, substring( @12data, 40 + @cmd_data_len, @orig_srv_len ), substring( @12data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3093.                 select @originator_id = @@identity
  3094.             end
  3095.         end
  3096.         else
  3097.             select @originator_id = 0
  3098.  
  3099.         -- Now insert into MSrepl_commands
  3100.  
  3101.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3102.             substring(@12data,11 ,8),
  3103.             substring(@12data,29 ,4), 
  3104.             substring(@12data,21 ,4), 
  3105.             @originator_id, 
  3106.             substring(@12data,25 ,4), 
  3107.             convert(bit,substring(@12data,33 ,1)), 
  3108.             substring(@12data,40,@cmd_data_len) )
  3109.     end
  3110.  
  3111.  
  3112.     IF @13data is null
  3113.       return
  3114.     IF datalength( @13data ) > 39
  3115.     begin
  3116.         -- Get the originator_id for the first command 
  3117.         select @cmd_data_len = substring( @13data, 34, 2 )
  3118.         select @orig_srv_len = substring( @13data, 36, 2 )
  3119.         select @orig_db_len = substring( @13data, 38, 2 )
  3120.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3121.         begin 
  3122.             set @originator_id = null 
  3123.             select @originator_id = id from MSrepl_originators where
  3124.                 publisher_database_id = @publisher_database_id 
  3125.                 and UPPER(srvname) = upper(convert(sysname, substring( @13data, 40 + @cmd_data_len, @orig_srv_len )))
  3126.                 and dbname = substring( @13data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3127.             if @originator_id is null
  3128.             begin
  3129.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3130.                     (@publisher_database_id, substring( @13data, 40 + @cmd_data_len, @orig_srv_len ), substring( @13data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3131.                 select @originator_id = @@identity
  3132.             end
  3133.         end
  3134.         else
  3135.             select @originator_id = 0
  3136.  
  3137.         -- Now insert into MSrepl_commands
  3138.  
  3139.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3140.             substring(@13data,11 ,8),
  3141.             substring(@13data,29 ,4), 
  3142.             substring(@13data,21 ,4), 
  3143.             @originator_id, 
  3144.             substring(@13data,25 ,4), 
  3145.             convert(bit,substring(@13data,33 ,1)), 
  3146.             substring(@13data,40,@cmd_data_len) )
  3147.     end
  3148.  
  3149.     IF @14data is null
  3150.       return
  3151.     IF datalength( @14data ) > 39
  3152.     begin
  3153.         -- Get the originator_id for the first command 
  3154.         select @cmd_data_len = substring( @14data, 34, 2 )
  3155.         select @orig_srv_len = substring( @14data, 36, 2 )
  3156.         select @orig_db_len = substring( @14data, 38, 2 )
  3157.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3158.         begin 
  3159.             set @originator_id = null 
  3160.             select @originator_id = id from MSrepl_originators where
  3161.                 publisher_database_id = @publisher_database_id 
  3162.                 and UPPER(srvname) = upper(convert(sysname, substring( @14data, 40 + @cmd_data_len, @orig_srv_len )))
  3163.                 and dbname = substring( @14data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3164.             if @originator_id is null
  3165.             begin
  3166.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3167.                     (@publisher_database_id, substring( @14data, 40 + @cmd_data_len, @orig_srv_len ), substring( @14data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3168.                 select @originator_id = @@identity
  3169.             end
  3170.         end
  3171.         else
  3172.             select @originator_id = 0
  3173.  
  3174.         -- Now insert into MSrepl_commands
  3175.  
  3176.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3177.             substring(@14data,11 ,8),
  3178.             substring(@14data,29 ,4), 
  3179.             substring(@14data,21 ,4), 
  3180.             @originator_id, 
  3181.             substring(@14data,25 ,4), 
  3182.             convert(bit,substring(@14data,33 ,1)), 
  3183.             substring(@14data,40,@cmd_data_len) )
  3184.     end
  3185.  
  3186.  
  3187.     IF @15data is null
  3188.       return
  3189.     IF datalength( @15data ) > 39
  3190.     begin
  3191.         -- Get the originator_id for the first command 
  3192.         select @cmd_data_len = substring( @15data, 34, 2 )
  3193.         select @orig_srv_len = substring( @15data, 36, 2 )
  3194.         select @orig_db_len = substring( @15data, 38, 2 )
  3195.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3196.         begin 
  3197.             set @originator_id = null 
  3198.             select @originator_id = id from MSrepl_originators where
  3199.                 publisher_database_id = @publisher_database_id 
  3200.                 and UPPER(srvname) = upper(convert(sysname, substring( @15data, 40 + @cmd_data_len, @orig_srv_len )))
  3201.                 and dbname = substring( @15data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3202.             if @originator_id is null
  3203.             begin
  3204.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3205.                     (@publisher_database_id, substring( @15data, 40 + @cmd_data_len, @orig_srv_len ), substring( @15data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3206.                 select @originator_id = @@identity
  3207.             end
  3208.         end
  3209.         else
  3210.             select @originator_id = 0
  3211.  
  3212.         -- Now insert into MSrepl_commands
  3213.  
  3214.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3215.             substring(@15data,11 ,8),
  3216.             substring(@15data,29 ,4), 
  3217.             substring(@15data,21 ,4), 
  3218.             @originator_id, 
  3219.             substring(@15data,25 ,4), 
  3220.             convert(bit,substring(@15data,33 ,1)), 
  3221.             substring(@15data,40,@cmd_data_len) )
  3222.     end
  3223.  
  3224.     IF @16data is null
  3225.       return
  3226.     IF datalength( @16data ) > 39
  3227.     begin
  3228.         -- Get the originator_id for the first command 
  3229.         select @cmd_data_len = substring( @16data, 34, 2 )
  3230.         select @orig_srv_len = substring( @16data, 36, 2 )
  3231.         select @orig_db_len = substring( @16data, 38, 2 )
  3232.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3233.         begin 
  3234.             set @originator_id = null 
  3235.             select @originator_id = id from MSrepl_originators where
  3236.                 publisher_database_id = @publisher_database_id 
  3237.                 and UPPER(srvname) = upper(convert(sysname, substring( @16data, 40 + @cmd_data_len, @orig_srv_len )))
  3238.                 and dbname = substring( @16data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3239.             if @originator_id is null
  3240.             begin
  3241.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3242.                     (@publisher_database_id, substring( @16data, 40 + @cmd_data_len, @orig_srv_len ), substring( @16data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3243.                 select @originator_id = @@identity
  3244.             end
  3245.         end
  3246.         else
  3247.             select @originator_id = 0
  3248.  
  3249.         -- Now insert into MSrepl_commands
  3250.  
  3251.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3252.             substring(@16data,11 ,8),
  3253.             substring(@16data,29 ,4), 
  3254.             substring(@16data,21 ,4), 
  3255.             @originator_id, 
  3256.             substring(@16data,25 ,4), 
  3257.             convert(bit,substring(@16data,33 ,1)), 
  3258.             substring(@16data,40,@cmd_data_len) )
  3259.     end
  3260.  
  3261.  
  3262.     IF @17data is null
  3263.       return
  3264.     IF datalength( @17data ) > 39
  3265.     begin
  3266.         -- Get the originator_id for the first command 
  3267.         select @cmd_data_len = substring( @17data, 34, 2 )
  3268.         select @orig_srv_len = substring( @17data, 36, 2 )
  3269.         select @orig_db_len = substring( @17data, 38, 2 )
  3270.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3271.         begin 
  3272.             set @originator_id = null 
  3273.             select @originator_id = id from MSrepl_originators where
  3274.                 publisher_database_id = @publisher_database_id 
  3275.                 and UPPER(srvname) = upper(convert(sysname, substring( @17data, 40 + @cmd_data_len, @orig_srv_len )))
  3276.                 and dbname = substring( @17data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3277.             if @originator_id is null
  3278.             begin
  3279.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3280.                     (@publisher_database_id, substring( @17data, 40 + @cmd_data_len, @orig_srv_len ), substring( @17data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3281.                 select @originator_id = @@identity
  3282.             end
  3283.         end
  3284.         else
  3285.             select @originator_id = 0
  3286.  
  3287.         -- Now insert into MSrepl_commands
  3288.  
  3289.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3290.             substring(@17data,11 ,8),
  3291.             substring(@17data,29 ,4), 
  3292.             substring(@17data,21 ,4), 
  3293.             @originator_id, 
  3294.             substring(@17data,25 ,4), 
  3295.             convert(bit,substring(@17data,33 ,1)), 
  3296.             substring(@17data,40,@cmd_data_len) )
  3297.     end
  3298.  
  3299.  
  3300.     IF @18data is null
  3301.       return
  3302.     IF datalength( @18data ) > 39
  3303.     begin
  3304.         -- Get the originator_id for the first command 
  3305.         select @cmd_data_len = substring( @18data, 34, 2 )
  3306.         select @orig_srv_len = substring( @18data, 36, 2 )
  3307.         select @orig_db_len = substring( @18data, 38, 2 )
  3308.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3309.         begin 
  3310.             set @originator_id = null 
  3311.             select @originator_id = id from MSrepl_originators where
  3312.                 publisher_database_id = @publisher_database_id 
  3313.                 and UPPER(srvname) = upper(convert(sysname, substring( @18data, 40 + @cmd_data_len, @orig_srv_len )))
  3314.                 and dbname = substring( @18data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3315.             if @originator_id is null
  3316.             begin
  3317.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3318.                     (@publisher_database_id, substring( @18data, 40 + @cmd_data_len, @orig_srv_len ), substring( @18data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3319.                 select @originator_id = @@identity
  3320.             end
  3321.         end
  3322.         else
  3323.             select @originator_id = 0
  3324.  
  3325.         -- Now insert into MSrepl_commands
  3326.  
  3327.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3328.             substring(@18data,11 ,8),
  3329.             substring(@18data,29 ,4), 
  3330.             substring(@18data,21 ,4), 
  3331.             @originator_id, 
  3332.             substring(@18data,25 ,4), 
  3333.             convert(bit,substring(@18data,33 ,1)), 
  3334.             substring(@18data,40,@cmd_data_len) )
  3335.     end
  3336.  
  3337.  
  3338.     IF @19data is null
  3339.       return
  3340.     IF datalength( @19data ) > 39
  3341.     begin
  3342.         -- Get the originator_id for the first command 
  3343.         select @cmd_data_len = substring( @19data, 34, 2 )
  3344.         select @orig_srv_len = substring( @19data, 36, 2 )
  3345.         select @orig_db_len = substring( @19data, 38, 2 )
  3346.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3347.         begin 
  3348.             set @originator_id = null 
  3349.             select @originator_id = id from MSrepl_originators where
  3350.                 publisher_database_id = @publisher_database_id 
  3351.                 and UPPER(srvname) = upper(convert(sysname, substring( @19data, 40 + @cmd_data_len, @orig_srv_len )))
  3352.                 and dbname = substring( @19data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3353.             if @originator_id is null
  3354.             begin
  3355.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3356.                     (@publisher_database_id, substring( @19data, 40 + @cmd_data_len, @orig_srv_len ), substring( @19data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3357.                 select @originator_id = @@identity
  3358.             end
  3359.         end
  3360.         else
  3361.             select @originator_id = 0
  3362.  
  3363.         -- Now insert into MSrepl_commands
  3364.  
  3365.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3366.             substring(@19data,11 ,8),
  3367.             substring(@19data,29 ,4), 
  3368.             substring(@19data,21 ,4), 
  3369.             @originator_id, 
  3370.             substring(@19data,25 ,4), 
  3371.             convert(bit,substring(@19data,33 ,1)), 
  3372.             substring(@19data,40,@cmd_data_len) )
  3373.     end
  3374.  
  3375.  
  3376.     IF @20data is null
  3377.       return
  3378.     IF datalength( @20data ) > 39
  3379.     begin
  3380.         -- Get the originator_id for the first command 
  3381.         select @cmd_data_len = substring( @20data, 34, 2 )
  3382.         select @orig_srv_len = substring( @20data, 36, 2 )
  3383.         select @orig_db_len = substring( @20data, 38, 2 )
  3384.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3385.         begin 
  3386.             set @originator_id = null 
  3387.             select @originator_id = id from MSrepl_originators where
  3388.                 publisher_database_id = @publisher_database_id 
  3389.                 and UPPER(srvname) = upper(convert(sysname, substring( @20data, 40 + @cmd_data_len, @orig_srv_len )))
  3390.                 and dbname = substring( @20data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3391.             if @originator_id is null
  3392.             begin
  3393.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3394.                     (@publisher_database_id, substring( @20data, 40 + @cmd_data_len, @orig_srv_len ), substring( @20data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3395.                 select @originator_id = @@identity
  3396.             end
  3397.         end
  3398.         else
  3399.             select @originator_id = 0
  3400.  
  3401.         -- Now insert into MSrepl_commands
  3402.  
  3403.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3404.             substring(@20data,11 ,8),
  3405.             substring(@20data,29 ,4), 
  3406.             substring(@20data,21 ,4), 
  3407.             @originator_id, 
  3408.             substring(@20data,25 ,4), 
  3409.             convert(bit,substring(@20data,33 ,1)), 
  3410.             substring(@20data,40,@cmd_data_len) )
  3411.     end
  3412.  
  3413.     IF @21data is null
  3414.       return
  3415.     IF datalength( @21data ) > 39
  3416.     begin
  3417.         -- Get the originator_id for the first command 
  3418.         select @cmd_data_len = substring( @21data, 34, 2 )
  3419.         select @orig_srv_len = substring( @21data, 36, 2 )
  3420.         select @orig_db_len = substring( @21data, 38, 2 )
  3421.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3422.         begin 
  3423.             set @originator_id = null 
  3424.             select @originator_id = id from MSrepl_originators where
  3425.                 publisher_database_id = @publisher_database_id 
  3426.                 and UPPER(srvname) = upper(convert(sysname, substring( @21data, 40 + @cmd_data_len, @orig_srv_len )))
  3427.                 and dbname = substring( @21data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3428.             if @originator_id is null
  3429.             begin
  3430.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3431.                     (@publisher_database_id, substring( @21data, 40 + @cmd_data_len, @orig_srv_len ), substring( @21data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3432.                 select @originator_id = @@identity
  3433.             end
  3434.         end
  3435.         else
  3436.             select @originator_id = 0
  3437.  
  3438.         -- Now insert into MSrepl_commands
  3439.  
  3440.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3441.             substring(@21data,11 ,8),
  3442.             substring(@21data,29 ,4), 
  3443.             substring(@21data,21 ,4), 
  3444.             @originator_id, 
  3445.             substring(@21data,25 ,4), 
  3446.             convert(bit,substring(@21data,33 ,1)), 
  3447.             substring(@21data,40,@cmd_data_len) )
  3448.     end
  3449.  
  3450.     IF @22data is null
  3451.       return
  3452.     IF datalength( @22data ) > 39
  3453.     begin
  3454.         -- Get the originator_id for the first command 
  3455.         select @cmd_data_len = substring( @22data, 34, 2 )
  3456.         select @orig_srv_len = substring( @22data, 36, 2 )
  3457.         select @orig_db_len = substring( @22data, 38, 2 )
  3458.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3459.         begin 
  3460.             set @originator_id = null 
  3461.             select @originator_id = id from MSrepl_originators where
  3462.                 publisher_database_id = @publisher_database_id 
  3463.                 and UPPER(srvname) = upper(convert(sysname, substring( @22data, 40 + @cmd_data_len, @orig_srv_len )))
  3464.                 and dbname = substring( @22data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3465.             if @originator_id is null
  3466.             begin
  3467.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3468.                     (@publisher_database_id, substring( @22data, 40 + @cmd_data_len, @orig_srv_len ), substring( @22data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3469.                 select @originator_id = @@identity
  3470.             end
  3471.         end
  3472.         else
  3473.             select @originator_id = 0
  3474.  
  3475.         -- Now insert into MSrepl_commands
  3476.  
  3477.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3478.             substring(@22data,11 ,8),
  3479.             substring(@22data,29 ,4), 
  3480.             substring(@22data,21 ,4), 
  3481.             @originator_id, 
  3482.             substring(@22data,25 ,4), 
  3483.             convert(bit,substring(@22data,33 ,1)), 
  3484.             substring(@22data,40,@cmd_data_len) )
  3485.     end
  3486.  
  3487.     IF @23data is null
  3488.       return
  3489.     IF datalength( @23data ) > 39
  3490.     begin
  3491.         -- Get the originator_id for the first command 
  3492.         select @cmd_data_len = substring( @23data, 34, 2 )
  3493.         select @orig_srv_len = substring( @23data, 36, 2 )
  3494.         select @orig_db_len = substring( @23data, 38, 2 )
  3495.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3496.         begin 
  3497.             set @originator_id = null 
  3498.             select @originator_id = id from MSrepl_originators where
  3499.                 publisher_database_id = @publisher_database_id 
  3500.                 and UPPER(srvname) = upper(convert(sysname, substring( @23data, 40 + @cmd_data_len, @orig_srv_len )))
  3501.                 and dbname = substring( @23data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3502.             if @originator_id is null
  3503.             begin
  3504.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3505.                     (@publisher_database_id, substring( @23data, 40 + @cmd_data_len, @orig_srv_len ), substring( @23data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3506.                 select @originator_id = @@identity
  3507.             end
  3508.         end
  3509.         else
  3510.             select @originator_id = 0
  3511.  
  3512.         -- Now insert into MSrepl_commands
  3513.  
  3514.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3515.             substring(@23data,11 ,8),
  3516.             substring(@23data,29 ,4), 
  3517.             substring(@23data,21 ,4), 
  3518.             @originator_id, 
  3519.             substring(@23data,25 ,4), 
  3520.             convert(bit,substring(@23data,33 ,1)), 
  3521.             substring(@23data,40,@cmd_data_len) )
  3522.     end
  3523.  
  3524.     IF @24data is null
  3525.       return
  3526.     IF datalength( @24data ) > 39
  3527.     begin
  3528.         -- Get the originator_id for the first command 
  3529.         select @cmd_data_len = substring( @24data, 34, 2 )
  3530.         select @orig_srv_len = substring( @24data, 36, 2 )
  3531.         select @orig_db_len = substring( @24data, 38, 2 )
  3532.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3533.         begin 
  3534.             set @originator_id = null 
  3535.             select @originator_id = id from MSrepl_originators where
  3536.                 publisher_database_id = @publisher_database_id 
  3537.                 and UPPER(srvname) = upper(convert(sysname, substring( @24data, 40 + @cmd_data_len, @orig_srv_len )))
  3538.                 and dbname = substring( @24data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3539.             if @originator_id is null
  3540.             begin
  3541.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3542.                     (@publisher_database_id, substring( @24data, 40 + @cmd_data_len, @orig_srv_len ), substring( @24data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3543.                 select @originator_id = @@identity
  3544.             end
  3545.         end
  3546.         else
  3547.             select @originator_id = 0
  3548.  
  3549.         -- Now insert into MSrepl_commands
  3550.  
  3551.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3552.             substring(@24data,11 ,8),
  3553.             substring(@24data,29 ,4), 
  3554.             substring(@24data,21 ,4), 
  3555.             @originator_id, 
  3556.             substring(@24data,25 ,4), 
  3557.             convert(bit,substring(@24data,33 ,1)), 
  3558.             substring(@24data,40,@cmd_data_len) )
  3559.     end
  3560.  
  3561.  
  3562.     IF @25data is null
  3563.       return
  3564.     IF datalength( @25data ) > 39
  3565.     begin
  3566.         -- Get the originator_id for the first command 
  3567.         select @cmd_data_len = substring( @25data, 34, 2 )
  3568.         select @orig_srv_len = substring( @25data, 36, 2 )
  3569.         select @orig_db_len = substring( @25data, 38, 2 )
  3570.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3571.         begin 
  3572.             set @originator_id = null 
  3573.             select @originator_id = id from MSrepl_originators where
  3574.                 publisher_database_id = @publisher_database_id 
  3575.                 and UPPER(srvname) = upper(convert(sysname, substring( @25data, 40 + @cmd_data_len, @orig_srv_len )))
  3576.                 and dbname = substring( @25data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3577.             if @originator_id is null
  3578.             begin
  3579.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3580.                     (@publisher_database_id, substring( @25data, 40 + @cmd_data_len, @orig_srv_len ), substring( @25data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3581.                 select @originator_id = @@identity
  3582.             end
  3583.         end
  3584.         else
  3585.             select @originator_id = 0
  3586.  
  3587.         -- Now insert into MSrepl_commands
  3588.  
  3589.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3590.             substring(@25data,11 ,8),
  3591.             substring(@25data,29 ,4), 
  3592.             substring(@25data,21 ,4), 
  3593.             @originator_id, 
  3594.             substring(@25data,25 ,4), 
  3595.             convert(bit,substring(@25data,33 ,1)), 
  3596.             substring(@25data,40,@cmd_data_len) )
  3597.     end
  3598.  
  3599.  
  3600.     IF @26data is null
  3601.       return
  3602.     IF datalength( @26data ) > 39
  3603.     begin
  3604.         -- Get the originator_id for the first command 
  3605.         select @cmd_data_len = substring( @26data, 34, 2 )
  3606.         select @orig_srv_len = substring( @26data, 36, 2 )
  3607.         select @orig_db_len = substring( @26data, 38, 2 )
  3608.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3609.         begin 
  3610.             set @originator_id = null 
  3611.             select @originator_id = id from MSrepl_originators where
  3612.                 publisher_database_id = @publisher_database_id 
  3613.                 and UPPER(srvname) = upper(convert(sysname, substring( @26data, 40 + @cmd_data_len, @orig_srv_len )))
  3614.                 and dbname = substring( @26data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3615.             if @originator_id is null
  3616.             begin
  3617.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3618.                     (@publisher_database_id, substring( @26data, 40 + @cmd_data_len, @orig_srv_len ), substring( @26data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3619.                 select @originator_id = @@identity
  3620.             end
  3621.         end
  3622.         else
  3623.             select @originator_id = 0
  3624.  
  3625.         -- Now insert into MSrepl_commands
  3626.  
  3627.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3628.             substring(@26data,11 ,8),
  3629.             substring(@26data,29 ,4), 
  3630.             substring(@26data,21 ,4), 
  3631.             @originator_id, 
  3632.             substring(@26data,25 ,4), 
  3633.             convert(bit,substring(@26data,33 ,1)), 
  3634.             substring(@26data,40,@cmd_data_len) )
  3635.     end
  3636.  
  3637.  
  3638.     IF @@ERROR <> 0
  3639.       return (1)
  3640. GO
  3641. raiserror(15339,-1,-1,'sp_MSadd_repl_commands27hp')
  3642. GO
  3643. CREATE PROCEDURE sp_MSadd_repl_commands27hp
  3644. @publisher_id smallint,
  3645. @publisher_db sysname,
  3646. @data varbinary( 1575 ),
  3647. @1data varbinary(1575) = NULL,
  3648. @2data varbinary(1575) = NULL,
  3649. @3data varbinary(1575) = NULL,
  3650. @4data varbinary(1575) = NULL,
  3651. @5data varbinary(1575) = NULL,
  3652. @6data varbinary(1575) = NULL,
  3653. @7data varbinary(1575) = NULL,
  3654. @8data varbinary(1575) = NULL,
  3655. @9data varbinary(1575) = NULL,
  3656. @10data varbinary(1575) = NULL,
  3657. @11data varbinary(1575) = NULL,
  3658. @12data varbinary(1575) = NULL,
  3659. @13data varbinary(1575) = NULL,
  3660. @14data varbinary(1575) = NULL,
  3661. @15data varbinary(1575) = NULL,
  3662. @16data varbinary(1575) = NULL,
  3663. @17data varbinary(1575) = NULL,
  3664. @18data varbinary(1575) = NULL,
  3665. @19data varbinary(1575) = NULL,
  3666. @20data varbinary(1575) = NULL,
  3667. @21data varbinary(1575) = NULL,
  3668. @22data varbinary(1575) = NULL,
  3669. @23data varbinary(1575) = NULL,
  3670. @24data varbinary(1575) = NULL,
  3671. @25data varbinary(1575) = NULL,
  3672. @26data varbinary(1575) = NULL
  3673. AS
  3674.  
  3675.     SET NOCOUNT ON
  3676.  
  3677.     DECLARE @xact_id    varbinary(10)
  3678.     DECLARE @xact_seqno varbinary(10)
  3679.     DECLARE @artid      int
  3680.     DECLARE @command_id int
  3681.     DECLARE @cmd_type   int
  3682.     DECLARE @partial_command bit
  3683.     DECLARE @command    varbinary(1024)
  3684.  
  3685.     DECLARE @originator sysname
  3686.     DECLARE @originator_db sysname
  3687.  
  3688.     DECLARE @publisher_database_id int
  3689.     DECLARE @date datetime
  3690.     declare @originator_id int
  3691.  
  3692.     DECLARE @cmd_data_len  smallint
  3693.     DECLARE @orig_srv_len smallint
  3694.     DECLARE @orig_db_len  smallint
  3695.  
  3696.     SELECT @date = GETDATE()
  3697.  
  3698.     -- Get publisher database id.
  3699.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  3700.         publisher_db = @publisher_db
  3701.  
  3702.     -- First insert into MS_repl_transactions
  3703.     IF convert( int, substring( @data, 25, 4 ) ) = 1
  3704.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3705.          substring( @data, 1, 10 ), substring( @data, 11, 10 ), @date)
  3706.  
  3707.     IF @1data is null
  3708.       goto INSERT_CMDS
  3709.     IF convert( int, substring( @1data, 25, 4 ) ) = 1
  3710.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3711.          substring( @1data, 1, 10 ), substring( @1data, 11, 10 ), @date)
  3712.  
  3713.     IF @2data is null
  3714.       goto INSERT_CMDS
  3715.     IF convert( int, substring( @2data, 25, 4 ) ) = 1
  3716.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3717.          substring( @2data, 1, 10 ), substring( @2data, 11, 10 ), @date)
  3718.     
  3719.     IF @3data is null
  3720.       goto INSERT_CMDS
  3721.     IF convert( int, substring( @3data, 25, 4 ) ) = 1
  3722.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3723.          substring( @3data, 1, 10 ), substring( @3data, 11, 10 ), @date)
  3724.  
  3725.     IF @4data is null
  3726.       goto INSERT_CMDS
  3727.     IF convert( int, substring( @4data, 25, 4 ) ) = 1
  3728.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3729.          substring( @4data, 1, 10 ), substring( @4data, 11, 10 ), @date)
  3730.  
  3731.     IF @5data is null
  3732.       goto INSERT_CMDS
  3733.     IF convert( int, substring( @5data, 25, 4 ) ) = 1
  3734.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3735.          substring( @5data, 1, 10 ), substring( @5data, 11, 10 ), @date)
  3736.  
  3737.     IF @6data is null
  3738.       goto INSERT_CMDS
  3739.     IF convert( int, substring( @6data, 25, 4 ) ) = 1
  3740.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3741.          substring( @6data, 1, 10 ), substring( @6data, 11, 10 ), @date)
  3742.  
  3743.     IF @7data is null
  3744.       goto INSERT_CMDS
  3745.     IF convert( int, substring( @7data, 25, 4 ) ) = 1
  3746.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3747.          substring( @7data, 1, 10 ), substring( @7data, 11, 10 ), @date)
  3748.  
  3749.     IF @8data is null
  3750.       goto INSERT_CMDS
  3751.     IF convert( int, substring( @8data, 25, 4 ) ) = 1
  3752.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3753.          substring( @8data, 1, 10 ), substring( @8data, 11, 10 ), @date)
  3754.  
  3755.     IF @9data is null
  3756.       goto INSERT_CMDS
  3757.     IF convert( int, substring( @9data, 25, 4 ) ) = 1
  3758.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3759.          substring( @9data, 1, 10 ), substring( @9data, 11, 10 ), @date)
  3760.  
  3761.     IF @10data is null
  3762.       goto INSERT_CMDS
  3763.     IF convert( int, substring( @10data, 25, 4 ) ) = 1
  3764.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3765.          substring( @10data, 1, 10 ), substring( @10data, 11, 10 ), @date)
  3766.  
  3767.     IF @11data is null
  3768.       goto INSERT_CMDS
  3769.     IF convert( int, substring( @11data, 25, 4 ) ) = 1
  3770.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3771.          substring( @11data, 1, 10 ), substring( @11data, 11, 10 ), @date)
  3772.  
  3773.     IF @12data is null
  3774.       goto INSERT_CMDS
  3775.     IF convert( int, substring( @12data, 25, 4 ) ) = 1
  3776.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3777.          substring( @12data, 1, 10 ), substring( @12data, 11, 10 ), @date)
  3778.  
  3779.     IF @13data is null
  3780.       goto INSERT_CMDS
  3781.     IF convert( int, substring( @13data, 25, 4 ) ) = 1
  3782.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3783.          substring( @13data, 1, 10 ), substring( @13data, 11, 10 ), @date)
  3784.  
  3785.     IF @14data is null
  3786.       goto INSERT_CMDS
  3787.     IF convert( int, substring( @14data, 25, 4 ) ) = 1
  3788.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3789.          substring( @14data, 1, 10 ), substring( @14data, 11, 10 ), @date)
  3790.  
  3791.     IF @15data is null
  3792.       goto INSERT_CMDS
  3793.     IF convert( int, substring( @15data, 25, 4 ) ) = 1
  3794.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3795.          substring( @15data, 1, 10 ), substring( @15data, 11, 10 ), @date)
  3796.  
  3797.     IF @16data is null
  3798.       goto INSERT_CMDS
  3799.     IF convert( int, substring( @16data, 25, 4 ) ) = 1
  3800.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3801.          substring( @16data, 1, 10 ), substring( @16data, 11, 10 ), @date)
  3802.  
  3803.     IF @17data is null
  3804.       goto INSERT_CMDS
  3805.     IF convert( int, substring( @17data, 25, 4 ) ) = 1
  3806.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3807.          substring( @17data, 1, 10 ), substring( @17data, 11, 10 ), @date)
  3808.  
  3809.     IF @18data is null
  3810.       goto INSERT_CMDS
  3811.     IF convert( int, substring( @18data, 25, 4 ) ) = 1
  3812.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3813.          substring( @18data, 1, 10 ), substring( @18data, 11, 10 ), @date)
  3814.  
  3815.     IF @19data is null
  3816.       goto INSERT_CMDS
  3817.     IF convert( int, substring( @19data, 25, 4 ) ) = 1
  3818.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3819.          substring( @19data, 1, 10 ), substring( @19data, 11, 10 ), @date)
  3820.  
  3821.     IF @20data is null
  3822.       goto INSERT_CMDS
  3823.     IF convert( int, substring( @20data, 25, 4 ) ) = 1
  3824.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3825.          substring( @20data, 1, 10 ), substring( @20data, 11, 10 ), @date)
  3826.  
  3827.     IF @21data is null
  3828.       goto INSERT_CMDS
  3829.     IF convert( int, substring( @21data, 25, 4 ) ) = 1
  3830.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3831.          substring( @21data, 1, 10 ), substring( @21data, 11, 10 ), @date)
  3832.  
  3833.     IF @22data is null
  3834.       goto INSERT_CMDS
  3835.     IF convert( int, substring( @22data, 25, 4 ) ) = 1
  3836.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3837.          substring( @22data, 1, 10 ), substring( @22data, 11, 10 ), @date)
  3838.  
  3839.     IF @23data is null
  3840.       goto INSERT_CMDS
  3841.     IF convert( int, substring( @23data, 25, 4 ) ) = 1
  3842.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3843.          substring( @23data, 1, 10 ), substring( @23data, 11, 10 ), @date)
  3844.  
  3845.     IF @24data is null
  3846.       goto INSERT_CMDS
  3847.     IF convert( int, substring( @24data, 25, 4 ) ) = 1
  3848.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3849.          substring( @24data, 1, 10 ), substring( @24data, 11, 10 ), @date)
  3850.  
  3851.     IF @25data is null
  3852.       goto INSERT_CMDS
  3853.     IF convert( int, substring( @25data, 25, 4 ) ) = 1
  3854.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3855.          substring( @25data, 1, 10 ), substring( @25data, 11, 10 ), @date)
  3856.  
  3857.     IF @26data is null
  3858.       goto INSERT_CMDS
  3859.     IF convert( int, substring( @26data, 25, 4 ) ) = 1
  3860.       INSERT INTO MSrepl_transactions VALUES (@publisher_database_id,
  3861.          substring( @26data, 1, 10 ), substring( @26data, 11, 10 ), @date)
  3862.  
  3863. INSERT_CMDS:
  3864.  
  3865.     if datalength( @data ) > 39
  3866.     begin
  3867.         -- Get the originator_id for the first command 
  3868.         select @cmd_data_len = substring( @data, 34, 2 )
  3869.         select @orig_srv_len = substring( @data, 36, 2 )
  3870.         select @orig_db_len = substring( @data, 38, 2 )
  3871.  
  3872.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3873.         begin 
  3874.             set @originator_id = null 
  3875.             select @originator_id = id from MSrepl_originators where
  3876.                 publisher_database_id = @publisher_database_id 
  3877.                 and UPPER(srvname) = upper(convert(sysname, substring( @data, 40 + @cmd_data_len, @orig_srv_len )))
  3878.                 and dbname = substring( @data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3879.             if @originator_id is null
  3880.             begin
  3881.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3882.                     (@publisher_database_id, substring( @data, 40 + @cmd_data_len, @orig_srv_len ), substring( @data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3883.                 select @originator_id = @@identity
  3884.             end
  3885.         end
  3886.         else
  3887.             select @originator_id = 0
  3888.  
  3889.         select @cmd_type = substring(@data,29,4) 
  3890.         if( @cmd_type in( 37,38 ) )
  3891.         begin
  3892.             select @artid = substring(@data,21,4)
  3893.             select @cmd_type = 38 - @cmd_type
  3894.             select @xact_seqno = substring( @data, 11, 10 )
  3895.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno 
  3896.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  3897.         end
  3898.  
  3899.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3900.             substring(@data,11,10),
  3901.             @cmd_type, 
  3902.             substring(@data,21,4), 
  3903.             @originator_id, 
  3904.             substring(@data,25,4), 
  3905.             convert(bit,substring(@data,33,1)), 
  3906.             substring(@data,40,@cmd_data_len) )
  3907.  
  3908.     end
  3909.     
  3910.     IF @1data is null
  3911.       return
  3912.     IF datalength( @1data ) > 39
  3913.     begin
  3914.         -- Get the originator_id for the first command 
  3915.         select @cmd_data_len = substring( @1data, 34, 2 )
  3916.         select @orig_srv_len = substring( @1data, 36, 2 )
  3917.         select @orig_db_len = substring( @1data, 38, 2 )
  3918.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3919.         begin 
  3920.             set @originator_id = null 
  3921.             select @originator_id = id from MSrepl_originators where
  3922.                 publisher_database_id = @publisher_database_id 
  3923.                 and UPPER(srvname) = upper(convert(sysname, substring( @1data, 40 + @cmd_data_len, @orig_srv_len )))
  3924.                 and dbname = substring( @1data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3925.             if @originator_id is null
  3926.             begin
  3927.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3928.                     (@publisher_database_id, substring( @1data, 40 + @cmd_data_len, @orig_srv_len ), substring( @1data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3929.                 select @originator_id = @@identity
  3930.             end
  3931.         end
  3932.         else
  3933.             select @originator_id = 0
  3934.  
  3935.         -- Now insert into MSrepl_commands
  3936.         select @cmd_type = substring(@1data,29,4)
  3937.         if( @cmd_type in( 37,38 ) )
  3938.         begin
  3939.             select @artid = substring(@1data,21,4)
  3940.             select @cmd_type = 38 - @cmd_type
  3941.             select @xact_seqno = substring( @1data, 11, 10 )
  3942.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  3943.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  3944.         end
  3945.  
  3946.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3947.             substring(@1data,11,10),
  3948.             @cmd_type, 
  3949.             substring(@1data,21,4), 
  3950.             @originator_id, 
  3951.             substring(@1data,25,4), 
  3952.             convert(bit,substring(@1data,33,1)), 
  3953.             substring(@1data,40,@cmd_data_len) )
  3954.     end
  3955.  
  3956.     IF @2data is null
  3957.       return
  3958.     IF datalength( @2data ) > 39
  3959.     begin
  3960.         -- Get the originator_id for the first command 
  3961.         select @cmd_data_len = substring( @2data, 34, 2 )
  3962.         select @orig_srv_len = substring( @2data, 36, 2 )
  3963.         select @orig_db_len = substring( @2data, 38, 2 )
  3964.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  3965.         begin 
  3966.             set @originator_id = null 
  3967.             select @originator_id = id from MSrepl_originators where
  3968.                 publisher_database_id = @publisher_database_id 
  3969.                 and UPPER(srvname) = upper(convert(sysname, substring( @2data, 40 + @cmd_data_len, @orig_srv_len )))
  3970.                 and dbname = substring( @2data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  3971.             if @originator_id is null
  3972.             begin
  3973.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  3974.                     (@publisher_database_id, substring( @2data, 40 + @cmd_data_len, @orig_srv_len ), substring( @2data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  3975.                 select @originator_id = @@identity
  3976.             end
  3977.         end
  3978.         else
  3979.             select @originator_id = 0
  3980.  
  3981.         -- Now insert into MSrepl_commands
  3982.         select @cmd_type = substring(@2data,29,4)
  3983.         if( @cmd_type in( 37,38 ) )
  3984.         begin
  3985.             select @artid = substring(@2data,21,4)
  3986.             select @cmd_type = 38 - @cmd_type
  3987.             select @xact_seqno = substring( @2data, 11, 10 )
  3988.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  3989.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  3990.         end
  3991.  
  3992.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  3993.             substring(@2data,11 ,10),
  3994.             @cmd_type, 
  3995.             substring(@2data,21 ,4), 
  3996.             @originator_id, 
  3997.             substring(@2data,25 ,4), 
  3998.             convert(bit,substring(@2data,33 ,1)), 
  3999.             substring(@2data,40,@cmd_data_len) )
  4000.  
  4001.     end
  4002.  
  4003.     IF @3data is null
  4004.       return
  4005.     IF datalength( @3data ) > 39
  4006.     begin
  4007.         -- Get the originator_id for the first command 
  4008.         select @cmd_data_len = substring( @3data, 34, 2 )
  4009.         select @orig_srv_len = substring( @3data, 36, 2 )
  4010.         select @orig_db_len = substring( @3data, 38, 2 )
  4011.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4012.         begin 
  4013.             set @originator_id = null 
  4014.             select @originator_id = id from MSrepl_originators where
  4015.                 publisher_database_id = @publisher_database_id 
  4016.                 and UPPER(srvname) = upper(convert(sysname, substring( @3data, 40 + @cmd_data_len, @orig_srv_len )))
  4017.                 and dbname = substring( @3data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4018.             if @originator_id is null
  4019.             begin
  4020.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4021.                     (@publisher_database_id, substring( @3data, 40 + @cmd_data_len, @orig_srv_len ), substring( @3data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4022.                 select @originator_id = @@identity
  4023.             end
  4024.         end
  4025.         else
  4026.             select @originator_id = 0
  4027.  
  4028.         -- Now insert into MSrepl_commands
  4029.         select @cmd_type = substring(@3data,29,4)
  4030.         if( @cmd_type in( 37,38 ) )
  4031.         begin
  4032.             select @artid = substring(@3data,21,4)
  4033.             select @cmd_type = 38 - @cmd_type
  4034.             select @xact_seqno = substring( @3data, 11, 10 )
  4035.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4036.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4037.         end
  4038.  
  4039.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4040.             substring(@3data,11 ,10),
  4041.             @cmd_type, 
  4042.             substring(@3data,21 ,4), 
  4043.             @originator_id, 
  4044.             substring(@3data,25 ,4), 
  4045.             convert(bit,substring(@3data,33 ,1)), 
  4046.             substring(@3data,40,@cmd_data_len) )
  4047.  
  4048.     end
  4049.  
  4050.     IF @4data is null
  4051.       return
  4052.     IF datalength( @4data ) > 39
  4053.     begin
  4054.         -- Get the originator_id for the first command 
  4055.         select @cmd_data_len = substring( @4data, 34, 2 )
  4056.         select @orig_srv_len = substring( @4data, 36, 2 )
  4057.         select @orig_db_len = substring( @4data, 38, 2 )
  4058.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4059.         begin 
  4060.             set @originator_id = null 
  4061.             select @originator_id = id from MSrepl_originators where
  4062.                 publisher_database_id = @publisher_database_id 
  4063.                 and UPPER(srvname) = upper(convert(sysname, substring( @4data, 40 + @cmd_data_len, @orig_srv_len )))
  4064.                 and dbname = substring( @4data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4065.             if @originator_id is null
  4066.             begin
  4067.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4068.                     (@publisher_database_id, substring( @4data, 40 + @cmd_data_len, @orig_srv_len ), substring( @4data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4069.                 select @originator_id = @@identity
  4070.             end
  4071.         end
  4072.         else
  4073.             select @originator_id = 0
  4074.  
  4075.         -- Now insert into MSrepl_commands
  4076.         select @cmd_type = substring(@4data,29,4)
  4077.         if( @cmd_type in( 37,38 ) )
  4078.         begin
  4079.             select @artid = substring(@4data,21,4)
  4080.             select @cmd_type = 38 - @cmd_type
  4081.             select @xact_seqno = substring( @4data, 11, 10 )
  4082.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4083.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4084.         end
  4085.  
  4086.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4087.             substring(@4data,11 ,10),
  4088.             @cmd_type, 
  4089.             substring(@4data,21 ,4), 
  4090.             @originator_id, 
  4091.             substring(@4data,25 ,4), 
  4092.             convert(bit,substring(@4data,33 ,1)), 
  4093.             substring(@4data,40,@cmd_data_len) )
  4094.  
  4095.     end
  4096.  
  4097.     IF @5data is null
  4098.       return
  4099.     IF datalength( @5data ) > 39
  4100.     begin
  4101.         -- Get the originator_id for the first command 
  4102.         select @cmd_data_len = substring( @5data, 34, 2 )
  4103.         select @orig_srv_len = substring( @5data, 36, 2 )
  4104.         select @orig_db_len = substring( @5data, 38, 2 )
  4105.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4106.         begin 
  4107.             set @originator_id = null 
  4108.             select @originator_id = id from MSrepl_originators where
  4109.                 publisher_database_id = @publisher_database_id 
  4110.                 and UPPER(srvname) = upper(convert(sysname, substring( @5data, 40 + @cmd_data_len, @orig_srv_len )))
  4111.                 and dbname = substring( @5data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4112.             if @originator_id is null
  4113.             begin
  4114.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4115.                     (@publisher_database_id, substring( @5data, 40 + @cmd_data_len, @orig_srv_len ), substring( @5data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4116.                 select @originator_id = @@identity
  4117.             end
  4118.         end
  4119.         else
  4120.             select @originator_id = 0
  4121.  
  4122.         -- Now insert into MSrepl_commands
  4123.         select @cmd_type = substring(@5data,29,4)
  4124.         if( @cmd_type in( 37,38 ) )
  4125.         begin
  4126.             select @artid = substring(@5data,21,4)
  4127.             select @cmd_type = 38 - @cmd_type
  4128.             select @xact_seqno = substring( @5data, 11, 10 )
  4129.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4130.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4131.         end
  4132.  
  4133.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4134.             substring(@5data,11 ,10),
  4135.             @cmd_type, 
  4136.             substring(@5data,21 ,4), 
  4137.             @originator_id, 
  4138.             substring(@5data,25 ,4), 
  4139.             convert(bit,substring(@5data,33 ,1)), 
  4140.             substring(@5data,40,@cmd_data_len) )
  4141.  
  4142.     end
  4143.  
  4144.     IF @6data is null
  4145.       return
  4146.     IF datalength( @6data ) > 39
  4147.     begin
  4148.         -- Get the originator_id for the first command 
  4149.         select @cmd_data_len = substring( @6data, 34, 2 )
  4150.         select @orig_srv_len = substring( @6data, 36, 2 )
  4151.         select @orig_db_len = substring( @6data, 38, 2 )
  4152.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4153.         begin 
  4154.             set @originator_id = null 
  4155.             select @originator_id = id from MSrepl_originators where
  4156.                 publisher_database_id = @publisher_database_id 
  4157.                 and UPPER(srvname) = upper(convert(sysname, substring( @6data, 40 + @cmd_data_len, @orig_srv_len )))
  4158.                 and dbname = substring( @6data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4159.             if @originator_id is null
  4160.             begin
  4161.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4162.                     (@publisher_database_id, substring( @6data, 40 + @cmd_data_len, @orig_srv_len ), substring( @6data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4163.                 select @originator_id = @@identity
  4164.             end
  4165.         end
  4166.         else
  4167.             select @originator_id = 0
  4168.  
  4169.         -- Now insert into MSrepl_commands
  4170.         select @cmd_type = substring(@6data,29,4)
  4171.         if( @cmd_type in( 37,38 ) )
  4172.         begin
  4173.             select @artid = substring(@6data,21,4)
  4174.             select @cmd_type = 38 - @cmd_type
  4175.             select @xact_seqno = substring( @6data, 11, 10 )
  4176.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4177.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4178.         end
  4179.  
  4180.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4181.             substring(@6data,11 ,10),
  4182.             @cmd_type, 
  4183.             substring(@6data,21 ,4), 
  4184.             @originator_id, 
  4185.             substring(@6data,25 ,4), 
  4186.             convert(bit,substring(@6data,33 ,1)), 
  4187.             substring(@6data,40,@cmd_data_len) )
  4188.  
  4189.     end
  4190.  
  4191.     IF @7data is null
  4192.       return
  4193.     IF datalength( @7data ) > 39
  4194.     begin
  4195.         -- Get the originator_id for the first command 
  4196.         select @cmd_data_len = substring( @7data, 34, 2 )
  4197.         select @orig_srv_len = substring( @7data, 36, 2 )
  4198.         select @orig_db_len = substring( @7data, 38, 2 )
  4199.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4200.         begin 
  4201.             set @originator_id = null 
  4202.             select @originator_id = id from MSrepl_originators where
  4203.                 publisher_database_id = @publisher_database_id 
  4204.                 and UPPER(srvname) = upper(convert(sysname, substring( @7data, 40 + @cmd_data_len, @orig_srv_len )))
  4205.                 and dbname = substring( @7data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4206.             if @originator_id is null
  4207.             begin
  4208.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4209.                     (@publisher_database_id, substring( @7data, 40 + @cmd_data_len, @orig_srv_len ), substring( @7data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4210.                 select @originator_id = @@identity
  4211.             end
  4212.         end
  4213.         else
  4214.             select @originator_id = 0
  4215.  
  4216.         -- Now insert into MSrepl_commands
  4217.         select @cmd_type = substring(@7data,29,4)
  4218.         if( @cmd_type in( 37,38 ) )
  4219.         begin
  4220.             select @artid = substring(@7data,21,4)
  4221.             select @cmd_type = 38 - @cmd_type
  4222.             select @xact_seqno = substring( @7data, 11, 10 )
  4223.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4224.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4225.         end
  4226.  
  4227.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4228.             substring(@7data,11 ,10),
  4229.             @cmd_type, 
  4230.             substring(@7data,21 ,4), 
  4231.             @originator_id, 
  4232.             substring(@7data,25 ,4), 
  4233.             convert(bit,substring(@7data,33 ,1)), 
  4234.             substring(@7data,40,@cmd_data_len) )
  4235.  
  4236.     end
  4237.  
  4238.     IF @8data is null
  4239.       return
  4240.     IF datalength( @8data ) > 39
  4241.     begin
  4242.         -- Get the originator_id for the first command 
  4243.         select @cmd_data_len = substring( @8data, 34, 2 )
  4244.         select @orig_srv_len = substring( @8data, 36, 2 )
  4245.         select @orig_db_len = substring( @8data, 38, 2 )
  4246.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4247.         begin 
  4248.             set @originator_id = null 
  4249.             select @originator_id = id from MSrepl_originators where
  4250.                 publisher_database_id = @publisher_database_id 
  4251.                 and UPPER(srvname) = upper(convert(sysname, substring( @8data, 40 + @cmd_data_len, @orig_srv_len )))
  4252.                 and dbname = substring( @8data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4253.             if @originator_id is null
  4254.             begin
  4255.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4256.                     (@publisher_database_id, substring( @8data, 40 + @cmd_data_len, @orig_srv_len ), substring( @8data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4257.                 select @originator_id = @@identity
  4258.             end
  4259.         end
  4260.         else
  4261.             select @originator_id = 0
  4262.  
  4263.         -- Now insert into MSrepl_commands
  4264.         select @cmd_type = substring(@8data,29,4)
  4265.         if( @cmd_type in( 37,38 ) )
  4266.         begin
  4267.             select @artid = substring(@8data,21,4)
  4268.             select @cmd_type = 38 - @cmd_type
  4269.             select @xact_seqno = substring( @8data, 11, 10 )
  4270.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4271.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4272.         end
  4273.  
  4274.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4275.             substring(@8data,11 ,10),
  4276.             @cmd_type, 
  4277.             substring(@8data,21 ,4), 
  4278.             @originator_id, 
  4279.             substring(@8data,25 ,4), 
  4280.             convert(bit,substring(@8data,33 ,1)), 
  4281.             substring(@8data,40,@cmd_data_len) )
  4282.     end
  4283.  
  4284.     IF @9data is null
  4285.       return
  4286.     IF datalength( @9data ) > 39
  4287.     begin
  4288.         -- Get the originator_id for the first command 
  4289.         select @cmd_data_len = substring( @9data, 34, 2 )
  4290.         select @orig_srv_len = substring( @9data, 36, 2 )
  4291.         select @orig_db_len = substring( @9data, 38, 2 )
  4292.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4293.         begin 
  4294.             set @originator_id = null 
  4295.             select @originator_id = id from MSrepl_originators where
  4296.                 publisher_database_id = @publisher_database_id 
  4297.                 and upper(srvname) = upper(convert(sysname, substring( @9data, 40 + @cmd_data_len, @orig_srv_len )))
  4298.                 and dbname = substring( @9data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4299.             if @originator_id is null
  4300.             begin
  4301.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4302.                     (@publisher_database_id, substring( @9data, 40 + @cmd_data_len, @orig_srv_len ), substring( @9data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4303.                 select @originator_id = @@identity
  4304.             end
  4305.         end
  4306.         else
  4307.             select @originator_id = 0
  4308.  
  4309.         -- Now insert into MSrepl_commands
  4310.         select @cmd_type = substring(@9data,29,4)
  4311.         if( @cmd_type in( 37,38 ) )
  4312.         begin
  4313.             select @artid = substring(@9data,21,4)
  4314.             select @cmd_type = 38 - @cmd_type
  4315.             select @xact_seqno = substring( @9data, 11, 10 )
  4316.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4317.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4318.         end
  4319.  
  4320.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4321.             substring(@9data,11 ,10),
  4322.             @cmd_type, 
  4323.             substring(@9data,21 ,4), 
  4324.             @originator_id, 
  4325.             substring(@9data,25 ,4), 
  4326.             convert(bit,substring(@9data,33 ,1)), 
  4327.             substring(@9data,40,@cmd_data_len) )
  4328.     end
  4329.  
  4330.     IF @10data is null
  4331.       return
  4332.     IF datalength( @10data ) > 39
  4333.     begin
  4334.         -- Get the originator_id for the first command 
  4335.         select @cmd_data_len = substring( @10data, 34, 2 )
  4336.         select @orig_srv_len = substring( @10data, 36, 2 )
  4337.         select @orig_db_len = substring( @10data, 38, 2 )
  4338.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4339.         begin 
  4340.             set @originator_id = null 
  4341.             select @originator_id = id from MSrepl_originators where
  4342.                 publisher_database_id = @publisher_database_id 
  4343.                 and UPPER(srvname) = upper(convert(sysname, substring( @10data, 40 + @cmd_data_len, @orig_srv_len )))
  4344.                 and dbname = substring( @10data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4345.             if @originator_id is null
  4346.             begin
  4347.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4348.                     (@publisher_database_id, substring( @10data, 40 + @cmd_data_len, @orig_srv_len ), substring( @10data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4349.                 select @originator_id = @@identity
  4350.             end
  4351.         end
  4352.         else
  4353.             select @originator_id = 0
  4354.  
  4355.         -- Now insert into MSrepl_commands
  4356.         select @cmd_type = substring(@10data,29,4)
  4357.         if( @cmd_type in( 37,38 ) )
  4358.         begin
  4359.             select @artid = substring(@10data,21,4)
  4360.             select @cmd_type = 38 - @cmd_type
  4361.             select @xact_seqno = substring( @10data, 11, 10 )
  4362.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4363.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4364.         end
  4365.  
  4366.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4367.             substring(@10data,11 ,10),
  4368.             @cmd_type, 
  4369.             substring(@10data,21 ,4), 
  4370.             @originator_id, 
  4371.             substring(@10data,25 ,4), 
  4372.             convert(bit,substring(@10data,33 ,1)), 
  4373.             substring(@10data,40,@cmd_data_len) )
  4374.  
  4375.     end
  4376.  
  4377.     IF @11data is null
  4378.       return
  4379.     IF datalength( @11data ) > 39
  4380.     begin
  4381.         -- Get the originator_id for the first command 
  4382.         select @cmd_data_len = substring( @11data, 34, 2 )
  4383.         select @orig_srv_len = substring( @11data, 36, 2 )
  4384.         select @orig_db_len = substring( @11data, 38, 2 )
  4385.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4386.         begin 
  4387.             set @originator_id = null 
  4388.             select @originator_id = id from MSrepl_originators where
  4389.                 publisher_database_id = @publisher_database_id 
  4390.                 and UPPER(srvname) = upper(convert(sysname, substring( @11data, 40 + @cmd_data_len, @orig_srv_len )))
  4391.                 and dbname = substring( @11data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4392.             if @originator_id is null
  4393.             begin
  4394.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4395.                     (@publisher_database_id, substring( @11data, 40 + @cmd_data_len, @orig_srv_len ), substring( @11data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4396.                 select @originator_id = @@identity
  4397.             end
  4398.         end
  4399.         else
  4400.             select @originator_id = 0
  4401.  
  4402.         -- Now insert into MSrepl_commands
  4403.         select @cmd_type = substring(@11data,29,4)
  4404.         if( @cmd_type in( 37,38 ) )
  4405.         begin
  4406.             select @artid = substring(@11data,21,4)
  4407.             select @cmd_type = 38 - @cmd_type
  4408.             select @xact_seqno = substring( @11data, 11, 10 )
  4409.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4410.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4411.         end
  4412.  
  4413.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4414.             substring(@11data,11 ,10),
  4415.             @cmd_type, 
  4416.             substring(@11data,21 ,4), 
  4417.             @originator_id, 
  4418.             substring(@11data,25 ,4), 
  4419.             convert(bit,substring(@11data,33 ,1)), 
  4420.             substring(@11data,40,@cmd_data_len) )
  4421.     end
  4422.  
  4423.     IF @12data is null
  4424.       return
  4425.     IF datalength( @12data ) > 39
  4426.     begin
  4427.         -- Get the originator_id for the first command 
  4428.         select @cmd_data_len = substring( @12data, 34, 2 )
  4429.         select @orig_srv_len = substring( @12data, 36, 2 )
  4430.         select @orig_db_len = substring( @12data, 38, 2 )
  4431.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4432.         begin 
  4433.             set @originator_id = null 
  4434.             select @originator_id = id from MSrepl_originators where
  4435.                 publisher_database_id = @publisher_database_id 
  4436.                 and UPPER(srvname) = upper(convert(sysname, substring( @12data, 40 + @cmd_data_len, @orig_srv_len )))
  4437.                 and dbname = substring( @12data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4438.             if @originator_id is null
  4439.             begin
  4440.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4441.                     (@publisher_database_id, substring( @12data, 40 + @cmd_data_len, @orig_srv_len ), substring( @12data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4442.                 select @originator_id = @@identity
  4443.             end
  4444.         end
  4445.         else
  4446.             select @originator_id = 0
  4447.  
  4448.         -- Now insert into MSrepl_commands
  4449.         select @cmd_type = substring(@12data,29,4)
  4450.         if( @cmd_type in( 37,38 ) )
  4451.         begin
  4452.             select @artid = substring(@12data,21,4)
  4453.             select @cmd_type = 38 - @cmd_type
  4454.             select @xact_seqno = substring( @12data, 11, 10 )
  4455.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4456.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4457.         end
  4458.  
  4459.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4460.             substring(@12data,11 ,10),
  4461.             @cmd_type, 
  4462.             substring(@12data,21 ,4), 
  4463.             @originator_id, 
  4464.             substring(@12data,25 ,4), 
  4465.             convert(bit,substring(@12data,33 ,1)), 
  4466.             substring(@12data,40,@cmd_data_len) )
  4467.     end
  4468.  
  4469.  
  4470.     IF @13data is null
  4471.       return
  4472.     IF datalength( @13data ) > 39
  4473.     begin
  4474.         -- Get the originator_id for the first command 
  4475.         select @cmd_data_len = substring( @13data, 34, 2 )
  4476.         select @orig_srv_len = substring( @13data, 36, 2 )
  4477.         select @orig_db_len = substring( @13data, 38, 2 )
  4478.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4479.         begin 
  4480.             set @originator_id = null 
  4481.             select @originator_id = id from MSrepl_originators where
  4482.                 publisher_database_id = @publisher_database_id 
  4483.                 and UPPER(srvname) = upper(convert(sysname, substring( @13data, 40 + @cmd_data_len, @orig_srv_len )))
  4484.                 and dbname = substring( @13data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4485.             if @originator_id is null
  4486.             begin
  4487.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4488.                     (@publisher_database_id, substring( @13data, 40 + @cmd_data_len, @orig_srv_len ), substring( @13data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4489.                 select @originator_id = @@identity
  4490.             end
  4491.         end
  4492.         else
  4493.             select @originator_id = 0
  4494.  
  4495.         -- Now insert into MSrepl_commands
  4496.         select @cmd_type = substring(@13data,29,4)
  4497.         if( @cmd_type in( 37,38 ) )
  4498.         begin
  4499.             select @artid = substring(@13data,21,4)
  4500.             select @cmd_type = 38 - @cmd_type
  4501.             select @xact_seqno = substring( @13data, 11, 10 )
  4502.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4503.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4504.         end
  4505.  
  4506.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4507.             substring(@13data,11 ,10),
  4508.             @cmd_type, 
  4509.             substring(@13data,21 ,4), 
  4510.             @originator_id, 
  4511.             substring(@13data,25 ,4), 
  4512.             convert(bit,substring(@13data,33 ,1)), 
  4513.             substring(@13data,40,@cmd_data_len) )
  4514.     end
  4515.  
  4516.     IF @14data is null
  4517.       return
  4518.     IF datalength( @14data ) > 39
  4519.     begin
  4520.         -- Get the originator_id for the first command 
  4521.         select @cmd_data_len = substring( @14data, 34, 2 )
  4522.         select @orig_srv_len = substring( @14data, 36, 2 )
  4523.         select @orig_db_len = substring( @14data, 38, 2 )
  4524.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4525.         begin 
  4526.             set @originator_id = null 
  4527.             select @originator_id = id from MSrepl_originators where
  4528.                 publisher_database_id = @publisher_database_id 
  4529.                 and UPPER(srvname) = upper(convert(sysname, substring( @14data, 40 + @cmd_data_len, @orig_srv_len )))
  4530.                 and dbname = substring( @14data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4531.             if @originator_id is null
  4532.             begin
  4533.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4534.                     (@publisher_database_id, substring( @14data, 40 + @cmd_data_len, @orig_srv_len ), substring( @14data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4535.                 select @originator_id = @@identity
  4536.             end
  4537.         end
  4538.         else
  4539.             select @originator_id = 0
  4540.  
  4541.         -- Now insert into MSrepl_commands
  4542.         select @cmd_type = substring(@14data,29,4)
  4543.         if( @cmd_type in( 37,38 ) )
  4544.         begin
  4545.             select @artid = substring(@14data,21,4)
  4546.             select @cmd_type = 38 - @cmd_type
  4547.             select @xact_seqno = substring( @14data, 11, 10 )
  4548.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4549.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4550.         end
  4551.  
  4552.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4553.             substring(@14data,11 ,10),
  4554.             @cmd_type, 
  4555.             substring(@14data,21 ,4), 
  4556.             @originator_id, 
  4557.             substring(@14data,25 ,4), 
  4558.             convert(bit,substring(@14data,33 ,1)), 
  4559.             substring(@14data,40,@cmd_data_len) )
  4560.     end
  4561.  
  4562.  
  4563.     IF @15data is null
  4564.       return
  4565.     IF datalength( @15data ) > 39
  4566.     begin
  4567.         -- Get the originator_id for the first command 
  4568.         select @cmd_data_len = substring( @15data, 34, 2 )
  4569.         select @orig_srv_len = substring( @15data, 36, 2 )
  4570.         select @orig_db_len = substring( @15data, 38, 2 )
  4571.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4572.         begin 
  4573.             set @originator_id = null 
  4574.             select @originator_id = id from MSrepl_originators where
  4575.                 publisher_database_id = @publisher_database_id 
  4576.                 and UPPER(srvname) = upper(convert(sysname, substring( @15data, 40 + @cmd_data_len, @orig_srv_len )))
  4577.                 and dbname = substring( @15data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4578.             if @originator_id is null
  4579.             begin
  4580.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4581.                     (@publisher_database_id, substring( @15data, 40 + @cmd_data_len, @orig_srv_len ), substring( @15data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4582.                 select @originator_id = @@identity
  4583.             end
  4584.         end
  4585.         else
  4586.             select @originator_id = 0
  4587.  
  4588.         -- Now insert into MSrepl_commands
  4589.         select @cmd_type = substring(@15data,29,4)
  4590.         if( @cmd_type in( 37,38 ) )
  4591.         begin
  4592.             select @artid = substring(@15data,21,4)
  4593.             select @cmd_type = 38 - @cmd_type
  4594.             select @xact_seqno = substring( @15data, 11, 10 )
  4595.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4596.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4597.         end
  4598.  
  4599.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4600.             substring(@15data,11 ,10),
  4601.             @cmd_type, 
  4602.             substring(@15data,21 ,4), 
  4603.             @originator_id, 
  4604.             substring(@15data,25 ,4), 
  4605.             convert(bit,substring(@15data,33 ,1)), 
  4606.             substring(@15data,40,@cmd_data_len) )
  4607.     end
  4608.  
  4609.     IF @16data is null
  4610.       return
  4611.     IF datalength( @16data ) > 39
  4612.     begin
  4613.         -- Get the originator_id for the first command 
  4614.         select @cmd_data_len = substring( @16data, 34, 2 )
  4615.         select @orig_srv_len = substring( @16data, 36, 2 )
  4616.         select @orig_db_len = substring( @16data, 38, 2 )
  4617.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4618.         begin 
  4619.             set @originator_id = null 
  4620.             select @originator_id = id from MSrepl_originators where
  4621.                 publisher_database_id = @publisher_database_id 
  4622.                 and UPPER(srvname) = upper(convert(sysname, substring( @16data, 40 + @cmd_data_len, @orig_srv_len )))
  4623.                 and dbname = substring( @16data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4624.             if @originator_id is null
  4625.             begin
  4626.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4627.                     (@publisher_database_id, substring( @16data, 40 + @cmd_data_len, @orig_srv_len ), substring( @16data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4628.                 select @originator_id = @@identity
  4629.             end
  4630.         end
  4631.         else
  4632.             select @originator_id = 0
  4633.  
  4634.         -- Now insert into MSrepl_commands
  4635.         select @cmd_type = substring(@16data,29,4)
  4636.         if( @cmd_type in( 37,38 ) )
  4637.         begin
  4638.             select @artid = substring(@16data,21,4)
  4639.             select @cmd_type = 38 - @cmd_type
  4640.             select @xact_seqno = substring( @16data, 11, 10 )
  4641.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4642.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4643.         end
  4644.  
  4645.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4646.             substring(@16data,11 ,10),
  4647.             @cmd_type, 
  4648.             substring(@16data,21 ,4), 
  4649.             @originator_id, 
  4650.             substring(@16data,25 ,4), 
  4651.             convert(bit,substring(@16data,33 ,1)), 
  4652.             substring(@16data,40,@cmd_data_len) )
  4653.     end
  4654.  
  4655.  
  4656.     IF @17data is null
  4657.       return
  4658.     IF datalength( @17data ) > 39
  4659.     begin
  4660.         -- Get the originator_id for the first command 
  4661.         select @cmd_data_len = substring( @17data, 34, 2 )
  4662.         select @orig_srv_len = substring( @17data, 36, 2 )
  4663.         select @orig_db_len = substring( @17data, 38, 2 )
  4664.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4665.         begin 
  4666.             set @originator_id = null 
  4667.             select @originator_id = id from MSrepl_originators where
  4668.                 publisher_database_id = @publisher_database_id 
  4669.                 and UPPER(srvname) = upper(convert(sysname, substring( @17data, 40 + @cmd_data_len, @orig_srv_len )))
  4670.                 and dbname = substring( @17data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4671.             if @originator_id is null
  4672.             begin
  4673.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4674.                     (@publisher_database_id, substring( @17data, 40 + @cmd_data_len, @orig_srv_len ), substring( @17data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4675.                 select @originator_id = @@identity
  4676.             end
  4677.         end
  4678.         else
  4679.             select @originator_id = 0
  4680.  
  4681.         -- Now insert into MSrepl_commands
  4682.         select @cmd_type = substring(@17data,29,4)
  4683.         if( @cmd_type in( 37,38 ) )
  4684.         begin
  4685.             select @artid = substring(@17data,21,4)
  4686.             select @cmd_type = 38 - @cmd_type
  4687.             select @xact_seqno = substring( @17data, 11, 10 )
  4688.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4689.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4690.         end
  4691.  
  4692.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4693.             substring(@17data,11 ,10),
  4694.             @cmd_type, 
  4695.             substring(@17data,21 ,4), 
  4696.             @originator_id, 
  4697.             substring(@17data,25 ,4), 
  4698.             convert(bit,substring(@17data,33 ,1)), 
  4699.             substring(@17data,40,@cmd_data_len) )
  4700.     end
  4701.  
  4702.  
  4703.     IF @18data is null
  4704.       return
  4705.     IF datalength( @18data ) > 39
  4706.     begin
  4707.         -- Get the originator_id for the first command 
  4708.         select @cmd_data_len = substring( @18data, 34, 2 )
  4709.         select @orig_srv_len = substring( @18data, 36, 2 )
  4710.         select @orig_db_len = substring( @18data, 38, 2 )
  4711.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4712.         begin 
  4713.             set @originator_id = null 
  4714.             select @originator_id = id from MSrepl_originators where
  4715.                 publisher_database_id = @publisher_database_id 
  4716.                 and UPPER(srvname) = upper(convert(sysname, substring( @18data, 40 + @cmd_data_len, @orig_srv_len )))
  4717.                 and dbname = substring( @18data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4718.             if @originator_id is null
  4719.             begin
  4720.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4721.                     (@publisher_database_id, substring( @18data, 40 + @cmd_data_len, @orig_srv_len ), substring( @18data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4722.                 select @originator_id = @@identity
  4723.             end
  4724.         end
  4725.         else
  4726.             select @originator_id = 0
  4727.  
  4728.         -- Now insert into MSrepl_commands
  4729.         select @cmd_type = substring(@18data,29,4)
  4730.         if( @cmd_type in( 37,38 ) )
  4731.         begin
  4732.             select @artid = substring(@18data,21,4)
  4733.             select @cmd_type = 38 - @cmd_type
  4734.             select @xact_seqno = substring( @18data, 11, 10 )
  4735.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4736.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4737.         end
  4738.  
  4739.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4740.             substring(@18data,11 ,10),
  4741.             @cmd_type, 
  4742.             substring(@18data,21 ,4), 
  4743.             @originator_id, 
  4744.             substring(@18data,25 ,4), 
  4745.             convert(bit,substring(@18data,33 ,1)), 
  4746.             substring(@18data,40,@cmd_data_len) )
  4747.     end
  4748.  
  4749.  
  4750.     IF @19data is null
  4751.       return
  4752.     IF datalength( @19data ) > 39
  4753.     begin
  4754.         -- Get the originator_id for the first command 
  4755.         select @cmd_data_len = substring( @19data, 34, 2 )
  4756.         select @orig_srv_len = substring( @19data, 36, 2 )
  4757.         select @orig_db_len = substring( @19data, 38, 2 )
  4758.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4759.         begin 
  4760.             set @originator_id = null 
  4761.             select @originator_id = id from MSrepl_originators where
  4762.                 publisher_database_id = @publisher_database_id 
  4763.                 and UPPER(srvname) = upper(convert(sysname, substring( @19data, 40 + @cmd_data_len, @orig_srv_len )))
  4764.                 and dbname = substring( @19data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4765.             if @originator_id is null
  4766.             begin
  4767.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4768.                     (@publisher_database_id, substring( @19data, 40 + @cmd_data_len, @orig_srv_len ), substring( @19data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4769.                 select @originator_id = @@identity
  4770.             end
  4771.         end
  4772.         else
  4773.             select @originator_id = 0
  4774.  
  4775.         -- Now insert into MSrepl_commands
  4776.         select @cmd_type = substring(@19data,29,4)
  4777.         if( @cmd_type in( 37,38 ) )
  4778.         begin
  4779.             select @artid = substring(@19data,21,4)
  4780.             select @cmd_type = 38 - @cmd_type
  4781.             select @xact_seqno = substring( @19data, 11, 10 )
  4782.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4783.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4784.         end
  4785.  
  4786.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4787.             substring(@19data,11 ,10),
  4788.             @cmd_type, 
  4789.             substring(@19data,21 ,4), 
  4790.             @originator_id, 
  4791.             substring(@19data,25 ,4), 
  4792.             convert(bit,substring(@19data,33 ,1)), 
  4793.             substring(@19data,40,@cmd_data_len) )
  4794.     end
  4795.  
  4796.  
  4797.     IF @20data is null
  4798.       return
  4799.     IF datalength( @20data ) > 39
  4800.     begin
  4801.         -- Get the originator_id for the first command 
  4802.         select @cmd_data_len = substring( @20data, 34, 2 )
  4803.         select @orig_srv_len = substring( @20data, 36, 2 )
  4804.         select @orig_db_len = substring( @20data, 38, 2 )
  4805.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4806.         begin 
  4807.             set @originator_id = null 
  4808.             select @originator_id = id from MSrepl_originators where
  4809.                 publisher_database_id = @publisher_database_id 
  4810.                 and UPPER(srvname) = upper(convert(sysname, substring( @20data, 40 + @cmd_data_len, @orig_srv_len )))
  4811.                 and dbname = substring( @20data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4812.             if @originator_id is null
  4813.             begin
  4814.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4815.                     (@publisher_database_id, substring( @20data, 40 + @cmd_data_len, @orig_srv_len ), substring( @20data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4816.                 select @originator_id = @@identity
  4817.             end
  4818.         end
  4819.         else
  4820.             select @originator_id = 0
  4821.  
  4822.         -- Now insert into MSrepl_commands
  4823.         select @cmd_type = substring(@20data,29,4)
  4824.         if( @cmd_type in( 37,38 ) )
  4825.         begin
  4826.             select @artid = substring(@20data,21,4)
  4827.             select @cmd_type = 38 - @cmd_type
  4828.             select @xact_seqno = substring( @20data, 11, 10 )
  4829.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4830.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4831.         end
  4832.  
  4833.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4834.             substring(@20data,11 ,10),
  4835.             @cmd_type, 
  4836.             substring(@20data,21 ,4), 
  4837.             @originator_id, 
  4838.             substring(@20data,25 ,4), 
  4839.             convert(bit,substring(@20data,33 ,1)), 
  4840.             substring(@20data,40,@cmd_data_len) )
  4841.     end
  4842.  
  4843.     IF @21data is null
  4844.       return
  4845.     IF datalength( @21data ) > 39
  4846.     begin
  4847.         -- Get the originator_id for the first command 
  4848.         select @cmd_data_len = substring( @21data, 34, 2 )
  4849.         select @orig_srv_len = substring( @21data, 36, 2 )
  4850.         select @orig_db_len = substring( @21data, 38, 2 )
  4851.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4852.         begin 
  4853.             set @originator_id = null 
  4854.             select @originator_id = id from MSrepl_originators where
  4855.                 publisher_database_id = @publisher_database_id 
  4856.                 and UPPER(srvname) = upper(convert(sysname, substring( @21data, 40 + @cmd_data_len, @orig_srv_len )))
  4857.                 and dbname = substring( @21data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4858.             if @originator_id is null
  4859.             begin
  4860.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4861.                     (@publisher_database_id, substring( @21data, 40 + @cmd_data_len, @orig_srv_len ), substring( @21data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4862.                 select @originator_id = @@identity
  4863.             end
  4864.         end
  4865.         else
  4866.             select @originator_id = 0
  4867.  
  4868.         -- Now insert into MSrepl_commands
  4869.         select @cmd_type = substring(@21data,29,4)
  4870.         if( @cmd_type in( 37,38 ) )
  4871.         begin
  4872.             select @artid = substring(@21data,21,4)
  4873.             select @cmd_type = 38 - @cmd_type
  4874.             select @xact_seqno = substring( @21data, 11, 10 )
  4875.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4876.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4877.         end
  4878.  
  4879.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4880.             substring(@21data,11 ,10),
  4881.             @cmd_type, 
  4882.             substring(@21data,21 ,4), 
  4883.             @originator_id, 
  4884.             substring(@21data,25 ,4), 
  4885.             convert(bit,substring(@21data,33 ,1)), 
  4886.             substring(@21data,40,@cmd_data_len) )
  4887.     end
  4888.  
  4889.     IF @22data is null
  4890.       return
  4891.     IF datalength( @22data ) > 39
  4892.     begin
  4893.         -- Get the originator_id for the first command 
  4894.         select @cmd_data_len = substring( @22data, 34, 2 )
  4895.         select @orig_srv_len = substring( @22data, 36, 2 )
  4896.         select @orig_db_len = substring( @22data, 38, 2 )
  4897.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4898.         begin 
  4899.             set @originator_id = null 
  4900.             select @originator_id = id from MSrepl_originators where
  4901.                 publisher_database_id = @publisher_database_id 
  4902.                 and UPPER(srvname) = upper(convert(sysname, substring( @22data, 40 + @cmd_data_len, @orig_srv_len )))
  4903.                 and dbname = substring( @22data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4904.             if @originator_id is null
  4905.             begin
  4906.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4907.                     (@publisher_database_id, substring( @22data, 40 + @cmd_data_len, @orig_srv_len ), substring( @22data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4908.                 select @originator_id = @@identity
  4909.             end
  4910.         end
  4911.         else
  4912.             select @originator_id = 0
  4913.  
  4914.         -- Now insert into MSrepl_commands
  4915.         select @cmd_type = substring(@22data,29,4)
  4916.         if( @cmd_type in( 37,38 ) )
  4917.         begin
  4918.             select @artid = substring(@22data,21,4)
  4919.             select @cmd_type = 38 - @cmd_type
  4920.             select @xact_seqno = substring( @22data, 11, 10 )
  4921.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4922.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4923.         end
  4924.  
  4925.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4926.             substring(@22data,11 ,10),
  4927.             @cmd_type, 
  4928.             substring(@22data,21 ,4), 
  4929.             @originator_id, 
  4930.             substring(@22data,25 ,4), 
  4931.             convert(bit,substring(@22data,33 ,1)), 
  4932.             substring(@22data,40,@cmd_data_len) )
  4933.     end
  4934.  
  4935.     IF @23data is null
  4936.       return
  4937.     IF datalength( @23data ) > 39
  4938.     begin
  4939.         -- Get the originator_id for the first command 
  4940.         select @cmd_data_len = substring( @23data, 34, 2 )
  4941.         select @orig_srv_len = substring( @23data, 36, 2 )
  4942.         select @orig_db_len = substring( @23data, 38, 2 )
  4943.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4944.         begin 
  4945.             set @originator_id = null 
  4946.             select @originator_id = id from MSrepl_originators where
  4947.                 publisher_database_id = @publisher_database_id 
  4948.                 and UPPER(srvname) = upper(convert(sysname, substring( @23data, 40 + @cmd_data_len, @orig_srv_len )))
  4949.                 and dbname = substring( @23data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4950.             if @originator_id is null
  4951.             begin
  4952.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4953.                     (@publisher_database_id, substring( @23data, 40 + @cmd_data_len, @orig_srv_len ), substring( @23data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  4954.                 select @originator_id = @@identity
  4955.             end
  4956.         end
  4957.         else
  4958.             select @originator_id = 0
  4959.  
  4960.         -- Now insert into MSrepl_commands
  4961.         select @cmd_type = substring(@23data,29,4)
  4962.         if( @cmd_type in( 37,38 ) )
  4963.         begin
  4964.             select @artid = substring(@23data,21,4)
  4965.             select @cmd_type = 38 - @cmd_type
  4966.             select @xact_seqno = substring( @23data, 11, 10 )
  4967.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  4968.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  4969.         end
  4970.  
  4971.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  4972.             substring(@23data,11 ,10),
  4973.             @cmd_type, 
  4974.             substring(@23data,21 ,4), 
  4975.             @originator_id, 
  4976.             substring(@23data,25 ,4), 
  4977.             convert(bit,substring(@23data,33 ,1)), 
  4978.             substring(@23data,40,@cmd_data_len) )
  4979.     end
  4980.  
  4981.     IF @24data is null
  4982.       return
  4983.     IF datalength( @24data ) > 39
  4984.     begin
  4985.         -- Get the originator_id for the first command 
  4986.         select @cmd_data_len = substring( @24data, 34, 2 )
  4987.         select @orig_srv_len = substring( @24data, 36, 2 )
  4988.         select @orig_db_len = substring( @24data, 38, 2 )
  4989.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  4990.         begin 
  4991.             set @originator_id = null 
  4992.             select @originator_id = id from MSrepl_originators where
  4993.                 publisher_database_id = @publisher_database_id 
  4994.                 and UPPER(srvname) = upper(convert(sysname, substring( @24data, 40 + @cmd_data_len, @orig_srv_len )))
  4995.                 and dbname = substring( @24data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  4996.             if @originator_id is null
  4997.             begin
  4998.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  4999.                     (@publisher_database_id, substring( @24data, 40 + @cmd_data_len, @orig_srv_len ), substring( @24data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5000.                 select @originator_id = @@identity
  5001.             end
  5002.         end
  5003.         else
  5004.             select @originator_id = 0
  5005.  
  5006.         -- Now insert into MSrepl_commands
  5007.         select @cmd_type = substring(@24data,29,4)
  5008.         if( @cmd_type in( 37,38 ) )
  5009.         begin
  5010.             select @artid = substring(@24data,21,4)
  5011.             select @cmd_type = 38 - @cmd_type
  5012.             select @xact_seqno = substring( @24data, 11, 10 )
  5013.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  5014.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5015.         end
  5016.  
  5017.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5018.             substring(@24data,11 ,10),
  5019.             @cmd_type, 
  5020.             substring(@24data,21 ,4), 
  5021.             @originator_id, 
  5022.             substring(@24data,25 ,4), 
  5023.             convert(bit,substring(@24data,33 ,1)), 
  5024.             substring(@24data,40,@cmd_data_len) )
  5025.     end
  5026.  
  5027.  
  5028.     IF @25data is null
  5029.       return
  5030.     IF datalength( @25data ) > 39
  5031.     begin
  5032.         -- Get the originator_id for the first command 
  5033.         select @cmd_data_len = substring( @25data, 34, 2 )
  5034.         select @orig_srv_len = substring( @25data, 36, 2 )
  5035.         select @orig_db_len = substring( @25data, 38, 2 )
  5036.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  5037.         begin 
  5038.             set @originator_id = null 
  5039.             select @originator_id = id from MSrepl_originators where
  5040.                 publisher_database_id = @publisher_database_id 
  5041.                 and UPPER(srvname) = upper(convert(sysname, substring( @25data, 40 + @cmd_data_len, @orig_srv_len )))
  5042.                 and dbname = substring( @25data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  5043.             if @originator_id is null
  5044.             begin
  5045.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  5046.                     (@publisher_database_id, substring( @25data, 40 + @cmd_data_len, @orig_srv_len ), substring( @25data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5047.                 select @originator_id = @@identity
  5048.             end
  5049.         end
  5050.         else
  5051.             select @originator_id = 0
  5052.  
  5053.         -- Now insert into MSrepl_commands
  5054.         select @cmd_type = substring(@25data,29,4)
  5055.         if( @cmd_type in( 37,38 ) )
  5056.         begin
  5057.             select @artid = substring(@25data,21,4)
  5058.             select @cmd_type = 38 - @cmd_type
  5059.             select @xact_seqno = substring( @25data, 11, 10 )
  5060.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  5061.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5062.         end
  5063.  
  5064.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5065.             substring(@25data,11 ,10),
  5066.             @cmd_type, 
  5067.             substring(@25data,21 ,4), 
  5068.             @originator_id, 
  5069.             substring(@25data,25 ,4), 
  5070.             convert(bit,substring(@25data,33 ,1)), 
  5071.             substring(@25data,40,@cmd_data_len) )
  5072.     end
  5073.  
  5074.  
  5075.     IF @26data is null
  5076.       return
  5077.     IF datalength( @26data ) > 39
  5078.     begin
  5079.         -- Get the originator_id for the first command 
  5080.         select @cmd_data_len = substring( @26data, 34, 2 )
  5081.         select @orig_srv_len = substring( @26data, 36, 2 )
  5082.         select @orig_db_len = substring( @26data, 38, 2 )
  5083.         if @orig_srv_len <> 0 and @orig_db_len <> 0 
  5084.         begin 
  5085.             set @originator_id = null 
  5086.             select @originator_id = id from MSrepl_originators where
  5087.                 publisher_database_id = @publisher_database_id 
  5088.                 and UPPER(srvname) = upper(convert(sysname, substring( @26data, 40 + @cmd_data_len, @orig_srv_len )))
  5089.                 and dbname = substring( @26data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len )
  5090.             if @originator_id is null
  5091.             begin
  5092.                 insert into MSrepl_originators (publisher_database_id, srvname, dbname) values
  5093.                     (@publisher_database_id, substring( @26data, 40 + @cmd_data_len, @orig_srv_len ), substring( @26data, 40 + @cmd_data_len + @orig_srv_len, @orig_db_len ))
  5094.                 select @originator_id = @@identity
  5095.             end
  5096.         end
  5097.         else
  5098.             select @originator_id = 0
  5099.  
  5100.         -- Now insert into MSrepl_commands
  5101.         select @cmd_type = substring(@26data,29,4)
  5102.         if( @cmd_type in( 37,38 ) )
  5103.         begin
  5104.             select @artid = substring(@26data,21,4)
  5105.             select @cmd_type = 38 - @cmd_type
  5106.             select @xact_seqno = substring( @26data, 11, 10 )
  5107.             exec sp_MSset_syncstate @publisher_id, @publisher_db, @artid, @cmd_type, @xact_seqno  
  5108.             select @cmd_type = (38 - @cmd_type) | 0x80000000
  5109.         end
  5110.  
  5111.         INSERT INTO MSrepl_commands VALUES (@publisher_database_id, 
  5112.             substring(@26data,11 ,10),
  5113.             @cmd_type, 
  5114.             substring(@26data,21 ,4), 
  5115.             @originator_id, 
  5116.             substring(@26data,25 ,4), 
  5117.             convert(bit,substring(@26data,33 ,1)), 
  5118.             substring(@26data,40,@cmd_data_len) )
  5119.     end
  5120.  
  5121.  
  5122.     IF @@ERROR <> 0
  5123.       return (1)
  5124.  
  5125. go
  5126.  
  5127.  
  5128. raiserror(15339,-1,-1,'sp_MSvalidate_distpublisher')
  5129. go
  5130. CREATE PROCEDURE sp_MSvalidate_distpublisher
  5131. @publisher sysname,
  5132. @publisher_id smallint = NULL OUTPUT
  5133. as
  5134.  
  5135.     set nocount on
  5136.  
  5137.     declare @distribution_db sysname
  5138.     declare @retcode int
  5139.  
  5140.     -- Check if publisher is a defined as a distribution publisher at this distributor
  5141.     select @publisher_id = srvid from master.dbo.sysservers where UPPER(srvname) = UPPER(@publisher) 
  5142.     if @publisher_id is NULL
  5143.     begin
  5144.         raiserror (14080, 11, -1)
  5145.         return (1)
  5146.     end
  5147.  
  5148.     if not exists (select * from msdb..MSdistpublishers where UPPER(name) = UPPER(@publisher))
  5149.     begin
  5150.         raiserror (14080, 11, -1)
  5151.         return (1)
  5152.     end
  5153.  
  5154.  
  5155.     -- Check if client is in the correct distribution database
  5156.     exec @retcode = dbo.sp_helpdistributor @publisher = @publisher, @distribdb = @distribution_db OUTPUT
  5157.     if @@error <> 0 OR @retcode <> 0
  5158.     begin
  5159.         raiserror (14071, 16, -1)
  5160.         return (1)
  5161.     end
  5162.  
  5163.     -- Check if publisher is associated with a distribution database
  5164.     if @distribution_db is NULL
  5165.     begin
  5166.         raiserror (14071, 16, -1)
  5167.         return(1)
  5168.     end
  5169.  
  5170.     -- Check if client is in the distribution database 
  5171.     if @distribution_db <> db_name()
  5172.     begin
  5173.         raiserror(14071, 16, -1)
  5174.         return(1)
  5175.     end
  5176.  
  5177. go
  5178.  
  5179. raiserror(15339,-1,-1,'sp_MSdrop_distribution_agent')
  5180. GO
  5181. CREATE PROCEDURE sp_MSdrop_distribution_agent (
  5182.     @publisher_id smallint,
  5183.     @publisher_db sysname,
  5184.     @publication sysname,
  5185.     @subscriber_id smallint,
  5186.     @subscriber_db sysname,
  5187.     @subscription_type int,
  5188.     @keep_for_last_run          bit = 0
  5189. AS
  5190. BEGIN
  5191.  
  5192.     SET NOCOUNT ON
  5193.  
  5194.     /*
  5195.     ** Declarations.
  5196.     */
  5197.     DECLARE @stopcode       int
  5198.             ,@retcode        int
  5199.             ,@job_id         binary(16)
  5200.             ,@is_continuous  bit
  5201.             ,@local_job      bit
  5202.             ,@publisher      sysname
  5203.             ,@schedule_name  sysname
  5204.             ,@job_command    nvarchar(512)
  5205.             ,@name           nvarchar(100)
  5206.             ,@agent_id       int
  5207.             ,@queue_id        sysname
  5208.             ,@qservicestatus int
  5209.             ,@qservername    nvarchar(255)
  5210.  
  5211.     select @stopcode = 1
  5212.             ,@qservername = @@servername
  5213.             ,@job_id = job_id, @local_job = local_job, @name = name, @agent_id = id,
  5214.             @queue_id = queue_id
  5215.     FROM MSdistribution_agents WHERE
  5216.         publisher_id = @publisher_id AND
  5217.         publisher_db = @publisher_db AND
  5218.         publication = @publication and
  5219.         subscriber_id = @subscriber_id and
  5220.         subscriber_db = @subscriber_db and
  5221.         subscription_type = @subscription_type
  5222.     
  5223.     -- Delete Perfmon instance
  5224.     dbcc deleteinstance ("SQL Replication Distribution", @name)
  5225.  
  5226.     select @publisher = srvname from master..sysservers where srvid = @publisher_id
  5227.  
  5228.     -- Return if not exists
  5229.     IF @local_job IS NULL
  5230.         RETURN(0)
  5231.  
  5232.     BEGIN TRAN
  5233.  
  5234.     if ((@queue_id is not null) and (@queue_id != N'mssqlqueue'))
  5235.     begin
  5236.         -- Check if the MSMQ service is running, if not running, return with error
  5237.         exec @retcode = master.dbo.xp_controlqueueservice 
  5238.                             @control_command = 1,
  5239.                             @return_result = @qservicestatus output
  5240.         if (@retcode != 0 or @@error != 0)
  5241.         begin
  5242.             raiserror('sp_MSdrop_distribution_agent(debug): xp_controlqueueservice failed in check mode', 16, 1)
  5243.             GOTO UNDO
  5244.         end
  5245.         
  5246.         if (@qservicestatus != 1)
  5247.         begin
  5248.             raiserror('sp_MSdrop_distribution_agent(debug): MSMQ service not running', 16, 1)
  5249.             GOTO UNDO
  5250.         end
  5251.  
  5252.         --
  5253.         -- delete the local private queue
  5254.         -- If it is a named instance, then just use the MACHINENAME
  5255.         --
  5256.         if (charindex(N'\', @qservername) > 0)
  5257.             select @qservername = substring(@qservername, 1, charindex(N'\', @qservername) - 1)
  5258.             
  5259.         exec @retcode = master.dbo.xp_deleteprivatequeue @qservername, @queue_id
  5260.         IF @@ERROR != 0 or @retcode != 0
  5261.         BEGIN
  5262.             RAISERROR('Debug: xp_deleteprivatequeue failed', -1, -1) WITH NOWAIT
  5263.             GOTO UNDO
  5264.         END
  5265.     end
  5266.  
  5267.     IF @local_job = 1 and @keep_for_last_run = 0
  5268.     BEGIN
  5269.         IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  5270.         BEGIN
  5271.             EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  5272.             IF @@ERROR <> 0 or @retcode <> 0
  5273.                 GOTO UNDO
  5274.         END
  5275.     END
  5276.  
  5277.     IF @local_job = 1 and @keep_for_last_run = 1
  5278.     BEGIN
  5279.             select @job_command=command from msdb.dbo.sysjobsteps where job_id=@job_id and step_id=2
  5280.  
  5281.             if PATINDEX('%-[Cc][Oo][Nn][Tt][Ii][Nn][Uu][Oo][Uu][Ss]%', @job_command) > 0
  5282.                 begin
  5283.                     select @is_continuous = 1
  5284.                     create table #sqlstatus(status nvarchar(20))
  5285.                     insert into #sqlstatus (status) exec master.dbo.xp_servicecontrol 'QUERYSTATE', 'SQLServerAgent'
  5286.                     if exists (select * from #sqlstatus where status='Running.') 
  5287.                             exec @stopcode = msdb.dbo.sp_stop_job @job_id = @job_id
  5288.                                  if @@ERROR<>0 GOTO UNDO
  5289.                     drop table #sqlstatus   
  5290.                     if @stopcode=0 
  5291.                         waitfor delay '00:00:30'
  5292.                 end
  5293.             
  5294.             EXEC @retcode = msdb.dbo.sp_update_job @job_id=@job_id, @delete_level=3 -- NOTE: Run once, success or failure!
  5295.             IF @@ERROR <> 0 or @retcode <> 0
  5296.                 GOTO UNDO
  5297.         
  5298.             EXEC @retcode = msdb.dbo.sp_delete_jobstep @job_id=@job_id, @step_id=3
  5299.             IF @@ERROR <> 0 or @retcode <> 0
  5300.                 GOTO UNDO
  5301.             EXEC @retcode = msdb.dbo.sp_delete_jobstep @job_id=@job_id, @step_id=1
  5302.             IF @@ERROR <> 0 or @retcode <> 0
  5303.                 GOTO UNDO
  5304.  
  5305.             select @job_command=command from msdb.dbo.sysjobsteps where job_id=@job_id and step_id=1        
  5306.             select @job_command = @job_command + ' -UnSubscribe 0 '  -- currently the value does not really matter
  5307.             
  5308.             EXEC @retcode = msdb.dbo.sp_update_jobstep @job_id=@job_id, @step_id=1, 
  5309.                                 @on_success_action=1, 
  5310.                                 @on_fail_action=2, 
  5311.                                 @command=@job_command
  5312.             IF @@ERROR <> 0 or @retcode <> 0
  5313.                 GOTO UNDO
  5314.  
  5315.             
  5316.             select @schedule_name = formatmessage(20532)
  5317.             EXEC @retcode = msdb.dbo.sp_update_jobschedule @job_id=@job_id, @name=@schedule_name, @freq_subday_type = 2, @freq_subday_interval=30
  5318.             IF @@ERROR<>0 or @retcode<>0
  5319.                 GOTO UNDO
  5320.             
  5321.             if (@is_continuous  = 1) and (@stopcode = 0)
  5322.                 begin
  5323.                     EXEC @retcode = msdb.dbo.sp_start_job @job_id=@job_id
  5324.                      if @@ERROR<>0 
  5325.                         GOTO UNDO
  5326.                 end
  5327.             /*
  5328.             ** The last run of this job will be as scheduled
  5329.             */
  5330.     END
  5331.  
  5332.     -- Remove agent entry
  5333.     DELETE MSdistribution_agents WHERE id = @agent_id
  5334.     IF @@ERROR <> 0 
  5335.         GOTO UNDO
  5336.  
  5337.     -- Remove associated history 
  5338.     DELETE MSdistribution_history WHERE agent_id = @agent_id
  5339.     IF @@ERROR <> 0 
  5340.         GOTO UNDO
  5341.  
  5342.     -- Update global replication status table
  5343.     EXEC dbo.sp_MSupdate_replication_status
  5344.         @publisher,
  5345.         @publisher_db,
  5346.         @publication,
  5347.         @agent_type = 3,
  5348.         @agent_name = @name,
  5349.         @status = -1    -- delete status
  5350.  
  5351.     COMMIT TRAN
  5352.  
  5353.     RETURN(0)
  5354.  
  5355. UNDO:
  5356.     if @@TRANCOUNT = 1
  5357.         ROLLBACK TRAN
  5358.     else
  5359.         COMMIT TRAN
  5360.     return(1)
  5361. END
  5362. GO
  5363.  
  5364. raiserror(15339,-1,-1,'sp_MSdrop_distribution_agentid')
  5365. GO
  5366. CREATE PROCEDURE sp_MSdrop_distribution_agentid (
  5367.     @agent_id int
  5368. ) AS
  5369.  
  5370.  
  5371.     SET NOCOUNT ON
  5372.  
  5373.     /*
  5374.     ** Declarations.
  5375.     */
  5376.     DECLARE @name           nvarchar(100)
  5377.     DECLARE @publisher      sysname
  5378.     DECLARE @publisher_db   sysname
  5379.     DECLARE @publication    sysname
  5380.  
  5381.     SELECT @name = name, @publisher = srvname, @publisher_db = publisher_db, @publication = publication FROM 
  5382.         MSdistribution_agents, master..sysservers WHERE 
  5383.         id = @agent_id and
  5384.         srvid = publisher_id
  5385.     
  5386.     -- Delete Perfmon instance
  5387.     dbcc deleteinstance ("SQL Replication Distribution", @name)
  5388.  
  5389.     -- Mask agent type, do this before deletion of the row
  5390.     declare @agent_type int
  5391.     set @agent_type = dbo.fn_MSmask_agent_type (@agent_id, 3)
  5392.  
  5393.     -- Remove agent entry
  5394.     DELETE MSdistribution_agents WHERE id = @agent_id
  5395.     IF @@ERROR <> 0 
  5396.         return 1
  5397.  
  5398.  
  5399.     -- Update global replication status table
  5400.     EXEC dbo.sp_MSupdate_replication_status
  5401.         @publisher,
  5402.         @publisher_db,
  5403.         @publication,
  5404.         @publication_type = 1,
  5405.         @agent_type = @agent_type,
  5406.         @agent_name = @name,
  5407.         @status = -1    -- delete status
  5408.  
  5409.     return 0
  5410.  
  5411. GO
  5412.  
  5413. raiserror(15339,-1,-1,'sp_MSdrop_qreader_agent')
  5414. GO
  5415. CREATE PROCEDURE sp_MSdrop_qreader_agent (
  5416.     @agent_id int
  5417. ) AS
  5418. BEGIN
  5419.     SET NOCOUNT ON
  5420.     --
  5421.     -- Declarations.
  5422.     --
  5423.     DECLARE @retcode        int
  5424.     DECLARE @job_id         binary(16)
  5425.     DECLARE @name           nvarchar(100)
  5426.     DECLARE @database        sysname
  5427.  
  5428.     select @database = db_name()
  5429.  
  5430.     -- get the agent and job ids
  5431.     SELECT @job_id = job_id, @name = name
  5432.     FROM MSqreader_agents 
  5433.     WHERE id = @agent_id        
  5434.  
  5435.     if (@agent_id is NULL)
  5436.         return (0)
  5437.                     
  5438.     -- Delete Perfmon instance
  5439.     dbcc deleteinstance ('SQL Replication QueueReader', @name)
  5440.  
  5441.     BEGIN TRAN sp_MSdrop_qreader_agent
  5442.  
  5443.     -- delete job for the agent
  5444.     IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  5445.     BEGIN
  5446.         EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  5447.         IF (@@ERROR != 0 or @retcode != 0)
  5448.             GOTO UNDO
  5449.     END
  5450.  
  5451.     -- Remove agent entry
  5452.     DELETE MSqreader_agents WHERE id = @agent_id        
  5453.     IF (@@ERROR != 0)
  5454.         GOTO UNDO
  5455.  
  5456.     -- Remove associated history 
  5457.     DELETE MSqreader_history 
  5458.     WHERE agent_id = @agent_id 
  5459.     IF (@@ERROR != 0)
  5460.         GOTO UNDO
  5461.  
  5462.     -- Update global replication status table
  5463.     EXEC dbo.sp_MSupdate_replication_status
  5464.         @@servername,
  5465.         @database,
  5466.         'ALL',
  5467.         @agent_type = 9,
  5468.         @agent_name = @name,
  5469.         @status = -1    -- delete status
  5470.  
  5471.     COMMIT TRAN sp_MSdrop_qreader_agent
  5472.     RETURN(0)
  5473.  
  5474. UNDO:
  5475.     ROLLBACK TRAN sp_MSdrop_qreader_agent
  5476.     return(1)
  5477. END
  5478. GO
  5479.  
  5480. raiserror(15339,-1,-1,'sp_MSdrop_qreader_history')
  5481. GO
  5482. CREATE PROCEDURE sp_MSdrop_qreader_history (
  5483.     @publication_id int
  5484. ) AS
  5485. BEGIN
  5486.     SET NOCOUNT ON
  5487.  
  5488.     -- Remove associated history 
  5489.     DELETE MSqreader_history 
  5490.     WHERE publication_id = @publication_id 
  5491.     IF (@@ERROR != 0)
  5492.         return (1)
  5493.     else
  5494.         return 0
  5495. END
  5496. GO
  5497.  
  5498. raiserror(15339,-1,-1,'sp_MSdrop_merge_agentid')
  5499. GO
  5500. CREATE PROCEDURE sp_MSdrop_merge_agentid (
  5501.     @agent_id int
  5502. ) AS
  5503.  
  5504.  
  5505.     SET NOCOUNT ON
  5506.  
  5507.     /*
  5508.     ** Declarations.
  5509.     */
  5510.     DECLARE @name           nvarchar(100)
  5511.     DECLARE @publisher      sysname
  5512.     DECLARE @publisher_db   sysname
  5513.     DECLARE @publication    sysname
  5514.  
  5515.     SELECT @name = name, @publisher = srvname, @publisher_db = publisher_db, @publication = publication FROM 
  5516.         MSmerge_agents, master..sysservers WHERE 
  5517.         id = @agent_id and
  5518.         srvid = publisher_id
  5519.     
  5520.     -- Delete Perfmon instance
  5521.     dbcc deleteinstance ("SQL Replication Merge", @name)
  5522.  
  5523.     -- Mask agent type, do this before delete the row.
  5524.     declare @agent_type int
  5525.     set @agent_type = dbo.fn_MSmask_agent_type (@agent_id, 4)
  5526.  
  5527.     -- Remove agent entry
  5528.     DELETE MSmerge_agents WHERE id = @agent_id
  5529.     IF @@ERROR <> 0 
  5530.         return 1
  5531.  
  5532.  
  5533.     -- Update global replication status table
  5534.     EXEC dbo.sp_MSupdate_replication_status
  5535.         @publisher,
  5536.         @publisher_db,
  5537.         @publication,
  5538.         @agent_type = @agent_type,
  5539.         @agent_name = @name,
  5540.         @status = -1    -- delete status
  5541.  
  5542.     return 0
  5543.  
  5544. GO
  5545.  
  5546. raiserror(15339,-1,-1,'sp_MSadd_qreader_agent')
  5547. GO
  5548. CREATE PROCEDURE sp_MSadd_qreader_agent (
  5549.     @name nvarchar(100) = NULL,
  5550.     @agent_id int = NULL OUTPUT,
  5551.     @agent_jobid binary(16) = NULL OUTPUT) 
  5552. AS
  5553. BEGIN
  5554.     SET NOCOUNT ON
  5555.  
  5556.     DECLARE @retcode                int
  5557.             ,@profile_id            int
  5558.             ,@category_name            sysname
  5559.             ,@database                sysname
  5560.  
  5561.     -- these are defaults used for sp_MSadd_repl_job
  5562.             ,@frequency_type int,
  5563.             @frequency_interval int,
  5564.             @frequency_relative_interval int,
  5565.             @frequency_recurrence_factor int,
  5566.             @frequency_subday int,
  5567.             @frequency_subday_interval int,
  5568.             @active_start_time_of_day int,
  5569.             @active_end_time_of_day int,
  5570.             @active_start_date int,
  5571.             @active_end_date int,
  5572.             @retryattempts int,
  5573.             @retrydelay int,
  5574.             @command nvarchar(4000)
  5575.             ,@jobname sysname
  5576.             ,@agent_name nvarchar(100)
  5577.  
  5578.     SELECT
  5579.         @frequency_type = 64,
  5580.         @frequency_interval = 1,
  5581.         @frequency_relative_interval = 1,
  5582.         @frequency_recurrence_factor  = 0,
  5583.         @frequency_subday = 4,
  5584.         @frequency_subday_interval = 5,
  5585.         @active_start_time_of_day = 0,
  5586.         @active_end_time_of_day = 235959,
  5587.         @active_start_date = 0,
  5588.         @active_end_date = 99991231,
  5589.         @retryattempts = 10,
  5590.         @retrydelay = 1
  5591.  
  5592.     --
  5593.     -- initialize
  5594.     --
  5595.     select @database = db_name()
  5596.             ,@agent_id = NULL
  5597.             ,@agent_jobid = NULL
  5598.  
  5599.     --
  5600.     -- Check for Agent entry
  5601.     --
  5602.     select top 1 @agent_id = id, @agent_name = name
  5603.     from dbo.MSqreader_agents
  5604.  
  5605.     --
  5606.     -- Check if we have any queue reader jobs for this database
  5607.     --
  5608.     select @agent_jobid = job.job_id
  5609.             ,@jobname = job.name 
  5610.     from msdb..sysjobs as job join msdb..sysjobsteps as step 
  5611.         on job.job_id = step.job_id 
  5612.             and job.category_id = 19
  5613.             and UPPER(job.originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName')))
  5614.             and step.subsystem = N'QueueReader' 
  5615.             and step.database_name = @database
  5616.  
  5617.     --
  5618.     -- begin tran
  5619.     --
  5620.     BEGIN TRAN sp_MSadd_qreader_agent
  5621.     
  5622.     --
  5623.     -- Check if we need to proceed
  5624.     -- add agent entry and job entry as required
  5625.     --
  5626.     if ((@agent_id IS NOT NULL) and (@agent_jobid IS NOT NULL))
  5627.     begin
  5628.         --
  5629.         -- we have an entry in MSqreader_agents and an entry in 
  5630.         -- msdb..sysjobs, make sure the names and jobid match
  5631.         --
  5632.         if (@agent_name != @jobname)
  5633.         begin
  5634.             --
  5635.             -- Update the agent name to be same as the job name
  5636.             --
  5637.             UPDATE MSqreader_agents SET name = @jobname WHERE id = @agent_id
  5638.             IF (@@ERROR != 0)
  5639.                 GOTO UNDO
  5640.         end
  5641.  
  5642.         if not exists (select * from MSqreader_agents
  5643.             where id = @agent_id and job_id = @agent_jobid)
  5644.         begin
  5645.             --
  5646.             -- Update the agent job_id if necessary
  5647.             --
  5648.             UPDATE MSqreader_agents SET job_id = @agent_jobid WHERE id = @agent_id
  5649.             IF (@@ERROR != 0)
  5650.                 GOTO UNDO
  5651.         end
  5652.  
  5653.         COMMIT TRAN sp_MSadd_qreader_agent
  5654.         RETURN(0)
  5655.     end
  5656.  
  5657.     --
  5658.     -- prepare the command
  5659.     -- Since this will always run on NT, use integrated security
  5660.     --
  5661.     select @command = N'-Distributor ' + quotename(@@SERVERNAME) 
  5662.                     + N' -DistributionDB ' + quotename(@database) 
  5663.                     + N' -DistributorSecurityMode 1 '
  5664.     
  5665.     SELECT @profile_id = profile_id
  5666.     FROM msdb..MSagent_profiles
  5667.     WHERE agent_type = 9
  5668.     AND def_profile = 1
  5669.  
  5670.     IF @profile_id IS NULL
  5671.         GOTO UNDO
  5672.  
  5673.     --
  5674.     -- Set the name
  5675.     --
  5676.     if (@name is NULL)
  5677.     begin
  5678.         select @name = case 
  5679.             when (@agent_name IS NULL and @jobname IS NULL) 
  5680.                 then quotename(@@servername) + '.' + cast(db_id() as nvarchar)
  5681.             when (@jobname IS NOT NULL)
  5682.                 then cast(@jobname as nvarchar(100))
  5683.                 else @agent_name
  5684.             end
  5685.     end
  5686.     else
  5687.     begin
  5688.         --
  5689.         -- we will override the user specified name if
  5690.         -- a job already exists
  5691.         --
  5692.         if (@jobname IS NOT NULL and @jobname != @name)
  5693.             select name = cast(@jobname as nvarchar(100))
  5694.     end
  5695.     
  5696.     --
  5697.     -- Insert row and Add Perfmoon instance only if needed
  5698.     --
  5699.     if (@agent_id IS NULL)
  5700.     begin
  5701.         INSERT INTO MSqreader_agents (name, profile_id) VALUES (@name, @profile_id)
  5702.         IF (@@ERROR != 0)
  5703.             GOTO UNDO
  5704.         SELECT @agent_id = @@IDENTITY
  5705.         dbcc addinstance ('SQL Replication QueueReader', @name)
  5706.     end
  5707.     else
  5708.     begin
  5709.         --
  5710.         -- update Agent name if necessary
  5711.         --
  5712.         if not exists (select * from MSqreader_agents 
  5713.             where id = @agent_id and name = @name) 
  5714.         begin
  5715.             UPDATE MSqreader_agents SET name = @name WHERE id = @agent_id
  5716.             IF (@@ERROR != 0)
  5717.                 GOTO UNDO
  5718.         end
  5719.     end
  5720.  
  5721.     --
  5722.     -- add the job if necessary
  5723.     -- For DMO scripting
  5724.     -- if the corresponding job for this agent does not exist we will 
  5725.     -- proceed and create the job (This is for the case when the user 
  5726.     -- generated the script at the publisher but did not re-create 
  5727.     -- repl jobs at the distributor.)
  5728.     --
  5729.     if (@agent_jobid IS NULL)
  5730.     begin
  5731.         -- Get Qreader category name (assumes category_id = 19)
  5732.         select @category_name = name FROM msdb.dbo.syscategories where category_id = 19
  5733.         
  5734.         EXECUTE @retcode = dbo.sp_MSadd_repl_job
  5735.             @name = @name,
  5736.             @subsystem = 'QueueReader',
  5737.             @server = @@SERVERNAME,
  5738.             @databasename = @database,
  5739.             @enabled = 1,
  5740.             @freqtype = @frequency_type,
  5741.             @freqinterval = @frequency_interval,
  5742.             @freqsubtype = @frequency_subday,
  5743.             @freqsubinterval = @frequency_subday_interval,
  5744.             @freqrelativeinterval = @frequency_relative_interval,
  5745.             @freqrecurrencefactor = 0,
  5746.             @activestartdate = @active_start_date,
  5747.             @activeenddate = @active_end_date,
  5748.             @activestarttimeofday = @active_start_time_of_day,
  5749.             @activeendtimeofday = @active_end_time_of_day,
  5750.             @nextrundate = 0,
  5751.             @nextruntime = 0,
  5752.             @runpriority = 0,
  5753.             @emailoperatorname = NULL,
  5754.             @retryattempts = @retryattempts,
  5755.             @retrydelay = @retrydelay,
  5756.             @command = @command,
  5757.             @loghistcompletionlevel = 0,
  5758.             @emailcompletionlevel = 0,
  5759.             @description = 'Reads queues for Queued updating subscriptions',
  5760.             @category_name = @category_name,
  5761.             @failure_detection = 1,
  5762.             @agent_id = @agent_id,
  5763.             @job_id = @agent_jobid OUTPUT
  5764.  
  5765.         IF (@@ERROR != 0 or @retcode != 0)
  5766.             GOTO UNDO
  5767.     end
  5768.     
  5769.     -- update agents table with the job id
  5770.     UPDATE MSqreader_agents SET job_id = @agent_jobid WHERE id = @agent_id
  5771.     IF (@@ERROR != 0)
  5772.         GOTO UNDO
  5773.  
  5774.     -- Update global replication status table
  5775.     EXEC @retcode = dbo.sp_MSupdate_replication_status
  5776.         @@servername,
  5777.         @database,
  5778.         'ALL',
  5779.         @agent_type = 9,
  5780.         @agent_name = @name,
  5781.         @status = 0     -- not running status
  5782.     IF (@@ERROR != 0 or @retcode != 0)
  5783.         GOTO UNDO
  5784.  
  5785.     COMMIT TRAN sp_MSadd_qreader_agent
  5786.     RETURN(0)
  5787.  
  5788. UNDO:
  5789.     --
  5790.     -- Since this proc is called from other SPs, doing
  5791.     -- a ROLLBACK can roll all the way to the top 
  5792.     -- so check for that and commit and return error code.
  5793.     -- the top level calling SP should do proper rollback
  5794.     -- based on returned error code
  5795.     --
  5796.     if (@@TRANCOUNT = 1)
  5797.         ROLLBACK TRAN sp_MSadd_qreader_agent
  5798.     else
  5799.         COMMIT TRAN sp_MSadd_qreader_agent
  5800.     return(1)
  5801. END
  5802. GO
  5803.  
  5804. raiserror(15339,-1,-1,'sp_MSadd_distribution_agent')
  5805. GO
  5806. CREATE PROCEDURE sp_MSadd_distribution_agent (
  5807.     @name sysname = NULL,
  5808.     @publisher_id smallint,
  5809.     @publisher_db sysname,
  5810.     @publication sysname,  
  5811.     @subscriber_id smallint,
  5812.     @subscriber_db sysname,
  5813.     @subscription_type int, -- have to have it to identify a distribution agent.
  5814.     @local_job bit, 
  5815.  
  5816.     @frequency_type int = 64,
  5817.     @frequency_interval int = 1,
  5818.     @frequency_relative_interval int = 1,
  5819.     @frequency_recurrence_factor int = 0,
  5820.     @frequency_subday int = 4,
  5821.     @frequency_subday_interval int = 5,
  5822.     @active_start_time_of_day int = 0,
  5823.     @active_end_time_of_day int = 235959,
  5824.     @active_start_date int = 0,
  5825.     @active_end_date int = 99991231,
  5826.  
  5827.     @retryattempts int = 10,
  5828.     @retrydelay int = 1,
  5829.     
  5830.     @command nvarchar(4000) = NULL,
  5831.     @agent_id int = NULL OUTPUT,
  5832.     @distribution_jobid binary(16) = NULL OUTPUT,
  5833.     @update_mode int = 0, 
  5834.  
  5835.     -- Agent offload
  5836.     @offloadagent bit = 0,
  5837.     @offloadserver sysname = NULL,
  5838.  
  5839.     @dts_package_name sysname = NULL,
  5840.     @dts_package_password nvarchar(524) = NULL,
  5841.     @dts_package_location int = 0
  5842. AS
  5843. BEGIN
  5844.     
  5845.     SET NOCOUNT ON
  5846.  
  5847.     /*
  5848.     ** Declarations.
  5849.     */
  5850.     DECLARE @retcode            int
  5851.     DECLARE @database           sysname
  5852.     DECLARE @profile_id         int
  5853.     DECLARE @distribution_type  int
  5854.     DECLARE @publisher          sysname
  5855.     DECLARE @category_name      sysname
  5856.     DECLARE @subscriber         sysname
  5857.     declare @publisher_database_id int
  5858.     declare @queue_id             sysname
  5859.             ,@qservicestatus    int
  5860.             ,@tries                tinyint
  5861.  
  5862.     /*
  5863.     ** Initializations
  5864.     */
  5865.     select @database = DB_NAME()
  5866.     
  5867.     -- Check the existance of the package if it is at the distributor side.
  5868.     if @dts_package_name is not null and @dts_package_location = 0
  5869.     begin
  5870.         exec @retcode = dbo.sp_MSrepl_validate_dts_package
  5871.             @name = @dts_package_name
  5872.         IF @@ERROR <> 0 or @retcode <> 0
  5873.             return (1)
  5874.     end
  5875.  
  5876.     -- if @name is not null, the proc is from DMO scripting
  5877.     -- check to see if the job is there or not, if not, reset @job_existing and
  5878.     -- @name values. This is for the case when the user generate the script at
  5879.     -- the publisher but did not re-create repl jobs at the distributor.
  5880.     if @local_job = 1 and @name is not null and 
  5881.        @name <> N''
  5882.     begin
  5883.         if not exists (select * from msdb..sysjobs_view where 
  5884.             name = @name and
  5885.             UPPER(originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName'))))
  5886.         begin
  5887.             set @name = null
  5888.         end
  5889.     end
  5890.  
  5891.     BEGIN TRAN
  5892.  
  5893.     -- Try to drop it first
  5894.     EXEC @retcode = dbo.sp_MSdrop_distribution_agent 
  5895.         @publisher_id = @publisher_id,
  5896.         @publisher_db = @publisher_db,
  5897.         @publication = @publication,
  5898.         @subscriber_id = @subscriber_id,
  5899.         @subscriber_db = @subscriber_db,
  5900.         @subscription_type = @subscription_type
  5901.     IF @@ERROR <> 0 or @retcode <> 0
  5902.         GOTO UNDO
  5903.  
  5904.     /* Code for distribution agent type in MSagent_profiles */
  5905.     SELECT @distribution_type = 3
  5906.  
  5907.     SELECT @profile_id = profile_id
  5908.     FROM msdb..MSagent_profiles
  5909.     WHERE agent_type = @distribution_type
  5910.         AND def_profile = 1
  5911.  
  5912.     IF @profile_id IS NULL
  5913.         GOTO UNDO
  5914.  
  5915.     select @publisher = srvname from master..sysservers where srvid = @publisher_id
  5916.     select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  5917.     select @publisher_database_id = id from MSpublisher_databases where 
  5918.         publisher_id = @publisher_id and
  5919.         publisher_db = @publisher_db
  5920.  
  5921.     -- Create queue if needed. (queued or failover mode)
  5922.     if (@update_mode in (2,3))
  5923.     begin
  5924.         -- Check if the MSMQ service is running
  5925.         exec @retcode = master.dbo.xp_controlqueueservice 
  5926.                             @control_command = 1,
  5927.                             @return_result = @qservicestatus output
  5928.         if (@retcode != 0 or @@error != 0)
  5929.         begin
  5930.             raiserror('sp_MSadd_distribution_agent(debug): xp_controlqueueservice failed in check mode', 16, 1)
  5931.             GOTO UNDO
  5932.         end
  5933.  
  5934.         if (@qservicestatus != 1)
  5935.         begin
  5936.             raiserror('sp_MSadd_distribution_agent(debug): MSMQ service not running. Start MSMQ services and retry subscription creation', 16, 1)
  5937.             GOTO UNDO
  5938.         end
  5939.  
  5940.         /***************************************************
  5941.         ***** For NOW we will not AUTOSTART MSMQ services
  5942.         ****************************************************
  5943.         if (@qservicestatus != 1)
  5944.         begin
  5945.             -- Queue service is not running. Try starting it only if it is
  5946.             -- stopped. Otherwise, return with error (we do not want to 
  5947.             -- handle the cases for Pause/Pending/Continue states)
  5948.             if (@qservicestatus = 2)
  5949.             begin
  5950.                 -- start the service
  5951.                 exec @retcode = master.dbo.xp_controlqueueservice 
  5952.                                     @control_command = 2,
  5953.                                     @return_result = @qservicestatus output
  5954.                 if (@retcode != 0 or @@error != 0)
  5955.                 begin
  5956.                     raiserror('sp_MSadd_distribution_agent(debug): xp_controlqueueservice failed in start mode', 16, 1)
  5957.                     GOTO UNDO
  5958.                 end
  5959.  
  5960.                 -- check status (try 3 times with 2 sec delays)
  5961.                 select @tries = 0
  5962.                 while ((@qservicestatus != 1) and (@tries < 3))
  5963.                 begin
  5964.                     WAITFOR DELAY '00:00:02'
  5965.                     select @tries = @tries + 1
  5966.                     
  5967.                     exec @retcode = master.dbo.xp_controlqueueservice 
  5968.                                         @control_command = 1,
  5969.                                         @return_result = @qservicestatus output
  5970.                     if (@retcode != 0 or @@error != 0)
  5971.                     begin
  5972.                         raiserror('sp_MSadd_distribution_agent(debug): xp_controlqueueservice failed in check mode', 16, 1)
  5973.                         GOTO UNDO
  5974.                     end                    
  5975.                 end
  5976.  
  5977.                 -- Did the service start
  5978.                 if (@qservicestatus != 1)
  5979.                 begin
  5980.                     raiserror('sp_MSadd_distribution_agent(debug): MSMQ service not running (delayed)', 16, 1)
  5981.                     GOTO UNDO
  5982.                 end
  5983.             end
  5984.             else
  5985.             begin
  5986.                 raiserror('sp_MSadd_distribution_agent(debug): MSMQ service not running (in transient state)', 16, 1)
  5987.                 GOTO UNDO
  5988.             end
  5989.         end
  5990.         ***************************************************/
  5991.  
  5992.         /******** 
  5993.         --
  5994.         -- create public queue
  5995.         --
  5996.         exec @retcode = master.dbo.xp_createqueue 
  5997.                             @publisher = @publisher,
  5998.                             @publisher_db = @publisher_db,
  5999.                             @publication = @publication, 
  6000.                             @subscriber = @subscriber,
  6001.                             @subscriber_db = @subscriber_db,
  6002.                             @queue_id = @queue_id output
  6003.         IF @@ERROR <> 0 or @retcode <> 0
  6004.         BEGIN
  6005.             RAISERROR('Debug: xp_createqueue failed', -1, -1) WITH NOWAIT
  6006.             GOTO UNDO
  6007.         END
  6008.         *******/
  6009.         --
  6010.         -- create local private queue
  6011.         --
  6012.         select @queue_id = cast(NEWID() as sysname)
  6013.         exec @retcode = master.dbo.xp_createprivatequeue @queue_id
  6014.         IF @@ERROR != 0 or @retcode != 0
  6015.         BEGIN
  6016.             select @queue_id = NULL
  6017.             RAISERROR('Debug: xp_createprivatequeue failed', -1, -1) WITH NOWAIT
  6018.             GOTO UNDO
  6019.         END
  6020.     end
  6021.     else if (@update_mode in (4,5))
  6022.     begin
  6023.         --
  6024.         -- SQL Queue being used
  6025.         --
  6026.         select @queue_id = N'mssqlqueue'
  6027.     end
  6028.  
  6029.     
  6030.     /* 
  6031.     ** Insert row
  6032.     */
  6033.     INSERT INTO MSdistribution_agents (name, publisher_database_id, publisher_id, publisher_db, publication, 
  6034.             subscriber_id, subscriber_db, subscription_type, local_job, 
  6035.             subscription_guid, profile_id, queue_id, 
  6036.             dts_package_name, dts_package_password, dts_package_location)
  6037.         VALUES ('',@publisher_database_id, @publisher_id, @publisher_db, @publication, 
  6038.             @subscriber_id, @subscriber_db, @subscription_type, @local_job, 
  6039.             newid(), @profile_id, @queue_id, 
  6040.             @dts_package_name, @dts_package_password, @dts_package_location)
  6041.     IF @@ERROR <> 0
  6042.         GOTO UNDO
  6043.     
  6044.     SELECT @agent_id = @@IDENTITY
  6045.  
  6046.     -- Add Perfmoon instance
  6047.     dbcc addinstance ("SQL Replication Distribution", @name)
  6048.  
  6049.     -- Set agent name
  6050.     if @subscriber is NULL select @subscriber = ''
  6051.     if @subscriber_db is NULL select @subscriber_db =''
  6052.     
  6053.     declare @job_existing bit
  6054.     
  6055.     IF @name IS NULL OR @name = N''
  6056.     BEGIN
  6057.         /*
  6058.         ** Sacrifice 1-2 character from each of (@publisher,@publication,
  6059.         ** @publisher_db,subscriber) to allow 4 more indentity digits in
  6060.         ** the distribution agent name. This will hopefully provide better
  6061.         ** guarantee of agent name uniqueness.
  6062.         */
  6063.         if @publication is NOT NULL and (LOWER(@publication)<>'all')
  6064.             SELECT @name = CONVERT(nvarchar(21),@publisher ) + '-' + 
  6065.                 CONVERT(nvarchar(21),@publisher_db) + '-' + 
  6066.                 CONVERT(nvarchar(21),@publication) + '-' + 
  6067.                 CONVERT(nvarchar(21),@subscriber) + '-' +
  6068.                 CONVERT(nvarchar, @@IDENTITY)
  6069.         else
  6070.             SELECT @name = CONVERT(nvarchar(28),@publisher ) + '-' + 
  6071.                 CONVERT(nvarchar(28),@publisher_db) + '-' + 
  6072.                 CONVERT(nvarchar(28),@subscriber) + '-' + 
  6073.                 CONVERT(nvarchar, @@IDENTITY)
  6074.  
  6075.         select @job_existing = 0
  6076.     END
  6077.     else
  6078.         select @job_existing = 1
  6079.  
  6080.     -- If creating a new job and the generated name already exists, re-generate the name with a 
  6081.     -- guid appended
  6082.     IF  @job_existing = 0
  6083.     BEGIN
  6084.         IF EXISTS (SELECT * FROM msdb..sysjobs_view 
  6085.                     WHERE name = @name 
  6086.                       AND UPPER(originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName'))))
  6087.         BEGIN
  6088.             if @publication is NOT NULL and (LOWER(@publication)<>'all')
  6089.                 SELECT @name = fn_repluniquename(newid(), @publisher, @publisher_db, 
  6090.                     @publication, @subscriber)
  6091.             else
  6092.                 SELECT @name = fn_repluniquename(newid(), @publisher, @publisher_db, 
  6093.                     @subscriber, null)
  6094.         END            
  6095.     END
  6096.  
  6097.     IF @local_job = 1
  6098.     BEGIN
  6099.         if @job_existing = 0
  6100.         begin
  6101.     --    *******WORKAROUND*******
  6102.             DECLARE @nullchar nchar(20)
  6103.             SELECT @nullchar = NULL
  6104.     --    *******WORKAROUND*******
  6105.             -- Get Distribution category name (assumes category_id = 10)
  6106.             select @category_name = name FROM msdb.dbo.syscategories where category_id = 10
  6107.  
  6108.             if @frequency_recurrence_factor is null
  6109.                 select @frequency_recurrence_factor = 0
  6110.  
  6111.             EXECUTE @retcode = dbo.sp_MSadd_repl_job
  6112.             @name = @name,
  6113.             @subsystem = 'Distribution',
  6114.             @server = @@SERVERNAME,
  6115.             @databasename = @database,
  6116.             @enabled = 1,
  6117.             @freqtype = @frequency_type,
  6118.             @freqinterval = @frequency_interval,
  6119.             @freqsubtype = @frequency_subday,
  6120.             @freqsubinterval = @frequency_subday_interval,
  6121.             @freqrelativeinterval = @frequency_relative_interval,
  6122.             @freqrecurrencefactor = @frequency_recurrence_factor,
  6123.             @activestartdate = @active_start_date,
  6124.             @activeenddate = @active_end_date,
  6125.             @activestarttimeofday = @active_start_time_of_day,
  6126.             @activeendtimeofday = @active_end_time_of_day,
  6127.             @nextrundate = 0,
  6128.             @nextruntime = 0,
  6129.             @runpriority = 0,
  6130.             @emailoperatorname = NULL,
  6131.             @retryattempts = @retryattempts,
  6132.             @retrydelay = @retrydelay,
  6133.             @command = @command,
  6134.             @loghistcompletionlevel = 0,
  6135.             @emailcompletionlevel = 0,
  6136.             @description = NULL,
  6137.             @category_name = @category_name,
  6138.             @failure_detection = 1,
  6139.             @agent_id = @agent_id,
  6140.             @job_id = @distribution_jobid OUTPUT
  6141.  
  6142.            IF @@ERROR <> 0 or @retcode <> 0
  6143.                 GOTO UNDO
  6144.         end
  6145.         else
  6146.         begin
  6147.             select @distribution_jobid = job_id from msdb..sysjobs_view where 
  6148.                 name = @name and
  6149.                 UPPER(originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName')))
  6150.             if @distribution_jobid IS NULL
  6151.             begin
  6152.                 -- Message from msdb.dbo.sp_verify_job_identifiers
  6153.                 RAISERROR(14262, -1, -1, 'Job', @name)          
  6154.                 GOTO UNDO
  6155.             end
  6156.         end
  6157.     END
  6158.     ELSE 
  6159.     BEGIN
  6160.         -- Generate a job GUID for remote agents. This will be used by the UI to uniquely
  6161.         -- identify rows returned by the enums
  6162.         set @distribution_jobid = newid();
  6163.     END
  6164.  
  6165.     UPDATE MSdistribution_agents SET name = @name,
  6166.         job_id = @distribution_jobid WHERE
  6167.         id = @agent_id
  6168.  
  6169.     IF @@ERROR <> 0
  6170.         GOTO UNDO
  6171.  
  6172.     -- Don't call agent offload stuff for virtual agents.
  6173.     IF @local_job = 1 and @subscription_type = 0
  6174.     BEGIN    
  6175.         -- Add offload parameter to agent command line if necessary
  6176.         IF @offloadagent = 1 
  6177.         BEGIN
  6178.             EXEC @retcode = sp_MSenableagentoffload @job_id = @distribution_jobid,
  6179.                                            @offloadserver = @offloadserver
  6180.         END
  6181.         ELSE
  6182.         BEGIN
  6183.             EXEC @retcode = sp_MSdisableagentoffload @job_id = @distribution_jobid,
  6184.                                             @offloadserver = @offloadserver
  6185.         END
  6186.         IF @@ERROR <> 0 OR @retcode <> 0
  6187.             GOTO UNDO
  6188.  
  6189.     END
  6190.  
  6191.     -- Update global replication status table
  6192.     EXEC @retcode = dbo.sp_MSupdate_replication_status
  6193.         @publisher,
  6194.         @publisher_db,
  6195.         @publication,
  6196.         @agent_type = 3,
  6197.         @agent_name = @name,
  6198.         @status = 0     -- not running status
  6199.  
  6200.     IF @@ERROR <> 0 OR @retcode <> 0
  6201.         GOTO UNDO
  6202.  
  6203.     COMMIT TRAN
  6204.  
  6205.     RETURN(0)
  6206. UNDO:
  6207.     --
  6208.     -- delete the MSMQ queue if necessary
  6209.     --
  6210.     if (@update_mode in (2,3) and @queue_id IS NOT NULL)
  6211.     begin
  6212.         exec master.dbo.xp_deleteprivatequeue @@servername, @queue_id
  6213.     end
  6214.     
  6215.     if @@TRANCOUNT = 1
  6216.         ROLLBACK TRAN
  6217.     else
  6218.         COMMIT TRAN
  6219.     return(1)
  6220. END
  6221. GO
  6222.  
  6223. raiserror(15339,-1,-1,'sp_MSdrop_agent_entry')
  6224. GO
  6225. /*
  6226. ** This one is reserved for future use.
  6227. */
  6228. CREATE PROCEDURE sp_MSdrop_agent_entry (
  6229. @pub_srvid      smallint,
  6230. @pub_db_name    sysname,
  6231. @publication    sysname,
  6232. @sub_srvid      smallint,
  6233. @sub_db_name    sysname
  6234. ) AS
  6235. delete from MSmerge_agents where publisher_id = @pub_srvid AND publisher_db = @pub_db_name AND publication=@publication
  6236.                                     AND subscriber_id = @sub_srvid AND subscriber_db = @sub_db_name
  6237. if @@ERROR<>0 return (1)
  6238. return (0)
  6239. GO
  6240.  
  6241.  
  6242. raiserror(15339,-1,-1,'sp_MSdrop_merge_agent')
  6243. GO
  6244. CREATE PROCEDURE sp_MSdrop_merge_agent (
  6245.     @publisher          sysname,
  6246.     @publisher_db       sysname,
  6247.     @publication        sysname,
  6248.     @subscriber         sysname,
  6249.     @subscriber_db      sysname,
  6250.     @keep_for_last_run  bit = 0 -- if the agent needs to stay to run one more time; default is NO
  6251. ) AS
  6252.  
  6253.  
  6254.     SET NOCOUNT ON
  6255.  
  6256.     /*
  6257.     ** Declarations.
  6258.     */
  6259.     DECLARE @retcode    int
  6260.     DECLARE @job_id     binary(16)
  6261.     DECLARE @local_job  bit
  6262.     DECLARE @publisher_id smallint
  6263.     DECLARE @subscriber_id smallint
  6264.     DECLARE @job_command nvarchar(512)
  6265.     DECLARE @name nvarchar(100)
  6266.     DECLARE @agent_id   int
  6267.  
  6268.     /*
  6269.     ** Initializations
  6270.     */
  6271.     -- Get subscriber info
  6272.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  6273.     select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  6274.  
  6275.  
  6276.     SELECT @job_id = job_id, @local_job = local_job, @name = name, @agent_id = id FROM MSmerge_agents (updlock holdlock) 
  6277.     WHERE
  6278.         publisher_id = @publisher_id AND
  6279.         publisher_db = @publisher_db AND
  6280.         publication = @publication and
  6281.         subscriber_id = @subscriber_id and
  6282.         subscriber_db = @subscriber_db 
  6283.  
  6284.     -- Delete Perfmon instance
  6285.     dbcc deleteinstance ("SQL Replication Merge", @name)
  6286.  
  6287.     -- Return if not exists
  6288.     IF @local_job IS NULL
  6289.         RETURN(0)
  6290.  
  6291.     BEGIN TRAN
  6292.  
  6293.     IF @keep_for_last_run = 0
  6294.     BEGIN
  6295.         if @local_job=1
  6296.         begin
  6297.             IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  6298.             begin
  6299.                 EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  6300.                 IF @@ERROR <> 0 or @retcode <> 0
  6301.                     GOTO UNDO
  6302.             end
  6303.         end
  6304.     END
  6305.  
  6306.     IF @local_job = 1 and @keep_for_last_run = 1
  6307.     BEGIN
  6308.         IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  6309.         BEGIN
  6310.             EXEC @retcode = msdb.dbo.sp_update_job @job_id=@job_id, @delete_level=3 -- NOTE: Only once, success or failure!
  6311.             IF @@ERROR <> 0 or @retcode <> 0
  6312.                 GOTO UNDO
  6313.             EXEC @retcode = msdb.dbo.sp_delete_jobstep @job_id=@job_id, @step_id=3
  6314.             IF @@ERROR <> 0 or @retcode <> 0
  6315.                 GOTO UNDO
  6316.             EXEC @retcode = msdb.dbo.sp_delete_jobstep @job_id=@job_id, @step_id=1
  6317.             IF @@ERROR <> 0 or @retcode <> 0
  6318.                 GOTO UNDO
  6319.  
  6320.             select @job_command=command from msdb.dbo.sysjobsteps where job_id=@job_id and step_id=1        
  6321.             select @job_command = @job_command + ' -AgentType 4 '
  6322.             
  6323.             EXEC @retcode = msdb.dbo.sp_update_jobstep @job_id=@job_id, @step_id=1, 
  6324.                 @on_success_action = 1,
  6325.                 @on_fail_action = 2,
  6326.                 @command=@job_command
  6327.             IF @@ERROR <> 0 or @retcode <> 0
  6328.                 GOTO UNDO
  6329.         END
  6330.     END
  6331.  
  6332.     DELETE MSmerge_agents WHERE id = @agent_id
  6333.     IF @@ERROR <> 0 
  6334.         GOTO UNDO
  6335.  
  6336.     -- Remove history       
  6337.     DELETE MSmerge_history WHERE agent_id = @agent_id 
  6338.     IF @@ERROR <> 0 
  6339.         GOTO UNDO
  6340.  
  6341.     -- Update global replication status table
  6342.     EXEC dbo.sp_MSupdate_replication_status
  6343.         @publisher,
  6344.         @publisher_db,
  6345.         @publication,
  6346.         @agent_type = 4,
  6347.         @agent_name = @name,
  6348.         @status = -1    -- delete status 
  6349.  
  6350.     COMMIT TRAN
  6351.  
  6352.     RETURN(0)
  6353.  
  6354. UNDO:
  6355.     if @@TRANCOUNT = 1
  6356.         ROLLBACK TRAN
  6357.     else
  6358.         COMMIT TRAN
  6359.     return(1)
  6360. GO
  6361.  
  6362. raiserror(15339,-1,-1,'sp_MSgetagentoffloadinfo')
  6363. GO
  6364. CREATE PROCEDURE sp_MSgetagentoffloadinfo (
  6365.     @job_id     VARBINARY(16)
  6366.     ) AS
  6367.  
  6368.     SET NOCOUNT ON
  6369.     DECLARE @agenttype NVARCHAR(20)
  6370.     DECLARE @offload_enabled bit
  6371.     DECLARE @offload_server  sysname
  6372.     DECLARE @agent_table     sysname  -- For use in error message
  6373.     DECLARE @independent_agent bit
  6374.  
  6375.     SELECT @agenttype = NULL
  6376.     SELECT @agent_table = RTRIM(@@SERVERNAME) + N'.dbo.'
  6377.     SELECT @independent_agent = 0
  6378.         
  6379.     SELECT @agenttype = LOWER(subsystem)
  6380.       FROM msdb..sysjobsteps
  6381.      WHERE job_id = @job_id
  6382.        AND LOWER(subsystem) IN (N'distribution', N'merge')
  6383.  
  6384.     IF @agenttype IS NULL
  6385.     BEGIN
  6386.         RAISERROR(21134, 16, -1)
  6387.         RETURN 1
  6388.     END
  6389.  
  6390.     IF @agenttype = N'distribution'
  6391.     BEGIN
  6392.         SELECT @offload_enabled = offload_enabled, 
  6393.                @offload_server = offload_server 
  6394.           FROM dbo.MSdistribution_agents da
  6395.     INNER JOIN dbo.MSsubscriptions s 
  6396.             ON da.id = s.agent_id
  6397.          WHERE job_id = @job_id        
  6398.         SELECT @agent_table = @agent_table + N'MSdistribution_agents'
  6399.     END
  6400.     ELSE
  6401.     BEGIN
  6402.         SELECT @offload_enabled = offload_enabled, 
  6403.                @offload_server = offload_server
  6404.           FROM dbo.MSmerge_agents
  6405.          WHERE job_id = @job_id 
  6406.         SELECT @agent_table = @agent_table + N'MSmerge_agents'
  6407.     END
  6408.  
  6409.     IF @@ROWCOUNT = 0
  6410.     BEGIN
  6411.         RAISERROR(21135, 16, -1, @agent_table)
  6412.         RETURN 1
  6413.     END
  6414.  
  6415.     IF @agenttype = N'distribution'
  6416.     BEGIN
  6417.         SELECT 'offload_enabled' = @offload_enabled,
  6418.                'offload_server' = @offload_server,
  6419.                'independent_agent' = @independent_agent
  6420.     END
  6421.     ELSE
  6422.     BEGIN
  6423.         SELECT 'offload_enabled' = @offload_enabled,
  6424.                'offload_server' = @offload_server
  6425.     END
  6426.  
  6427.     RETURN 0
  6428. GO
  6429.  
  6430. raiserror(15339,-1,-1,'sp_MSadd_merge_agent')
  6431. GO
  6432. CREATE PROCEDURE sp_MSadd_merge_agent (
  6433. -- not null if from scripting
  6434.     @name                           sysname = NULL,
  6435.     @publisher                      sysname,                    /* Publisher server */
  6436.     @publisher_db                   sysname,                    /* Publisher database */
  6437.     @publication                    sysname,                    /* Publication name */
  6438.     @subscriber                     sysname,                    /* Subscriber server */
  6439.     @subscriber_db                  sysname,                    /* Subscription database */
  6440.     @local_job                      bit,
  6441.     @frequency_type                 int = NULL,
  6442.     @frequency_interval             int = NULL,             
  6443.     @frequency_relative_interval    int = NULL, 
  6444.     @frequency_recurrence_factor    int = NULL, 
  6445.     @frequency_subday               int = NULL,
  6446.     @frequency_subday_interval      int = NULL,    
  6447.     @active_start_time_of_day       int = NULL, 
  6448.     @active_end_time_of_day         int = NULL,         
  6449.     @active_start_date              int = NULL, 
  6450.     @active_end_date                int = NULL,
  6451.     @optional_command_line          nvarchar(255) = '',     /* Optional command line arguments */
  6452.     @merge_jobid                    binary(16) = NULL OUTPUT,
  6453.     -- Agent offload
  6454.     @offloadagent                   bit = 0,
  6455.     @offloadserver                  sysname = NULL,
  6456.     @subscription_type              int = 0 -- 0 = push, 1 = pull
  6457.     ) AS
  6458.  
  6459.     SET NOCOUNT ON
  6460.  
  6461.     /*
  6462.     ** Declarations.
  6463.     */
  6464.     declare @retcode        int
  6465.     DECLARE @publisher_id   smallint
  6466.     DECLARE @subscriber_id  smallint
  6467.     DECLARE @profile_id     int
  6468.     DECLARE @merge_type     int
  6469.     DECLARE @command        nvarchar(4000)
  6470.  
  6471.     DECLARE @subscriber_security_mode       int                 /* 0 standard; 1 integrated */
  6472.     DECLARE @subscriber_login               sysname 
  6473.     DECLARE @subscriber_password            nvarchar(524) 
  6474.     DECLARE @subscriber_datasource_type     int     /* 0 SQL Server, 1 ODBC, 2 Jet, 3 OLEDB */
  6475.     DECLARE @distributor                    sysname 
  6476.     DECLARE @distributor_security_mode      int                     /* 0 standard; 1 integrated */
  6477.     DECLARE @distributor_login              sysname 
  6478.     DECLARE @distributor_password           nvarchar(524)
  6479.     DECLARE @database                       sysname
  6480.     DECLARE @agent_id                       int
  6481.     DECLARE @category_name                  sysname
  6482.     DECLARE @dsn_subscriber                 tinyint
  6483.     DECLARE @jet_subscriber                 tinyint
  6484.     DECLARE @oledb_subscriber               tinyint
  6485.     DECLARE @exchange_subscriber            tinyint
  6486.     DECLARE @oracle_subscriber              tinyint
  6487.     DECLARE @db2universal_subscriber        tinyint
  6488.     DECLARE @platform_nt                    binary
  6489.     DECLARE @provider_name                    sysname
  6490.  
  6491.     set @subscriber_security_mode = 1
  6492.     set @subscriber_login = NULL
  6493.     set @subscriber_password = NULL
  6494.     set @distributor = @@SERVERNAME
  6495.  
  6496.     set @dsn_subscriber = 1    /* Const: subscriber type 'dsn' */ 
  6497.     set @jet_subscriber = 2   
  6498.     set @oledb_subscriber = 3 
  6499.     set @exchange_subscriber = 4
  6500.     set @oracle_subscriber = 5 
  6501.     set @db2universal_subscriber = 6
  6502.  
  6503.     set @platform_nt = 0x1  
  6504.     
  6505.     -- Set null @optional_command_line to empty string to avoid string concat problem
  6506.     if @optional_command_line is null
  6507.         set @optional_command_line = ''
  6508.     else
  6509.         set @optional_command_line = N' ' + LTRIM( RTRIM(@optional_command_line) ) + N' '
  6510.  
  6511.     -- Get subscriber security context
  6512.     select  @subscriber_security_mode = security_mode,
  6513.             @subscriber_login = login,
  6514.             @subscriber_password = password
  6515.         from MSsubscriber_info where
  6516.             UPPER(publisher) = UPPER(@publisher) and
  6517.             UPPER(subscriber) = UPPER(@subscriber)
  6518.             
  6519.     -- Always use integrated security on winNT
  6520.     if (@platform_nt = platform() & @platform_nt )
  6521.         set @distributor_security_mode = 1
  6522.     else
  6523.     begin
  6524.         select  @distributor_security_mode = 0,
  6525.                 @distributor_login  = login,
  6526.                 @distributor_password = password
  6527.             from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername)
  6528.     end
  6529.     
  6530.     /*
  6531.     ** Initializations
  6532.     */
  6533.     -- Get subscriber info
  6534.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  6535.     select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  6536.  
  6537.     select @subscriber_datasource_type = type
  6538.         from MSsubscriber_info 
  6539.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  6540.  
  6541.     /*
  6542.     ** Jet and Oracle subscribers are actually added to MSsubscriber_info as OLE DB subscribers,
  6543.     ** since they can be used in transactional replication also.
  6544.     ** Map the type to Jet or Oracle based on OLE DB provider name.
  6545.     */
  6546.     if (@subscriber_datasource_type = @oledb_subscriber) 
  6547.     BEGIN
  6548.         select @provider_name = providername from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  6549.         if (upper(@provider_name) = 'MICROSOFT.JET.OLEDB.4.0')
  6550.             select @subscriber_datasource_type = @jet_subscriber
  6551.         else if (upper(@provider_name) = 'MSDAORA')
  6552.             select @subscriber_datasource_type = @oracle_subscriber
  6553.         else if (upper(@provider_name) = 'DB2OLEDB')
  6554.             select @subscriber_datasource_type = @db2universal_subscriber
  6555.     END
  6556.     
  6557.     if (@subscriber_datasource_type IS NULL)
  6558.         select @subscriber_datasource_type = 0
  6559.  
  6560.     -- if @name is not null, the proc is from DMO scripting
  6561.     -- check to see if the job is there are not, if not, reset @job_existing and
  6562.     -- @name values. This is for the case when the user generate the script at
  6563.     -- the publisher but did not re-create repl jobs at the distributor.
  6564.     if @local_job = 1 and @name is not null and 
  6565.        @name <> N''
  6566.     begin
  6567.         if not exists (select * from msdb..sysjobs_view where 
  6568.             name = @name and
  6569.             UPPER(originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName'))))
  6570.         begin
  6571.             set @name = null
  6572.         end
  6573.     end
  6574.  
  6575.     BEGIN TRAN
  6576.  
  6577.     -- Try to drop it first
  6578.     EXEC dbo.sp_MSdrop_merge_agent 
  6579.         @publisher = @publisher,
  6580.         @publisher_db = @publisher_db,
  6581.         @publication = @publication,
  6582.         @subscriber = @subscriber,
  6583.         @subscriber_db = @subscriber_db
  6584.           
  6585.     IF @@ERROR <> 0
  6586.         GOTO UNDO
  6587.  
  6588.     /* Code for merge agent type in MSagent_profiles */
  6589.     SELECT @merge_type = 4
  6590.  
  6591.     SELECT @profile_id = profile_id
  6592.     FROM msdb..MSagent_profiles
  6593.     WHERE agent_type = @merge_type
  6594.         AND def_profile = 1
  6595.  
  6596.     IF @profile_id IS NULL
  6597.         RETURN (1)
  6598.  
  6599.     /* 
  6600.     ** Insert row
  6601.     */
  6602.     INSERT INTO MSmerge_agents (name, publisher_id, publisher_db, publication, 
  6603.          subscriber_id, subscriber_db, local_job, profile_id)
  6604.          VALUES ('',@publisher_id, @publisher_db, @publication, 
  6605.          @subscriber_id, @subscriber_db, @local_job, @profile_id)
  6606.     IF @@ERROR <> 0
  6607.         GOTO UNDO
  6608.  
  6609.     set @agent_id = @@IDENTITY
  6610.     
  6611.     if @frequency_type is NULL
  6612.         set @frequency_type = 4     /* Daily */
  6613.     if @frequency_interval is NULL
  6614.         set @frequency_interval = 1
  6615.     if @frequency_relative_interval is NULL
  6616.         set @frequency_relative_interval = 1
  6617.     if @frequency_recurrence_factor is NULL
  6618.         set @frequency_recurrence_factor = 0
  6619.     if @frequency_subday is NULL
  6620.         set @frequency_subday = 8   /* Hour */
  6621.     if @frequency_subday_interval is NULL
  6622.         set @frequency_subday_interval = 1
  6623.     if @active_start_time_of_day is NULL
  6624.         set @active_start_time_of_day = 0
  6625.     if @active_end_time_of_day is NULL
  6626.         set @active_end_time_of_day = 235959
  6627.     if @active_start_date is NULL
  6628.         set @active_start_date = 0
  6629.     if @active_end_date is NULL
  6630.         set @active_end_date = 99991231
  6631.  
  6632.     declare @job_existing bit
  6633.     IF @name IS NULL OR @name = N''
  6634.     begin
  6635.         SELECT @name = CONVERT(nvarchar(21),@publisher ) + '-' + CONVERT(nvarchar(21),@publisher_db) + '-' + 
  6636.                         CONVERT(nvarchar(21),@publication) + '-' + CONVERT(nvarchar(21),@subscriber) + '-' +
  6637.                             CONVERT(nvarchar, @@IDENTITY)
  6638.         select @job_existing = 0
  6639.     end
  6640.     else
  6641.         select @job_existing = 1
  6642.     
  6643.     -- If creating a new job and the generated name already exists, re-generate the name with a 
  6644.     -- guid appended
  6645.     IF  @job_existing = 0
  6646.     BEGIN
  6647.         IF EXISTS (SELECT * FROM msdb..sysjobs_view 
  6648.                     WHERE name = @name 
  6649.                       AND UPPER(originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName'))))
  6650.         BEGIN
  6651.             SELECT @name = fn_repluniquename(newid(), @publisher, @publisher_db, 
  6652.                 @publication, @subscriber)
  6653.         END            
  6654.     END
  6655.  
  6656.     -- Add Perfmoon instance
  6657.     dbcc addinstance ("SQL Replication Merge", @name)
  6658.  
  6659.     IF @local_job = 1
  6660.     BEGIN
  6661.         if @job_existing = 0
  6662.         begin
  6663.  
  6664.             /* Construct task command */
  6665.  
  6666.             select @command = '-Publisher ' + QUOTENAME(@publisher) + ' -PublisherDB ' + QUOTENAME(@publisher_db) + ' '
  6667.             select @command = @command + '-Publication ' + QUOTENAME(@publication) + ' '
  6668.             select @command = @command + '-Subscriber ' + QUOTENAME(@subscriber)  + ' '
  6669.  
  6670.             if (@subscriber_datasource_type = 0)
  6671.                 select @command = @command + '-SubscriberDB ' + QUOTENAME(@subscriber_db) + ' '
  6672.         
  6673.             if (@subscriber_datasource_type <> 0)
  6674.                 select @command = @command + '-SubscriberType ' + convert(nvarchar(10),@subscriber_datasource_type) + ' '
  6675.     
  6676.             select @command = @command + @optional_command_line
  6677.             select @command = @command + '-Distributor ' + QUOTENAME(@distributor) + ' '
  6678.  
  6679.             select @command = @command + '-DistributorSecurityMode ' + 
  6680.                 convert(nvarchar(10),@distributor_security_mode) +  ' ' 
  6681.             if @distributor_security_mode <> 1
  6682.             begin
  6683.                 if @distributor_login is not NULL
  6684.                     select @command = @command + '-DistributorLogin ' + @distributor_login + ' '
  6685.                 if @distributor_password is not NULL
  6686.                     select @command = @command + '-DistributorEncryptedPassword ' + quotename(@distributor_password) + ' '
  6687.             end
  6688.  
  6689.             select @database = db_name()
  6690.  
  6691.             -- Get Merge category name (assumes category_id = 14)
  6692.             select @category_name = name FROM msdb.dbo.syscategories where category_id = 14
  6693.  
  6694.             EXEC @retcode = dbo.sp_MSadd_repl_job
  6695.                     @name = @name,
  6696.                     @subsystem = 'Merge',
  6697.                     @server = @@SERVERNAME,
  6698.                     @databasename = @database,
  6699.                     @enabled = 1,
  6700.                     @freqtype = @frequency_type,
  6701.                     @freqinterval = @frequency_interval,
  6702.                     @freqsubtype = @frequency_subday,
  6703.                     @freqsubinterval = @frequency_subday_interval,
  6704.                     @freqrelativeinterval = @frequency_relative_interval,
  6705.                     @freqrecurrencefactor = @frequency_recurrence_factor,
  6706.                     @activestartdate = @active_start_date,
  6707.                     @activeenddate = @active_end_date,
  6708.                     @activestarttimeofday = @active_start_time_of_day,
  6709.                     @activeendtimeofday = @active_end_time_of_day,
  6710.                     @command = @command,
  6711.                     @category_name = @category_name,
  6712.                     @failure_detection = 1,
  6713.                     @agent_id = @agent_id,
  6714.                     @retryattempts = 10,
  6715.                     @retrydelay = 1,
  6716.                     @job_id = @merge_jobid OUTPUT
  6717.             
  6718.             if @@ERROR <> 0 or @retcode <> 0
  6719.                 goto UNDO
  6720.         end
  6721.         else
  6722.         begin
  6723.             select @merge_jobid = job_id from msdb..sysjobs_view where 
  6724.                 name = @name and
  6725.                 UPPER(originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName')))
  6726.             if @merge_jobid IS NULL
  6727.             begin
  6728.                 -- Message from msdb.dbo.sp_verify_job_identifiers
  6729.                 RAISERROR(14262, -1, -1, 'Job', @name)          
  6730.                 GOTO UNDO
  6731.             end
  6732.         end
  6733.     END /* for local_job = 1 */
  6734.     ELSE 
  6735.     BEGIN
  6736.         -- Generate a job GUID for remote agents. This will be used by the UI to uniquely
  6737.         -- identify rows returned by the enums
  6738.         set @merge_jobid = newid();
  6739.     END
  6740.             
  6741.     UPDATE MSmerge_agents SET name = @name,
  6742.         job_id = @merge_jobid WHERE
  6743.         id = @agent_id
  6744.  
  6745.     IF @@ERROR <> 0
  6746.         GOTO UNDO
  6747.  
  6748.  
  6749.     IF @subscription_type = 0
  6750.     BEGIN
  6751.         -- Add offload parameter to agent command line if necessary
  6752.         IF @offloadagent = 1 
  6753.         BEGIN
  6754.             EXEC @retcode = sp_MSenableagentoffload @job_id = @merge_jobid,
  6755.                                             @offloadserver = @offloadserver
  6756.         END
  6757.         ELSE
  6758.         BEGIN
  6759.             EXEC @retcode = sp_MSdisableagentoffload @job_id = @merge_jobid,
  6760.                                             @offloadserver = @offloadserver 
  6761.         END
  6762.         IF @@ERROR <> 0 OR @retcode <> 0
  6763.             GOTO UNDO
  6764.  
  6765.     END
  6766.  
  6767.     -- Update global replication status table
  6768.     EXEC dbo.sp_MSupdate_replication_status
  6769.         @publisher,
  6770.         @publisher_db,
  6771.         @publication,
  6772.         @publication_type = 1, -- Merge 
  6773.         @agent_type = 4,
  6774.         @agent_name = @name,
  6775.         @status = 0     -- not running status
  6776.  
  6777.     COMMIT TRAN
  6778.  
  6779.     RETURN(0)
  6780.  
  6781. UNDO:
  6782.     if @@TRANCOUNT = 1
  6783.         ROLLBACK TRAN
  6784.     else
  6785.         COMMIT TRAN
  6786.     return(1)
  6787. GO
  6788.  
  6789. raiserror(15339,-1,-1,'sp_MSdrop_subscription')
  6790. GO
  6791. CREATE PROCEDURE sp_MSdrop_subscription
  6792. @publisher sysname,
  6793. @publisher_db sysname,
  6794. @subscriber sysname,
  6795. @article_id int = NULL,
  6796. @subscriber_db sysname = NULL,
  6797. @publication sysname = NULL,
  6798. @article sysname = NULL
  6799.  
  6800. as
  6801.  
  6802.     set nocount on
  6803.  
  6804.     declare @publisher_id smallint
  6805.     declare @subscriber_id smallint
  6806.     declare @name nvarchar (100)
  6807.     declare @retcode int
  6808.     declare @push tinyint
  6809.     declare @anonymous tinyint
  6810.     declare @keep_for_last_run bit
  6811.     declare @virtual smallint
  6812.     declare @virtual_anonymous smallint
  6813.     declare @independent_agent bit
  6814.     declare @publication_id int
  6815.     declare @subscription_type int
  6816.     declare @thirdparty_flag bit
  6817.     declare @id             int
  6818.     declare @publication_name sysname
  6819.     declare @queued_sub_precount int
  6820.  
  6821.     select @push = 0        -- const: push subscription type 
  6822.     select @anonymous = 2   -- const: push subscription type 
  6823.     select @virtual = -1    -- const: virtual subscriber id 
  6824.     select @virtual_anonymous = -2  -- const: virtual anonymous subscriber id 
  6825.  
  6826.     -- Select the current count of the queued subscribers prior to 
  6827.     -- dropping this subscription
  6828.     select @queued_sub_precount = count(*) from dbo.MSsubscriptions where update_mode in (2,3,4,5)
  6829.  
  6830.     -- Save off name for dummy status row
  6831.     select @publication_name = @publication
  6832.  
  6833.     -- Check if publisher is a defined as a distribution publisher in the current database
  6834.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  6835.     if @retcode <> 0
  6836.     begin
  6837.         return(1)
  6838.     end
  6839.  
  6840.     -- Check if subscriber exists
  6841.     if @subscriber is null
  6842.     begin
  6843.         select @subscriber_id = @virtual
  6844.         -- hardcoded in sp_MSadd_subscription
  6845.         select @subscriber_db = 'virtual'
  6846.     end
  6847.     else
  6848.         select @subscriber_id = srvid from master..sysservers, MSsubscriber_info where 
  6849.             UPPER(srvname) = UPPER(@subscriber) and
  6850.             UPPER(subscriber) = UPPER(@subscriber) and
  6851.             UPPER(publisher) = UPPER(@publisher)
  6852.     if @subscriber_id is NULL
  6853.     begin
  6854.         raiserror (20032, 16, -1, @subscriber, @publisher) 
  6855.         return (1)
  6856.     end
  6857.  
  6858.     -- If publication exists this is a post 6.x publisher
  6859.     if @publication is not NULL
  6860.     begin
  6861.         select @publication_id = publication_id,
  6862.                @thirdparty_flag = thirdparty_flag
  6863.             from MSpublications where
  6864.             publisher_id = @publisher_id and
  6865.             publisher_db = @publisher_db and
  6866.             publication = @publication
  6867.             
  6868.         -- Get article_id 
  6869.         if @article is not NULL and @article_id = 0
  6870.         begin
  6871.             select @article_id = article_id from MSarticles where 
  6872.                 publisher_id = @publisher_id and
  6873.                 publisher_db = @publisher_db and
  6874.                 publication_id = @publication_id and
  6875.                 article = @article
  6876.         end
  6877.         -- Check that subscription exists
  6878.         -- Only do the check for post 6x publisher
  6879.         if not exists (select * from MSsubscriptions where 
  6880.             publisher_id = @publisher_id and 
  6881.             publisher_db = @publisher_db and 
  6882.             publication_id = @publication_id and
  6883.             subscriber_id = @subscriber_id and
  6884.             subscriber_db = @subscriber_db)
  6885.         begin
  6886.             if @thirdparty_flag = 1
  6887.             begin
  6888.                 raiserror (14050, 16, -1)
  6889.                 return(1)
  6890.             end
  6891.             else
  6892.                 return (0)
  6893.         end
  6894.     end
  6895.  
  6896.     -- get the subscription type
  6897.     -- used when dropping dist agent
  6898.     select @subscription_type = subscription_type, 
  6899.         @independent_agent = independent_agent
  6900.         from MSsubscriptions where
  6901.         publisher_id = @publisher_id and
  6902.         publisher_db = @publisher_db and
  6903.         (publication_id = @publication_id or
  6904.          @publication_id is NULL) and
  6905.         (@article_id is NULL or
  6906.         article_id = @article_id) and
  6907.         (subscriber_id = @subscriber_id and
  6908.         (subscriber_db = @subscriber_db or @subscriber_id = @virtual))
  6909.  
  6910.     begin transaction
  6911.     save transaction MSdrop_subscription
  6912.  
  6913.     -- Delete the subscription 
  6914.     -- For anonymous type, delete virtual anonymous subscription also
  6915.     -- if deleting the  virtual subscription 
  6916.     -- (since there can be only one subscriber_id per article, subscriber_db doesn't matter)
  6917.     delete from MSsubscriptions where
  6918.         publisher_id = @publisher_id and
  6919.         publisher_db = @publisher_db and
  6920.         (publication_id = @publication_id or
  6921.          @publication_id is NULL) and
  6922.         (@article_id is NULL or
  6923.         article_id = @article_id) and
  6924.         ((subscriber_id = @subscriber_id and
  6925.         (subscriber_db = @subscriber_db or @subscriber_id = @virtual)) or
  6926.         -- Delete virtual anonymous subscription 
  6927.         -- if deleting virtual subscription for a anonymous publication
  6928.        (@subscriber_id = @virtual and subscriber_id = @virtual_anonymous))
  6929.  
  6930.     if @@error <> 0
  6931.     begin
  6932.         if @@trancount > 0
  6933.         begin
  6934.             rollback transaction MSdrop_subscription
  6935.             commit transaction  -- to finish off the tran we started in this proc (though 
  6936.                             -- work was rolled back to savepoint)
  6937.         end
  6938.         return 1
  6939.     end
  6940.     
  6941.     -- If it is the last subscription for the distribution agent, drop the dist agent
  6942.     if not exists (select * from MSsubscriptions    where
  6943.         publisher_id = @publisher_id and
  6944.         publisher_db = @publisher_db and
  6945.         (publication_id = @publication_id or
  6946.         @publication_id is NULL or
  6947.          @independent_agent = 0 ) and
  6948.         independent_agent = @independent_agent and
  6949.         subscriber_id = @subscriber_id and
  6950.         subscriber_db = @subscriber_db and
  6951.         subscription_type = @subscription_type)
  6952.     begin
  6953.         -- Harded coded in sp_MSadd_subscription.
  6954.         if @independent_agent = 0
  6955.             select @publication = 'ALL'
  6956.         /*
  6957.         ** Get agentid to check history record
  6958.         */
  6959.         select @id=id from MSdistribution_agents where 
  6960.         publisher_id = @publisher_id and
  6961.         publisher_db = @publisher_db and
  6962.         publication = @publication and
  6963.         subscriber_id = @subscriber_id and
  6964.         subscriber_db = @subscriber_db
  6965.  
  6966.     /*
  6967.     ** If the subscription has not yet been synced, there is no need for subscriber side cleanup 
  6968.     ** therefore no need for the last agent run.
  6969.     */
  6970.     if exists (select * from MSdistribution_history where agent_id = @id)
  6971.         select @keep_for_last_run = 0 -- default is not to do cleanup
  6972.     else 
  6973.         select @keep_for_last_run = 0
  6974.  
  6975.  
  6976.     /*
  6977.     ** Delete distribution task.
  6978.     */
  6979.         execute @retcode = dbo.sp_MSdrop_distribution_agent 
  6980.             @publisher_id = @publisher_id,
  6981.             @publisher_db = @publisher_db,
  6982.             @publication = @publication,
  6983.             @subscriber_id = @subscriber_id,
  6984.             @subscriber_db = @subscriber_db,
  6985.             @subscription_type = @subscription_type,
  6986.             @keep_for_last_run = @keep_for_last_run  
  6987.  
  6988.         if @@error <> 0 or @retcode <> 0
  6989.         begin
  6990.             if @@trancount > 0
  6991.             begin
  6992.                 rollback transaction MSdrop_subscription
  6993.                 commit transaction  -- to finish off the tran we started in this proc (though 
  6994.                                 -- work was rolled back to savepoint)
  6995.             end
  6996.             return 1
  6997.         end
  6998.     end
  6999.  
  7000.     
  7001.     -- Delete anonymous agents that are not in subscription table anymore
  7002.     -- It is due to dropping articles. Don't raise messages
  7003.     if @subscriber_id = @virtual
  7004.     begin
  7005.         delete MSdistribution_agents where
  7006.             anonymous_agent_id is not null and 
  7007.             not exists (select * from MSsubscriptions s where
  7008.                 s.agent_id = anonymous_agent_id)
  7009.  
  7010.  
  7011.         if @@error <> 0
  7012.         begin
  7013.             if @@trancount > 0
  7014.             begin
  7015.                 rollback transaction MSdrop_subscription
  7016.                 commit transaction  -- to finish off the tran we started in this proc (though 
  7017.                                 -- work was rolled back to savepoint)
  7018.             end
  7019.             return 1
  7020.         end
  7021.     end
  7022.  
  7023.  
  7024.     -- delete any rows in syncstate tracking table
  7025.  
  7026.     delete MSsync_states where 
  7027.         publisher_id = @publisher_id and
  7028.         publisher_db = @publisher_db and
  7029.         publication_id = @publication_id 
  7030.  
  7031.     if @@error <> 0
  7032.     begin
  7033.         if @@trancount > 0
  7034.         begin
  7035.             rollback transaction MSdrop_subscription
  7036.             commit transaction  -- to finish off the tran we started in this proc (though 
  7037.                             -- work was rolled back to savepoint)
  7038.         end
  7039.         return 1
  7040.     end
  7041.  
  7042.  
  7043.     commit transaction
  7044.  
  7045.     --  Add dummy distribution aent row entry for publication.  This will allow the status
  7046.     --  for the shared distribution agent to be restricted
  7047.     if @publication_name IS NOT NULL
  7048.     begin
  7049.         EXEC dbo.sp_MSupdate_replication_status
  7050.             @publisher,
  7051.             @publisher_db,
  7052.             @publication_name, 
  7053.             @agent_type = 3,   
  7054.             @agent_name = NULL, 
  7055.             @status = -1    -- delete
  7056.     end
  7057.  
  7058.     -- Refresh global status table. 
  7059.     EXEC dbo.sp_MSupdate_replication_status
  7060.         @publisher,
  7061.         @publisher_db,
  7062.         @publication = '%',    -- refresh the publisher node.
  7063.         @agent_type = NULL,    -- Not used    with @status = -2
  7064.         @agent_name = NULL, -- Not used with @status = -2
  7065.         @status = -2    -- refresh status
  7066.  
  7067.     -- Check to see if we need to drop the qreader agent
  7068.     if (@@error = 0 and @queued_sub_precount = 1 and
  7069.         not exists (select * from dbo.MSsubscriptions where update_mode in (2,3,4,5)))
  7070.     begin
  7071.         declare @agent_id int
  7072.         
  7073.         select top 1 @agent_id = id from dbo.MSqreader_agents
  7074.         if (@agent_id is not null)
  7075.             execute dbo.sp_MSdrop_qreader_agent @agent_id
  7076.     end    
  7077.  
  7078. GO
  7079.  
  7080. raiserror(15339,-1,-1,'sp_MSadd_subscription')
  7081. GO
  7082. CREATE PROCEDURE sp_MSadd_subscription
  7083. @publisher sysname,
  7084. @publisher_db sysname,
  7085. @subscriber sysname,       
  7086. @article_id int = NULL,
  7087. @subscriber_db sysname = NULL,
  7088. @status tinyint,                    -- 0 = inactive, 1 = subscribed, 2 = active 
  7089. @subscription_seqno varbinary(16),  -- publisher's database sequence number 
  7090.  
  7091. -- Post 6.5 parameters
  7092. @publication sysname = NULL,    -- 6.x publishers will not provide this
  7093. @article sysname = NULL,
  7094. @subscription_type tinyint = 0,     -- 0 = push, 1 = pull, 2 = anonymous 
  7095. @sync_type tinyint = 0,             -- 0 = none  1 = automatic snaphot  2 = no intial snapshot
  7096. @snapshot_seqno_flag bit = 0,       -- 1 = subscription seqno is the snapshot seqno
  7097.  
  7098. @frequency_type int = NULL,
  7099. @frequency_interval int = NULL,
  7100. @frequency_relative_interval int = NULL,
  7101. @frequency_recurrence_factor int = NULL,
  7102. @frequency_subday int = NULL,
  7103. @frequency_subday_interval int = NULL,
  7104. @active_start_time_of_day int = NULL,
  7105. @active_end_time_of_day int = NULL,
  7106. @active_start_date int = NULL,
  7107. @active_end_date int = NULL,
  7108. @optional_command_line nvarchar(4000) = '',
  7109.  
  7110. -- synctran
  7111. @update_mode tinyint = 0, -- 0 = read only, 1 = sync tran, 2 = queued tran, 
  7112.                           -- 3 = failover, 4 = sqlqueued tran, 5 = sqlqueued failover
  7113. @loopback_detection bit = 0,
  7114. @distribution_jobid binary(16) = NULL OUTPUT,
  7115.  
  7116. -- agent offload
  7117. @offloadagent  bit = 0,
  7118. @offloadserver sysname = NULL,
  7119.  
  7120. -- If agent is already created, the package name will be ignored.         
  7121. @dts_package_name sysname = NULL,
  7122. @dts_package_password nvarchar(524) = NULL,
  7123. @dts_package_location    int = 0,
  7124. @distribution_job_name sysname = NULL
  7125.  
  7126. as
  7127.  
  7128.     set nocount on
  7129.     declare @publisher_id smallint
  7130.     declare @subscriber_id smallint
  7131.     declare @command nvarchar (4000)
  7132.     declare @type tinyint
  7133.     declare @database sysname
  7134.     declare @long_name nvarchar (255)
  7135.     declare @retcode int
  7136.     declare @login sysname
  7137.     declare @password nvarchar(524)
  7138.     declare @retryattempts int
  7139.     declare @retrydelay int
  7140.     declare @virtual smallint                       -- const: virtual subscriber id 
  7141.     declare @virtual_anonymous smallint                 -- const: virtual anonymous subscriber id 
  7142.     declare @publication_str nvarchar (32)
  7143.     declare @agent_id int
  7144.     declare @publication_id int
  7145.     declare @independent_agent bit
  7146.     declare @allow_pull bit
  7147.     declare @active tinyint
  7148.  
  7149.     declare @flushfrequency int 
  7150.     declare @frequencytype int
  7151.     declare @frequencyinterval int 
  7152.     declare @frequencyrelativeinterval int
  7153.     declare @frequencyrecurrencefactor int 
  7154.     declare @frequencysubday int 
  7155.     declare @frequencysubdayinterval int
  7156.     declare @activestarttimeofday int
  7157.     declare @activeendtimeofday int
  7158.     declare @activestartdate int 
  7159.     declare @activeenddate int 
  7160.     DECLARE @dsn_subscriber tinyint
  7161.     DECLARE @jet_subscriber tinyint
  7162.     DECLARE @oledb_subscriber tinyint
  7163.     declare @thirdparty_flag bit
  7164.  
  7165.     DECLARE @distributor_security_mode      int                     /* 0 standard; 1 integrated */
  7166.     DECLARE @distributor_login              sysname 
  7167.     DECLARE @distributor_password           nvarchar(524)
  7168.     DECLARE @publisher_database_id int
  7169.     DECLARE @platform_nt binary
  7170.     declare @anonymous_agent_id int
  7171.     DECLARE @agent_name nvarchar(100)
  7172.     DECLARE @publication_name sysname
  7173.  
  7174.     -- Store off publication name for dummy monitor row
  7175.     select @publication_name = @publication
  7176.  
  7177.     -- Defined in sqlrepl.h
  7178.     -- Set null @optional_command_line to empty string to avoid string concat problem
  7179.     if @optional_command_line is null
  7180.         set @optional_command_line = ''
  7181.     else
  7182.         set @optional_command_line = N' ' + LTRIM( RTRIM(@optional_command_line) ) + N' '
  7183.  
  7184.     select @dsn_subscriber = 1    /* Const: subscriber type 'dsn' */ 
  7185.     select @jet_subscriber = 2   
  7186.     select @oledb_subscriber = 3   
  7187.  
  7188.     select @virtual = -1
  7189.     select @virtual_anonymous = -2
  7190.  
  7191.     select @active = 2
  7192.  
  7193.     select @platform_nt = 0x1
  7194.  
  7195.     -- Check if publisher is a defined as a distribution publisher in the current database
  7196.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  7197.     if @retcode <> 0 or @@error <> 0
  7198.     begin
  7199.         return(1)
  7200.     end
  7201.  
  7202.     -- Check if subscriber exists
  7203.     if @subscriber is null
  7204.     begin
  7205.       select @subscriber_id = @virtual
  7206.       -- The following 2 variables are hardcoded in sp_MSget_repl_cmds_anonymous 
  7207.       select @subscriber_db = 'virtual'
  7208.       select @subscription_type = 0
  7209.     end
  7210.     else
  7211.         select @subscriber_id = srvid from master..sysservers, MSsubscriber_info where 
  7212.             UPPER(srvname) = UPPER(@subscriber) and
  7213.             UPPER(subscriber) = UPPER(@subscriber) and
  7214.             UPPER(publisher) = UPPER(@publisher)
  7215.     if @subscriber_id is NULL
  7216.     begin
  7217.         raiserror (20032, 16, -1, @subscriber, @publisher) 
  7218.         return (1)
  7219.     end
  7220.     -- Special logic for 6.5 publisher.
  7221.     -- If publisher_id, publisher_db pair is not in MSpublisher_databases then add it.  This will be used
  7222.     -- to store a publisher_database_id in the MSrepl_transactions and MSrepl_commands table.
  7223.     if @publication is null
  7224.     begin
  7225.         if not exists (select * from MSpublisher_databases where publisher_id = @publisher_id and
  7226.             publisher_db = @publisher_db)
  7227.         begin
  7228.             insert into MSpublisher_databases (publisher_id, publisher_db) values (@publisher_id, @publisher_db)
  7229.             if @@error <> 0
  7230.                 goto UNDO
  7231.         end
  7232.     end
  7233.     
  7234.     -- Get publisher_database_id
  7235.     select @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and
  7236.         publisher_db = @publisher_db
  7237.     if @@error <> 0
  7238.         return 1
  7239.  
  7240.     -- If publication exists this is a post 6.x publisher
  7241.     if @publication is not NULL
  7242.     begin
  7243.         select @publication_id = publication_id, 
  7244.             @independent_agent = independent_agent, @allow_pull = allow_pull,
  7245.             @thirdparty_flag = thirdparty_flag from 
  7246.             MSpublications where 
  7247.             publisher_id = @publisher_id and
  7248.             publisher_db = @publisher_db and
  7249.             publication = @publication
  7250.         if @publication_id is NULL
  7251.         begin
  7252.             raiserror (20026, 11, -1, @publication)
  7253.             return (1)
  7254.         end
  7255.  
  7256.         -- Check if article_id exists
  7257.         if @article_id is not NULL 
  7258.         begin
  7259.             if not exists (select * from MSarticles where 
  7260.                 publisher_id = @publisher_id and
  7261.                 publisher_db = @publisher_db and
  7262.                 article_id = @article_id)
  7263.             begin
  7264.                 raiserror (20027, 11, -1, @article) 
  7265.                 return (1)
  7266.             end
  7267.         end
  7268.  
  7269.         -- Check if article exists
  7270.         if @article is not NULL and @article_id is NULL
  7271.         begin
  7272.             select @article_id = article_id from MSarticles where 
  7273.                 publisher_id = @publisher_id and
  7274.                 publisher_db = @publisher_db and
  7275.                 article = @article
  7276.             if @article_id is NULL
  7277.             begin
  7278.                 raiserror (20027, 11, -1, @article) 
  7279.                 return (1)
  7280.             end
  7281.         end
  7282.     end
  7283.     else
  7284.     begin   -- Set 6.x publishing values
  7285.         select @publication_id = 0
  7286.         select @independent_agent = 0
  7287.         select @allow_pull = 0
  7288.         select @thirdparty_flag = 0
  7289.     end
  7290.  
  7291.     -- Make sure subscription does not already exist
  7292.     if exists (select * from MSsubscriptions where 
  7293.         publisher_id = @publisher_id and 
  7294.         publisher_db = @publisher_db and 
  7295.         publication_id = @publication_id and
  7296.         article_id = @article_id and
  7297.         subscriber_id = @subscriber_id and
  7298.         subscriber_db = @subscriber_db)
  7299.     begin
  7300.         if @thirdparty_flag = 1
  7301.         begin
  7302.             raiserror (14058, 16, -1)
  7303.             return(1)
  7304.         end
  7305.         else
  7306.         begin
  7307.             exec @retcode = dbo.sp_MSdrop_subscription
  7308.                 @publisher = @publisher,
  7309.                 @publisher_db = @publisher_db,
  7310.                 @subscriber = @subscriber,
  7311.                 @article_id = @article_id,
  7312.                 @subscriber_db = @subscriber_db,
  7313.                 @publication = @publication,
  7314.                 @article = @article
  7315.             if @retcode <> 0 or @@error <> 0
  7316.             begin
  7317.                 return(1)
  7318.             end
  7319.         end
  7320.     end
  7321.  
  7322.     -- Check to see if we need to add a new distribution agent for the subscription.
  7323.     -- It is database wide for non independent agent publications, and publication wide otherwise.
  7324.     -- Check to see if the distribution agent for this subscription is already added.
  7325.  
  7326.     select @agent_id = NULL
  7327.     select @agent_id = agent_id from 
  7328.         MSsubscriptions where
  7329.         publisher_id = @publisher_id and
  7330.         publisher_db = @publisher_db and
  7331.         subscription_type = @subscription_type and
  7332.         (publication_id = @publication_id or @independent_agent = 0) and
  7333.         independent_agent = @independent_agent and 
  7334.         subscriber_id = @subscriber_id and
  7335.         subscriber_db = @subscriber_db
  7336.  
  7337.     if @subscriber_id = @virtual
  7338.     begin
  7339.         select @anonymous_agent_id = agent_id from 
  7340.             MSsubscriptions where
  7341.             publisher_id = @publisher_id and
  7342.             publisher_db = @publisher_db and
  7343.             subscription_type = @subscription_type and
  7344.             (publication_id = @publication_id or @independent_agent = 0) and
  7345.             independent_agent = @independent_agent and 
  7346.             subscriber_id = @virtual_anonymous and
  7347.             subscriber_db = @subscriber_db
  7348.     end
  7349.     
  7350.     -- Always use integrated security on winNT
  7351.     if (@platform_nt = platform() & @platform_nt )
  7352.         set @distributor_security_mode = 1
  7353.     else
  7354.     begin
  7355.         select  @distributor_security_mode = 0,
  7356.                 @distributor_login  = login,
  7357.                 @distributor_password = password
  7358.             from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername)
  7359.     end
  7360.  
  7361.     --Get default task parameter values from MSsubscriber_info 
  7362.     select @type = type
  7363.     from MSsubscriber_info 
  7364.     where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  7365.  
  7366.     -- Only SQL Server and OLEDB subscriber support dts
  7367.     if @dts_package_name is not null and @type not in (0, @oledb_subscriber)
  7368.     begin
  7369.         -- Only sqlserver or oledb sub are allowed
  7370.         raiserror(21170, 16, -1)
  7371.         return 1
  7372.     end
  7373.  
  7374.     begin tran
  7375.     save transaction MSadd_subscription
  7376.  
  7377.     if @agent_id is NOT NULL
  7378.     begin
  7379.         select @distribution_jobid = job_id from MSdistribution_agents
  7380.             where id = @agent_id
  7381.     end
  7382.     else
  7383.     begin
  7384.  
  7385.  
  7386.         -- Create distribution agent
  7387.         -- Do not create local job if
  7388.         -- 1. virtual subscription 
  7389.         -- 2. no subscriber information, return (6.x legacy)
  7390.         -- 3. pull (this sp will not be called for anonymous subscription)
  7391.  
  7392.         declare @local_job bit
  7393.  
  7394.         if @subscriber_id = @virtual or 
  7395.             not exists (select * from MSsubscriber_info where
  7396.                 UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)) OR 
  7397.             @subscription_type = 1 
  7398.  
  7399.             select @local_job = 0
  7400.         else
  7401.             select @local_job = 1
  7402.  
  7403.         -- 'ALL' is reserved for indication all publications
  7404.         -- Hardcoded in sp_MSenum*... 
  7405.         -- Note! @publication is overwritten
  7406.         
  7407.         if @independent_agent = 0
  7408.             select @publication = 'ALL'
  7409.  
  7410.         if @local_job = 1
  7411.         begin
  7412.             select 
  7413.                 @frequencytype = frequency_type,
  7414.                 @frequencyinterval = frequency_interval,
  7415.                 @frequencyrelativeinterval = frequency_relative_interval,
  7416.                 @frequencyrecurrencefactor = frequency_recurrence_factor,
  7417.                 @frequencysubday = frequency_subday,
  7418.                 @frequencysubdayinterval = frequency_subday_interval,
  7419.                 @activestarttimeofday = active_start_time_of_day,
  7420.                 @activeendtimeofday = active_end_time_of_day,
  7421.                 @activestartdate = active_start_date,
  7422.                 @activeenddate = active_end_date
  7423.             from MSsubscriber_schedule 
  7424.             where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0    
  7425.  
  7426.             if @frequency_type is null
  7427.                 select @frequency_type = @frequencytype
  7428.  
  7429.             if @frequency_interval  is null
  7430.                 select  @frequency_interval = @frequencyinterval
  7431.  
  7432.             if @frequency_relative_interval is null
  7433.                 select  @frequency_relative_interval = @frequencyrelativeinterval
  7434.  
  7435.             if @frequency_recurrence_factor is null
  7436.                 select  @frequency_recurrence_factor = @frequencyrecurrencefactor
  7437.  
  7438.             if @frequency_subday is null
  7439.                 select  @frequency_subday = @frequencysubday
  7440.  
  7441.             if @frequency_subday_interval is null
  7442.                 select  @frequency_subday_interval = @frequencysubdayinterval
  7443.  
  7444.             if @active_start_time_of_day is null
  7445.                 select  @active_start_time_of_day = @activestarttimeofday
  7446.  
  7447.             if @active_end_time_of_day is null
  7448.                 select  @active_end_time_of_day = @activeendtimeofday
  7449.  
  7450.             if @active_start_date is null
  7451.                 select  @active_start_date = @activestartdate
  7452.  
  7453.             if @active_end_date is null
  7454.                 select  @active_end_date = @activeenddate
  7455.  
  7456.             -- Construct task command 
  7457.             select @command = '-Subscriber ' + QUOTENAME(@subscriber)  + ' '
  7458.  
  7459.             declare @dsn_dbname sysname
  7460.             SELECT @dsn_dbname = formatmessage(20586)
  7461.             -- DSN subscribers don't have a subscriber db name.
  7462.             if @subscriber_db is not NULL --AND @type NOT IN( @dsn_subscriber,@jet_subscriber, @oledb_subscriber)
  7463.             -- 7.0 publisher still uses DSN. 8.0 publisher use localized '(default destination)'
  7464.             -- ActiveX may use unlocalized '(default destination)'
  7465.             AND @subscriber_db NOT IN( N'(default destination)', N'DSN', @dsn_dbname)
  7466.             begin
  7467.                 select @command = @command  + '-SubscriberDB ' + QUOTENAME(@subscriber_db) + ' '
  7468.             end
  7469.             select @command = @command + '-Publisher ' + QUOTENAME(@publisher) + ' '
  7470.             select @command = @command + '-Distributor ' + QUOTENAME(@@SERVERNAME) + ' '
  7471.  
  7472.             select @command = @command + '-DistributorSecurityMode ' + 
  7473.                 convert(nvarchar(10),@distributor_security_mode) +  ' ' 
  7474.             if @distributor_security_mode <> 1
  7475.             begin
  7476.                 if @distributor_login is not NULL
  7477.                     select @command = @command + '-DistributorLogin ' + @distributor_login + ' '
  7478.                 if @distributor_password is not NULL
  7479.                     select @command = @command + '-DistributorEncryptedPassword ' + quotename(@distributor_password) + ' '
  7480.             end
  7481.  
  7482.             if @independent_agent = 1
  7483.                 select @command = @command +'-Publication ' + QUOTENAME(@publication) + ' '
  7484.  
  7485.             if @publisher_db is not NULL
  7486.                 select @command = @command + '-PublisherDB ' + QUOTENAME(@publisher_db) + ' '
  7487.  
  7488.             if @type = @dsn_subscriber or @type = @oledb_subscriber
  7489.               select @command = @command + '-SubscriberType ' + convert (nvarchar(10),@type) + ' '
  7490.             
  7491.             if @dts_package_name is not null
  7492.               select @command = @command + '-UseDTS '
  7493.             
  7494.  
  7495.             -- 64 is auto-start. Agents should be in continuous mode. sp_MSadd_repl_job will append "-Continuous" to the end of command line
  7496.  
  7497.             if datalength(@command) + datalength(@optional_command_line) > 8000
  7498.             begin
  7499.                 RAISERROR(20018, 16, -1)
  7500.                 RETURN(1)
  7501.             end
  7502.             select @command = @command + @optional_command_line
  7503.             
  7504.             execute @retcode = dbo.sp_MSadd_distribution_agent
  7505.                 @publisher_id = @publisher_id,
  7506.                 @publisher_db = @publisher_db,
  7507.                 @publication = @publication,
  7508.                 @subscriber_id = @subscriber_id,
  7509.                 @subscriber_db = @subscriber_db,
  7510.                 @subscription_type = @subscription_type,
  7511.                 @local_job = @local_job,
  7512.                 @frequency_type = @frequency_type,
  7513.                 @frequency_interval = @frequency_interval,
  7514.                 @frequency_subday = @frequency_subday,
  7515.                 @frequency_subday_interval = @frequency_subday_interval,
  7516.                 @frequency_relative_interval = @frequency_relative_interval,
  7517.                 @frequency_recurrence_factor = @frequency_recurrence_factor,
  7518.                 @active_start_date = @active_start_date,
  7519.                 @active_end_date = @active_end_date,
  7520.                 @active_start_time_of_day = @active_start_time_of_day,
  7521.                 @active_end_time_of_day = @active_end_time_of_day,
  7522.                 @command = @command,
  7523.                 @agent_id = @agent_id OUTPUT,
  7524.                 @distribution_jobid = @distribution_jobid OUTPUT,
  7525.                 @update_mode = @update_mode,
  7526.                 @offloadagent = @offloadagent,
  7527.                 @offloadserver = @offloadserver,
  7528.                 @dts_package_name = @dts_package_name,
  7529.                 @dts_package_password = @dts_package_password,
  7530.                 @dts_package_location = @dts_package_location,
  7531.                 @name = @distribution_job_name
  7532.  
  7533.  
  7534.             if @@error <> 0 or @retcode <> 0
  7535.                 goto UNDO
  7536.         end
  7537.         else
  7538.         begin
  7539.             execute @retcode = dbo.sp_MSadd_distribution_agent
  7540.                 @publisher_id = @publisher_id,
  7541.                 @publisher_db = @publisher_db,
  7542.                 @publication = @publication,
  7543.                 @subscriber_id = @subscriber_id,
  7544.                 @subscriber_db = @subscriber_db,
  7545.                 @subscription_type = @subscription_type,
  7546.                 @local_job = @local_job,
  7547.                 @agent_id = @agent_id OUTPUT,
  7548.                 @distribution_jobid = @distribution_jobid OUTPUT,
  7549.                 @update_mode = @update_mode,
  7550.                 @offloadagent = @offloadagent,
  7551.                 @offloadserver = @offloadserver 
  7552.                 
  7553.                 -- Only push has distributor side package.
  7554.  
  7555.             if @@error <> 0 or @retcode <> 0
  7556.                 goto UNDO
  7557.         end
  7558.  
  7559.         if @subscriber_id = @virtual
  7560.         begin
  7561.             execute @retcode = dbo.sp_MSadd_distribution_agent
  7562.                 @publisher_id = @publisher_id,
  7563.                 @publisher_db = @publisher_db,
  7564.                 @publication = @publication,
  7565.                 @subscriber_id = @virtual_anonymous,
  7566.                 @subscriber_db = @subscriber_db,
  7567.                 @subscription_type = @subscription_type,
  7568.                 @local_job = @local_job,
  7569.                 @agent_id = @anonymous_agent_id OUTPUT,
  7570.                 @distribution_jobid = @distribution_jobid OUTPUT,
  7571.                 @update_mode = @update_mode
  7572.                 -- No need to specify offload parameters for virtual agents
  7573.                 -- No need to specify package name for virtual agents
  7574.         end
  7575.     end
  7576.  
  7577.     insert into MSsubscriptions values (@publisher_database_id, @publisher_id, @publisher_db, @publication_id,
  7578.         @article_id, @subscriber_id, @subscriber_db, @subscription_type, @sync_type, @status, 
  7579.         @subscription_seqno, @snapshot_seqno_flag, @independent_agent, getdate(), 
  7580.         -- synctran
  7581.         @loopback_detection, @agent_id, @update_mode, @subscription_seqno, @subscription_seqno)
  7582.     if @@error <> 0
  7583.         goto UNDO
  7584.  
  7585.     -- For shiloh, always add virtual anonymous entry for attach logic
  7586.     -- If anonymous publication, add "virtual anonymous" subscription
  7587.     -- when adding the virtual subscription
  7588.     if @subscriber_id = @virtual
  7589.     begin
  7590.         insert into MSsubscriptions values (@publisher_database_id, @publisher_id, @publisher_db, @publication_id,
  7591.             @article_id, @virtual_anonymous, @subscriber_db, @subscription_type, @sync_type, @status, 
  7592.             @subscription_seqno, @snapshot_seqno_flag, @independent_agent, getdate(), 
  7593.             -- synctran
  7594.             @loopback_detection, @anonymous_agent_id, @update_mode, @subscription_seqno, @subscription_seqno)
  7595.         if @@error <> 0
  7596.             goto UNDO
  7597.     end
  7598.  
  7599.     -- Check to see if we need to add a new qreader agent
  7600.     if (@update_mode in (2,3,4,5))
  7601.     begin
  7602.         --
  7603.         -- we can have only one agent for the distribution database
  7604.         --
  7605.         if not exists (select * from dbo.MSqreader_agents) 
  7606.         begin
  7607.             execute @retcode = dbo.sp_MSadd_qreader_agent
  7608.             if (@retcode != 0 or @@error != 0)
  7609.                 goto UNDO
  7610.         end
  7611.     end
  7612.     
  7613.     commit transaction
  7614.  
  7615.     --  Add dummy distribution aent row entry for publication.  This will allow the status
  7616.     --  for the shared distribution agent to be restricted
  7617.     if @publication_name IS NOT NULL
  7618.     begin
  7619.         select @agent_name = name from MSdistribution_agents where id = @agent_id
  7620.  
  7621.         if @agent_name IS NOT NULL
  7622.             EXEC dbo.sp_MSupdate_replication_status
  7623.                 @publisher,
  7624.                 @publisher_db,
  7625.                 @publication_name, 
  7626.                 @agent_type = 3,   
  7627.                 @agent_name = @agent_name, 
  7628.                 @status = -3    -- Use current agent_status
  7629.     end
  7630.  
  7631.     -- Refresh global status table. 
  7632.     EXEC dbo.sp_MSupdate_replication_status
  7633.         @publisher,
  7634.         @publisher_db,
  7635.         @publication = '%',    -- refresh the publisher node.
  7636.         @agent_type = NULL,    -- Not used    with @status = -2
  7637.         @agent_name = NULL, -- Not used with @status = -2
  7638.         @status = -2    -- refresh status
  7639.  
  7640.     return(0)
  7641.  
  7642. UNDO:
  7643.     if @@TRANCOUNT > 0
  7644.     begin
  7645.         ROLLBACK TRAN MSadd_subscription
  7646.         COMMIT TRAN
  7647.     end
  7648.     return(1)
  7649.  
  7650. GO
  7651.  
  7652. raiserror(15339,-1,-1,'sp_MSupdate_subscription')
  7653. GO
  7654. CREATE PROCEDURE sp_MSupdate_subscription
  7655. @publisher sysname,
  7656. @publisher_db sysname,
  7657. @subscriber sysname,
  7658. @article_id int,
  7659. @status int,
  7660. @subscription_seqno varbinary(16),
  7661. --post 6x
  7662. @destination_db sysname = '%'
  7663.  
  7664. as
  7665.     set nocount on
  7666.     declare @publisher_id smallint  
  7667.     declare @subscriber_id smallint
  7668.     declare @automatic tinyint
  7669.     declare @snapshot_seqno_flag bit
  7670.     declare @virtual smallint 
  7671.     declare @virtual_anonymous smallint 
  7672.     declare @retcode int
  7673.     declare @active tinyint
  7674.     declare @subscribed tinyint
  7675.     declare @agent_id int
  7676.     declare @sync_type tinyint
  7677.     declare @virtual_agent_id int
  7678.     declare @publication_id int
  7679.  
  7680.     select @automatic = 1
  7681.     select @virtual = - 1
  7682.     select @virtual_anonymous = - 2
  7683.     select @active = 2
  7684.     select @subscribed = 1
  7685.  
  7686.     -- Check if publisher is a defined as a distribution publisher in the current database
  7687.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  7688.     if @retcode <> 0
  7689.     begin
  7690.         return(1)
  7691.     end
  7692.  
  7693.     -- Check if subscriber exists
  7694.     if @subscriber is null
  7695.     begin
  7696.         select @subscriber_id = @virtual
  7697.         select @destination_db = '%'
  7698.     end
  7699.     else
  7700.         select @subscriber_id = srvid from master..sysservers, MSsubscriber_info where 
  7701.             UPPER(srvname) = UPPER(@subscriber) and
  7702.             UPPER(subscriber) = UPPER(@subscriber) and
  7703.             UPPER(publisher) = UPPER(@publisher)
  7704.     if @subscriber_id is NULL
  7705.     begin
  7706.         raiserror (20032, 16, -1, @subscriber, @publisher) 
  7707.         return (1)
  7708.     end
  7709.  
  7710.     begin tran
  7711.     save transaction MSupdate_subscription
  7712.  
  7713.     if @status = @active
  7714.     begin
  7715.         -- Activating the subscription
  7716.         /*
  7717.         **  It will be used by:
  7718.         **  1. no_sync subscriptions
  7719.         **  2. subscriptions on immediate_sync pub that are activate 
  7720.         **  using virtual subscritpions's snapshots.
  7721.         **  3. snapshot agents for 6.5 publishers
  7722.         */
  7723.         -- Get agent_id etc
  7724.         select @agent_id = agent_id, @sync_type = sync_type,
  7725.             @publication_id = publication_id
  7726.             from MSsubscriptions where
  7727.             publisher_id = @publisher_id and
  7728.             publisher_db = @publisher_db and
  7729.             article_id = @article_id and
  7730.             subscriber_id = @subscriber_id and 
  7731.             -- Use equal so 6.x publisher will get nothing (since @destination_db is '%')
  7732.             subscriber_db = @destination_db
  7733.  
  7734.         -- If immediate_sync publication and sync type is auto_sync
  7735.         -- Set the subscription_seqno and snapshot_seqno to be of the virtual subscription 
  7736.         -- for real subscription when activating the subscription.
  7737.         -- We have to do it for the whole publication to prevent the
  7738.         -- distribution agent from picking up partial snapshot transaction
  7739.         if  @subscriber IS NOT NULL AND
  7740.             @sync_type = @automatic and
  7741.             exists (select * from MSpublications p where
  7742.                 -- publication_id is unique across dist db
  7743.                 p.publication_id = @publication_id and
  7744.                 p.immediate_sync = 1 
  7745.                 )
  7746.         begin
  7747.             -- Get virtual agent_id
  7748.             select @virtual_agent_id = agent_id from MSsubscriptions where
  7749.                 publisher_id = @publisher_id and
  7750.                 publisher_db = @publisher_db and
  7751.                 article_id = @article_id and
  7752.                 subscriber_id = @virtual
  7753.  
  7754.             -- Note it is possible that the virtual subscriptions
  7755.             -- were deactivated during clean up.
  7756.             /* Update the subscription table for the whole publication */
  7757.             -- Note: You need to change sp_MSreset_subscription_seqno when you 
  7758.             -- change this query
  7759.             update MSsubscriptions  set 
  7760.                 snapshot_seqno_flag =  
  7761.                     (select subscription_seqno from MSsubscriptions rs2
  7762.                         where
  7763.                         rs2.agent_id = @virtual_agent_id and
  7764.                         rs2.article_id = rs1.article_id),
  7765.                 status =    
  7766.                     (select status from MSsubscriptions rs2
  7767.                         where
  7768.                         rs2.agent_id = @virtual_agent_id and
  7769.                         rs2.article_id = rs1.article_id),
  7770.                 -- Use current date rather than virtual sub date for the
  7771.                 -- calculation in cleanup 
  7772.                 subscription_time = getdate(),
  7773.                 subscription_seqno = 
  7774.                     (select subscription_seqno from MSsubscriptions rs2
  7775.                         where
  7776.                         rs2.agent_id = @virtual_agent_id and
  7777.                         rs2.article_id = rs1.article_id),
  7778.                 publisher_seqno = 
  7779.                     (select publisher_seqno from MSsubscriptions rs2
  7780.                         where
  7781.                         rs2.agent_id = @virtual_agent_id and
  7782.                         rs2.article_id = rs1.article_id),
  7783.                 ss_cplt_seqno = 
  7784.                     (select ss_cplt_seqno from MSsubscriptions rs2
  7785.                         where
  7786.                         rs2.agent_id = @virtual_agent_id and
  7787.                         rs2.article_id = rs1.article_id)
  7788.                 from MSsubscriptions rs1 where
  7789.                     agent_id = @agent_id and
  7790.                     sync_type = @automatic and
  7791.                     status = @subscribed            
  7792.             if @@ERROR <> 0
  7793.                 goto UNDO
  7794.         end
  7795.         else
  7796.         begin
  7797.             update MSsubscriptions set status = @status, subscription_time = getdate(), 
  7798.                 publisher_seqno = @subscription_seqno, ss_cplt_seqno = @subscription_seqno,
  7799.                 -- Have to do this. Refer to anonymous agent "no init sync" option logic above
  7800.                 -- and sp_MSset_snapshot_seqno.
  7801.                 snapshot_seqno_flag = 0 
  7802.                 where
  7803.                   publisher_id = @publisher_id and
  7804.                   publisher_db = @publisher_db and
  7805.                   article_id = @article_id and
  7806.                   ((@subscriber_id <> @virtual and (subscriber_id = @subscriber_id and ((@destination_db = N'%') or (subscriber_db = @destination_db)) )) or
  7807.                   -- Activate virtual_anonymous but NOT virtual
  7808.                   -- This is for no init option for anonymous agent
  7809.                   -- Refer to sp_addsubscription , sp_MSget_repl_cmds_anonymous
  7810.                   -- and sp_MSset_snapshot_seqno
  7811.                   (@subscriber_id =  @virtual and subscriber_id = @virtual_anonymous))
  7812.             if @@error <> 0
  7813.                 goto UNDO
  7814.         
  7815.             -- For 6.5 publishers.
  7816.             -- Snapshot agents of 6.5 publishers will call sp_changesubstatus which will
  7817.             -- RPC this stored procedure to activate the subscription. The RPC calls are
  7818.             -- not in one transaction.
  7819.             -- We have to do it for the whole publication to prevent the
  7820.             -- distribution agent from picking up partial snapshot transaction
  7821.  
  7822.             -- Get publication_id 
  7823.             -- The publication_id and sync type are set by SNAPSHOT agent 
  7824.             -- calling sp_MSset_snapshot_xact_seqno
  7825.             -- Don't do it if @subscriber_id is virtual to prevent virtual sub
  7826.             -- to be activated.
  7827.             if @destination_db = '%' and @subscriber_id <> @virtual
  7828.             begin
  7829.                 declare @publication_id_6x int
  7830.                 -- Get the publication_id.
  7831.                 -- Note that if the sync_type is not automatic, the publication_id
  7832.                 -- will be null. In this case, we will not do the later
  7833.                 -- update (we don't need to)
  7834.                 select top 1 @publication_id_6x = publication_id from MSsubscriptions 
  7835.                     where   publisher_id = @publisher_id and
  7836.                             publisher_db = @publisher_db and
  7837.                             subscriber_id = @subscriber_id and 
  7838.                             sync_type = @automatic and
  7839.                             article_id = @article_id
  7840.  
  7841.                 if @publication_id_6x <> NULL
  7842.                 begin
  7843.                     update MSsubscriptions set status = @status, subscription_time = getdate() 
  7844.                         where
  7845.                           publisher_id = @publisher_id and
  7846.                           publisher_db = @publisher_db and
  7847.                           subscriber_id = @subscriber_id and 
  7848.                           sync_type = @automatic and
  7849.                           publication_id = @publication_id_6x and
  7850.                           status <> @status
  7851.                     if @@error <> 0
  7852.                         goto UNDO
  7853.                 end
  7854.             end
  7855.         end
  7856.     end -- End activating the subscription
  7857.     else
  7858.     begin -- Deactivating the subscription or change it from 'subscribed' to 'initiated'
  7859.         /*
  7860.         **  If @status is @active, it will be used by:
  7861.         **  sp_reinitsubscription at publisher to reset the subscription status to 'subscribed'
  7862.         **  If @status is @initiated (2), it will be used by snapshot agent with 
  7863.         **  sp_MSactivate_auto_sub => sp_changesubstatus.
  7864.         */
  7865.         update MSsubscriptions set status = @status, 
  7866.                                    publisher_seqno = @subscription_seqno, 
  7867.                                    ss_cplt_seqno = @subscription_seqno
  7868.             where
  7869.             publisher_id = @publisher_id and
  7870.             publisher_db = @publisher_db and
  7871.             article_id = @article_id and
  7872.             ((@subscriber_id <> @virtual and (subscriber_id = @subscriber_id and ((@destination_db = N'%') or (subscriber_db = @destination_db)) )) or
  7873.             -- Deactivating both virtual and virtual anonymous
  7874.             (@subscriber_id =  @virtual and (subscriber_id = @virtual or (subscriber_id = @virtual_anonymous and
  7875.             -- When changing to @initiated, do not change activated virtual_anonymous_subscription.
  7876.             (@status = @subscribed or snapshot_seqno_flag = 0)))))
  7877.  
  7878.         if @@error <> 0
  7879.             goto UNDO
  7880.     end
  7881.  
  7882.     
  7883.     commit transaction
  7884.     return (0)
  7885.  
  7886. UNDO:
  7887.     if @@TRANCOUNT > 0
  7888.     begin
  7889.         ROLLBACK TRAN MSupdate_subscription
  7890.         COMMIT TRAN
  7891.     end
  7892.     return(1)
  7893. GO
  7894.  
  7895.  
  7896. declare @dbname sysname
  7897. select  @dbname = db_name()
  7898. execute('dump transaction ' +@dbname+ ' with no_log')
  7899.  
  7900. go
  7901.  
  7902. /*
  7903. **  Note: sp_MSget_repl_commands and sp_MSget_repl_count have very similar
  7904. **  queries. Any changes to one of them should be applied to all others.
  7905. */
  7906.  
  7907. raiserror(15339,-1,-1,'sp_MSget_repl_commands')
  7908. GO
  7909. CREATE PROCEDURE sp_MSget_repl_commands
  7910. @agent_id int,
  7911. @last_xact_seqno varbinary(16),
  7912. @get_count bit = 0,
  7913. @compatibility_level int = 7000000
  7914. as
  7915.  
  7916.     set nocount on
  7917.  
  7918.     declare @active_status tinyint
  7919.     declare @initiate_status tinyint
  7920.     declare @snapshot_bit int
  7921.     declare @synctran_type int
  7922.     declare @read_only tinyint
  7923.     declare @retcode int
  7924.     declare @publisher_database_id int
  7925.     declare @originator_id int
  7926.     declare @subscriber sysname
  7927.     declare @subscriber_db sysname
  7928.     declare @subscriber_id smallint
  7929.     declare @publisher_db sysname
  7930.     declare @publisher_id smallint
  7931.     declare @max_xact_seqno varbinary(16)
  7932.     declare @concurrent int
  7933.     declare @concurrent_c int
  7934.  
  7935.     select @read_only = 0
  7936.     select @active_status = 2
  7937.     select @initiate_status = 3
  7938.     select @snapshot_bit = 0x80000000
  7939.     -- in sqlrepl.h
  7940.     select @synctran_type = @snapshot_bit | 9
  7941.     select @concurrent = 3
  7942.     select @concurrent_c = 4
  7943.  
  7944.     -- Security Check
  7945.     -- @agent_id might be null when it comes from sp_MSget_repl_cmd_anonymous
  7946.     if @agent_id is not null
  7947.     begin
  7948.         exec @retcode = dbo.sp_MScheck_pull_access
  7949.             @agent_id = @agent_id,
  7950.             @agent_type = 0 -- distribution agent
  7951.         if @@error <> 0 or @retcode <> 0
  7952.             return (1)
  7953.     end
  7954.     
  7955.     -- Get publisher database id etc.
  7956.     SELECT @publisher_database_id = publisher_database_id,
  7957.         @publisher_db = publisher_db,
  7958.         @publisher_id = publisher_id,
  7959.         @subscriber_id = subscriber_id, @subscriber_db = subscriber_db
  7960.         from MSdistribution_agents where id = @agent_id
  7961.  
  7962.     -- Get the last xact_seqno on the pub db FIRST. It will
  7963.     -- be used as the upper bound for differnt queries. We have to do
  7964.     -- this to prevent transactions on new or changed subscriptions or
  7965.     -- with new orignator_id being skipped eigher by preselected query or
  7966.     -- preselected originator_id.
  7967.     -- Have to have readpast here to prevent the query be blocked by logreader
  7968.     -- (even before the first row to the dist agent).
  7969.     --
  7970.     -- Note:  DO NOT consider distcmds inserted for a concurrent snapshot
  7971.     -- These represent 'forward in time' xacts.  Skipping past these xacts
  7972.     -- can cause lost transactions!
  7973.     --
  7974.     -- Note2: consider adding new MSrepl_commands idx with keys:  
  7975.     -- publisher_database_id, command_id, type, xact_seqno
  7976.     --
  7977.     -- Note3: might be able to use replpostcmd + a LSN mapping token to 
  7978.     -- allow SS agent to post sync cmds to log instead of dist db.
  7979.     --
  7980.     select @max_xact_seqno = max(xact_seqno) from MSrepl_commands (READPAST)
  7981.       where 
  7982.          publisher_database_id = @publisher_database_id and
  7983.          command_id = 1 and
  7984.          type <> -2147483611
  7985.  
  7986.     -- If there's nothing to do, return here to avoid more queries.
  7987.     if @max_xact_seqno = @last_xact_seqno
  7988.     begin
  7989.         if @get_count = 1
  7990.         begin
  7991.             select 
  7992.                 'undelivered_commands' = convert(int, 0), 
  7993.                 'undelivered_transactions' = convert(int, 0) 
  7994.         end
  7995.         else
  7996.         begin
  7997.             select rc.xact_seqno, rc.partial_command, rc.type, 
  7998.                 rc.command_id, rc.command
  7999.                 from                
  8000.                     MSrepl_commands rc
  8001.                 where 0 = 1
  8002.             select @max_xact_seqno
  8003.         end
  8004.         return 0
  8005.     end
  8006.  
  8007.     -- Get subscriber name
  8008.     select @subscriber = srvname from master..sysservers where
  8009.         srvid = @subscriber_id
  8010.         
  8011.     -- Note: if no originator id in the table, it will be 0, so that no loop back
  8012.     -- detection will be done!.
  8013.     -- Since the logreader will insert into the MSrepl_originators table,
  8014.     -- this query has to be later then get max seqno query!!!!!
  8015.     --select @originator_id = 0
  8016.     select @originator_id = ISNULL(id, 0) from MSrepl_originators where
  8017.         publisher_database_id = @publisher_database_id and
  8018.         UPPER(srvname) = UPPER(@subscriber) and
  8019.         dbname = @subscriber_db
  8020.  
  8021.     if @get_count = 1
  8022.     begin
  8023.         select 
  8024.             'undelivered_commands' = count(*), 
  8025.             'undelivered_transactions' = count(distinct xact_seqno) from
  8026.  
  8027.         MSrepl_commands rc JOIN MSsubscriptions s
  8028.         ON (rc.article_id = s.article_id AND rc.publisher_database_id=s.publisher_database_id )
  8029.         
  8030.         where
  8031.  
  8032.         s.agent_id = @agent_id and
  8033.         s.status = @active_status and
  8034.         rc.publisher_database_id = @publisher_database_id and
  8035.         s.publisher_database_id = @publisher_database_id and
  8036.         rc.xact_seqno > @last_xact_seqno and
  8037.         rc.xact_seqno <= @max_xact_seqno and
  8038.         -- If log based transaction, we do
  8039.         -- 1. only select tran later than sub pub seqno
  8040.         -- 2. loopback detection
  8041.         (((rc.type & @snapshot_bit) <> @snapshot_bit and
  8042.         rc.xact_seqno > s.publisher_seqno and
  8043.         rc.xact_seqno > s.ss_cplt_seqno and
  8044.         --
  8045.         -- Loopback detection
  8046.         --
  8047.         (s.loopback_detection = 0 or
  8048.             (@originator_id != 0 and rc.originator_id <> @originator_id))) or 
  8049.         -- If snapshot transaction, we do
  8050.         -- 1. filter out the  snapshot transactions that were inserted later that is not
  8051.         -- the subscription's snapshot transaction
  8052.         -- 2. filter out trigger generation command for non synctran subscription.
  8053.         -- Note: don't do loop back detection.
  8054.         ((rc.type & @snapshot_bit) = @snapshot_bit and 
  8055.         rc.xact_seqno >= s.subscription_seqno and 
  8056.         rc.xact_seqno <= s.ss_cplt_seqno and
  8057.         (s.update_mode <> @read_only or rc.type <> @synctran_type))) and
  8058.         -- Filter out the new command types that we have introduced after 7.0
  8059.         (@compatibility_level > 7000000 or
  8060.         (rc.type & ~@snapshot_bit) not in 
  8061.         (25, 40, 45, 50, 51, 52, 53, 54, 55, 56 ,57, 58, 68, 69))
  8062.                 
  8063.         return(0)
  8064.     end
  8065.  
  8066.     -- if this agent is servicing any inactive concurrent sync articles
  8067.     -- then return no rows.  The concurrent sync article will be activated
  8068.     -- when the SYNCDONE token is written to the distribution db by the logreader
  8069.     -- at this point, all log records associated with the sync will be present in 
  8070.     -- MSrepl_commands
  8071.  
  8072.     if exists( SELECT * FROM MSsubscriptions s JOIN MSpublications p 
  8073.                ON(     s.publisher_id = p.publisher_id and
  8074.                     s.publisher_db = p.publisher_db and
  8075.                     s.publication_id = p.publication_id )
  8076.                WHERE
  8077.                 s.agent_id = @agent_id and
  8078.                 s.status = @initiate_status and
  8079.                 (p.sync_method = @concurrent or p.sync_method = @concurrent_c) )
  8080.     begin
  8081.         select rc.xact_seqno, rc.partial_command, rc.type, 
  8082.             rc.command_id, rc.command
  8083.             from                
  8084.                 MSrepl_commands rc
  8085.             where 0 = 1
  8086.         select @last_xact_seqno
  8087.         return 0
  8088.     end
  8089.  
  8090.     -- Decide on a best query method.
  8091.     -- Note: The order of the following queries is important and
  8092.     -- not abitrary.
  8093.     
  8094.     -- Get subscription info
  8095.     declare @num_non_active int
  8096.     declare @num_article int
  8097.     declare @num_loopback int
  8098.     declare @max_sub_seqno varbinary(16)
  8099.     declare @max_pub_seqno varbinary(16)
  8100.  
  8101.  
  8102.     select 
  8103.         @num_non_active = sum(case when status <> @active_status then 1 else 0 end),
  8104.         @num_article = count(*),
  8105.         @num_loopback   = sum(case when loopback_detection <> 0 then 1 else 0 end),
  8106.         @max_sub_seqno  = max(subscription_seqno),
  8107.         @max_pub_seqno = max(publisher_seqno)
  8108.         from MSsubscriptions where
  8109.             agent_id = @agent_id
  8110.  
  8111.     --select @num_non_active, @num_loopback, @max_sub_seqno
  8112.     
  8113.     if  @last_xact_seqno < @max_sub_seqno or  
  8114.         @last_xact_seqno < @max_pub_seqno or 
  8115.         @num_non_active <> 0
  8116.     -- The agent is still working on snapshot transactions. Need a full join in this case
  8117.     begin
  8118.         -- no loopback    
  8119.         if @originator_id = 0
  8120.         begin
  8121.             -- Join with every thing but no loop back
  8122.             select rc.xact_seqno, rc.partial_command, rc.type, 
  8123.                 rc.command_id, rc.command
  8124.                 from                
  8125.                     MSrepl_commands rc JOIN MSsubscriptions s
  8126.                 -- At end, we use the FASTFIRSTROW option which tends to force
  8127.                 -- a nested inner loop join driven from MSrepl_commands
  8128.                 ON (rc.article_id = s.article_id AND rc.publisher_database_id=s.publisher_database_id )
  8129.                 
  8130.                 where
  8131.  
  8132.                 s.agent_id = @agent_id and
  8133.                 s.status = @active_status and
  8134.                 rc.publisher_database_id = @publisher_database_id and
  8135.                 s.publisher_database_id = @publisher_database_id and
  8136.                 rc.xact_seqno > @last_xact_seqno and
  8137.                 rc.xact_seqno <= @max_xact_seqno and
  8138.                 -- If log based transaction, we do
  8139.                 -- 1. only select tran later than sub pub seqno
  8140.                 -- 2. only select tran later than ss_cplt_seqno 
  8141.                 (((rc.type & @snapshot_bit) <> @snapshot_bit and
  8142.                 rc.xact_seqno > s.publisher_seqno and
  8143.                 rc.xact_seqno > s.ss_cplt_seqno ) 
  8144.                 or 
  8145.                 -- If snapshot transaction, we do
  8146.                 -- 1. filter out the  snapshot transactions that were inserted later that is not
  8147.                 -- the subscription's snapshot transaction
  8148.                 -- 2. filter out trigger generation command for non synctran subscription.
  8149.                 -- Note: don't do loop back detection.
  8150.                 ((rc.type & @snapshot_bit) = @snapshot_bit and 
  8151.                 rc.xact_seqno >= s.subscription_seqno and 
  8152.                 rc.xact_seqno <= s.ss_cplt_seqno and
  8153.                 (s.update_mode <> @read_only or rc.type <> @synctran_type))) and
  8154.                 -- Filter out the new command types that we have introduced after 7.0
  8155.                 (@compatibility_level > 7000000 or
  8156.                 (rc.type & ~@snapshot_bit) not in 
  8157.                 (25, 40, 45, 50, 51, 52, 53, 54, 55, 56 ,57, 58, 68, 69))
  8158.                 order by rc.xact_seqno, rc.command_id asc
  8159.                 OPTION (FAST 1)
  8160.         end
  8161.         else
  8162.         begin
  8163.             -- Join with every thing with loop back
  8164.             select rc.xact_seqno, rc.partial_command, rc.type, 
  8165.                 rc.command_id, rc.command
  8166.                 from                
  8167.                     MSrepl_commands rc JOIN MSsubscriptions s
  8168.                 -- At end, we use the FASTFIRSTROW option which tends to force
  8169.                 -- a nested inner loop join driven from MSrepl_commands
  8170.                 ON (rc.article_id = s.article_id AND rc.publisher_database_id=s.publisher_database_id )
  8171.                 
  8172.                 where
  8173.  
  8174.                 s.agent_id = @agent_id and
  8175.                 s.status = @active_status and
  8176.                 rc.publisher_database_id = @publisher_database_id and
  8177.                 s.publisher_database_id = @publisher_database_id and
  8178.                 rc.xact_seqno > @last_xact_seqno and
  8179.                 rc.xact_seqno <= @max_xact_seqno and
  8180.                 -- If log based transaction, we do
  8181.                 -- 1. only select tran later than sub pub seqno
  8182.                 -- 2. loopback detection
  8183.                 (((rc.type & @snapshot_bit) <> @snapshot_bit and
  8184.                 rc.xact_seqno > s.publisher_seqno and
  8185.                 rc.xact_seqno > s.ss_cplt_seqno and
  8186.                 --
  8187.                 -- Loopback detection
  8188.                 --
  8189.                 (s.loopback_detection = 0 or
  8190.                     rc.originator_id <> @originator_id)) or 
  8191.                 -- If snapshot transaction, we do
  8192.                 -- 1. filter out the  snapshot transactions that were inserted later that is not
  8193.                 -- the subscription's snapshot transaction
  8194.                 -- 2. filter out trigger generation command for non synctran subscription.
  8195.                 -- Note: don't do loop back detection.
  8196.                 ((rc.type & @snapshot_bit) = @snapshot_bit and 
  8197.                 rc.xact_seqno >= s.subscription_seqno and 
  8198.                 rc.xact_seqno <= s.ss_cplt_seqno and
  8199.                 (s.update_mode <> @read_only or rc.type <> @synctran_type))) and
  8200.                 -- Filter out the new command types that we have introduced after 7.0
  8201.                 (@compatibility_level > 7000000 or
  8202.                 (rc.type & ~@snapshot_bit) not in 
  8203.                 (25, 40, 45, 50, 51, 52, 53, 54, 55, 56 ,57, 58, 68, 69))
  8204.                 order by rc.xact_seqno, rc.command_id asc
  8205.                 OPTION (FAST 1)
  8206.             end
  8207.     end
  8208.     -- The agent has finished snapshot transactions but it has loopback detection.
  8209.     else if @num_loopback <> 0 and @originator_id <> 0
  8210.     begin
  8211.         -- Join plus loopback
  8212.         select rc.xact_seqno, rc.partial_command, rc.type, 
  8213.             rc.command_id, rc.command
  8214.             from                
  8215.                 MSrepl_commands rc JOIN MSsubscriptions s
  8216.             -- At end, we use the FASTFIRSTROW option which tends to force
  8217.             -- a nested inner loop join driven from MSrepl_commands
  8218.             ON (rc.article_id = s.article_id)
  8219.             
  8220.             where
  8221.  
  8222.             s.agent_id = @agent_id and
  8223.             rc.publisher_database_id = @publisher_database_id and
  8224.             rc.xact_seqno > @last_xact_seqno and
  8225.             rc.xact_seqno <= @max_xact_seqno and
  8226.             (rc.type & @snapshot_bit) <> @snapshot_bit and
  8227.             (rc.type & ~@snapshot_bit) not in ( 37, 38 ) and
  8228.             --
  8229.             -- Loopback detection
  8230.             --
  8231.             (s.loopback_detection = 0 or
  8232.             rc.originator_id <> @originator_id) 
  8233.             order by rc.xact_seqno, rc.command_id asc
  8234.             OPTION (FAST 1)
  8235.     end
  8236.     -- The agent has finished snapshot transactions. It has NO loopback detection.
  8237.     else if @num_article <> (select count(*) from MSarticles  a where
  8238.         publisher_id = @publisher_id and
  8239.         publisher_db = @publisher_db)
  8240.     -- Not a full subscription, do mini join
  8241.     begin
  8242.         -- Mini join along. Only agent_id and article_id columns in MSsubscriptions
  8243.         -- are used. So only index pages are needed for the join.
  8244.         select rc.xact_seqno, rc.partial_command, rc.type, 
  8245.         rc.command_id, rc.command
  8246.         from                
  8247.             MSrepl_commands rc JOIN MSsubscriptions s
  8248.         -- At end, we use the FASTFIRSTROW option which tends to force
  8249.         -- a nested inner loop join driven from MSrepl_commands
  8250.         ON (rc.article_id = s.article_id)
  8251.         where
  8252.         s.agent_id = @agent_id and
  8253.         rc.publisher_database_id = @publisher_database_id and
  8254.         rc.xact_seqno > @last_xact_seqno and
  8255.         rc.xact_seqno <= @max_xact_seqno and
  8256.         (rc.type & @snapshot_bit) <> @snapshot_bit and
  8257.         (rc.type & ~@snapshot_bit) not in ( 37, 38 ) 
  8258.         order by rc.xact_seqno, rc.command_id asc
  8259.         OPTION (FAST 1)
  8260.     end
  8261.     else
  8262.     -- The query will fly if we reach here!! No join is needed.
  8263.     -- It is a full sub to pub db, the dist agent is beyond snapshots, 
  8264.     -- all sub are active and no loopback detection. 
  8265.     begin
  8266.         -- no join.
  8267.         select rc.xact_seqno, rc.partial_command, rc.type, 
  8268.         rc.command_id, rc.command
  8269.         from                
  8270.             MSrepl_commands rc 
  8271.         where
  8272.         rc.publisher_database_id = @publisher_database_id and
  8273.         rc.xact_seqno > @last_xact_seqno and
  8274.         rc.xact_seqno <= @max_xact_seqno and
  8275.         (rc.type & @snapshot_bit) <> @snapshot_bit and
  8276.         (rc.type & ~@snapshot_bit) not in ( 37, 38 ) 
  8277.         order by rc.xact_seqno, rc.command_id asc
  8278.     end 
  8279.  
  8280.     -- Return the max seqno of this batch to distribution agent.
  8281.     select @max_xact_seqno
  8282.  
  8283. GO
  8284.  
  8285.  
  8286.  
  8287. raiserror(15339,-1,-1,'sp_MSget_repl_cmds_anonymous')
  8288. GO
  8289. CREATE PROCEDURE sp_MSget_repl_cmds_anonymous
  8290. @agent_id int,
  8291. @last_xact_seqno varbinary(16),
  8292. @no_init_sync bit = 0,
  8293. @get_count bit = 0,
  8294. @compatibility_level int = 7000000
  8295.  
  8296. as
  8297.  
  8298.    set nocount on
  8299.  
  8300.    declare @virtual_agent_id int    /* virtual sub agent id */
  8301.    declare @anonymous_agent_id int  /* virtual anonymous agent id */
  8302.  
  8303.     -- Note @agent_id will be overwritten later.
  8304.     select  @virtual_agent_id =   virtual_agent_id,
  8305.             @anonymous_agent_id = anonymous_agent_id
  8306.         from MSdistribution_agents where
  8307.             id = @agent_id
  8308.     
  8309.     -- Return error if agent entry does not exists (being deleted).
  8310.     if @virtual_agent_id is null
  8311.     begin
  8312.         raiserror(21072, 16, -1)
  8313.         return(1)
  8314.     end
  8315.  
  8316.     -- If no init sync, use anonymous account to start immediately.
  8317.     -- If first time or right after reinit,  use virtual account. 
  8318.     -- otherwise use virtual anonymous account
  8319.     if  @no_init_sync = 1 
  8320.         select @agent_id = @anonymous_agent_id
  8321.     else if @last_xact_seqno = 0x00 
  8322.         select @agent_id = @virtual_agent_id
  8323.     else
  8324.         select @agent_id = @anonymous_agent_id
  8325.     -- Call main procedure to get commands
  8326.     exec dbo.sp_MSget_repl_commands 
  8327.         @agent_id = @agent_id,
  8328.         @last_xact_seqno = @last_xact_seqno,
  8329.         @get_count = @get_count,
  8330.         @compatibility_level = @compatibility_level
  8331. GO
  8332.  
  8333.  
  8334.  
  8335. raiserror(15339,-1,-1,'sp_MSanonymous_status')
  8336. GO
  8337. CREATE PROCEDURE sp_MSanonymous_status
  8338. @agent_id           int,
  8339. @no_init_sync       int = 0,
  8340. @last_xact_seqno varbinary(16)
  8341. as
  8342.  
  8343.    set nocount on
  8344.  
  8345.    declare @virtual_agent_id int    /* virtual sub agent id */
  8346.    declare @anonymous_agent_id int  /* virtual anonymous agent id */
  8347.  
  8348.     -- Note @agent_id will be overwritten later.
  8349.     select  @virtual_agent_id =   virtual_agent_id,
  8350.             @anonymous_agent_id = anonymous_agent_id
  8351.         from MSdistribution_agents where
  8352.             id = @agent_id
  8353.     
  8354.     -- Return error if agent entry does not exists (being deleted).
  8355.     if @virtual_agent_id is null
  8356.     begin
  8357.         raiserror(21072, 16, -1)
  8358.         return(1)
  8359.     end
  8360.  
  8361.     -- If no init sync, use anonymous account to start immediately.
  8362.     -- If first time, or still working on the first snapshot, or just finished
  8363.     -- the first snapshot, use virtual account. This is to cover the case
  8364.     -- of multiple snapshot transactions (for example, one per article) in the first
  8365.     -- snapshot.
  8366.     -- otherwise use virtual anonymous account
  8367.     if  @no_init_sync = 1 
  8368.         select @agent_id = @anonymous_agent_id
  8369.     else if @last_xact_seqno = 0x00 
  8370.         select @agent_id = @virtual_agent_id
  8371.     else
  8372.         select @agent_id = @anonymous_agent_id
  8373.     
  8374.     -- Call main procedure to get status
  8375.     exec dbo.sp_MSsubscription_status
  8376.         @agent_id = @agent_id
  8377. GO
  8378.  
  8379. raiserror(15339,-1,-1,'sp_MSadd_anonymous_agent')
  8380. GO
  8381. CREATE PROCEDURE sp_MSadd_anonymous_agent
  8382. @publisher_id       smallint,
  8383. @publisher_db       sysname,
  8384. @publication        sysname,
  8385. @subscriber_db      sysname,
  8386. @subscriber_name    sysname,
  8387. @anonymous_subid    uniqueidentifier output,
  8388. @agent_id           int output,
  8389. @reinitanon         bit = 0
  8390.  
  8391. as
  8392.  
  8393. /*
  8394. ** This stored procedure does not really add a job at distribution database;
  8395. ** if add a row in MSdistribution_agent table for anonymous subscription for the 
  8396. ** purpose of history logging
  8397. */
  8398.  
  8399.    set nocount on
  8400.    declare @distribution_type smallint
  8401.    declare @profile_id int
  8402.    declare @subscriber_id smallint
  8403.    declare @retcode int
  8404.    declare @publication_id int
  8405.    declare @virtual_agent_id int
  8406.    declare @anonymous_agent_id int
  8407.    declare @virtual smallint
  8408.    declare @virtual_anonymous smallint
  8409.    declare @new_agent_id int
  8410.    declare @anonymous int
  8411.    declare @publisher_database_id int
  8412.    declare @allow_anonymous bit
  8413.    declare @publication_type int
  8414.    declare @merge_publication_type int
  8415.    
  8416.    select @publication_type = NULL
  8417.    select @merge_publication_type = 2
  8418.    
  8419.    select @virtual = -1
  8420.    select @virtual_anonymous = -2
  8421.    select @anonymous = 2
  8422.    
  8423.     -- Check to see if the publication is valid and allow anonymous
  8424.     select @publication_id = publication_id, @allow_anonymous = allow_anonymous, @publication_type = publication_type
  8425.         from MSpublications where
  8426.         publisher_id = @publisher_id and
  8427.         publisher_db = @publisher_db and
  8428.         publication = @publication 
  8429.  
  8430.     if @publication_id is null
  8431.     begin
  8432.         RAISERROR (21040, 16, -1, @publication)
  8433.         return 1
  8434.     end
  8435.  
  8436.     if @publication_type = @merge_publication_type
  8437.     begin
  8438.         RAISERROR(21132, 16, -1, @publication)
  8439.         return 1
  8440.     end
  8441.  
  8442.     if @allow_anonymous = 0
  8443.     begin
  8444.         RAISERROR (21084, 16, -1, @publication)
  8445.         return 1       
  8446.     end
  8447.  
  8448.     if @subscriber_name is null
  8449.         select @subscriber_name = N''
  8450.  
  8451.     -- Get virtual ids
  8452.     select top 1 @virtual_agent_id = agent_id, 
  8453.         @publisher_database_id = publisher_database_id from MSsubscriptions where
  8454.         publisher_id = @publisher_id and
  8455.         publisher_db = @publisher_db and
  8456.         publication_id = @publication_id and
  8457.         subscriber_id = @virtual
  8458.  
  8459.     select top 1 @anonymous_agent_id = agent_id from MSsubscriptions where
  8460.         publisher_id = @publisher_id and
  8461.         publisher_db = @publisher_db and
  8462.         publication_id = @publication_id and
  8463.         subscriber_id = @virtual_anonymous
  8464.  
  8465.  
  8466.     -- Security check
  8467.     exec @retcode = dbo.sp_MScheck_pull_access
  8468.         @agent_id =  @anonymous_agent_id,
  8469.         @agent_type = 0 -- distribution agent   
  8470.     if @retcode <> 0 or @@error <> 0
  8471.         return (1)
  8472.  
  8473.     /*
  8474.     **  To return two more parameters for the purpose of anonymous monitoring
  8475.     ** 
  8476.     ** If @anonymous_subid is null, this is a new anonymous subscription; A new row would be inserted in MSdistribution_agents.
  8477.     ** And its id (identity) and newly generated ID will be returned; The new ID would be used in subscriber side.
  8478.     */
  8479.     select @subscriber_id = 0   -- for anonymous subscribers, ID is always 0
  8480.  
  8481.     select @agent_id = id from MSdistribution_agents 
  8482.         where anonymous_subid = @anonymous_subid
  8483.         
  8484.     
  8485.     IF @agent_id is null
  8486.         BEGIN
  8487.             if @anonymous_subid is not NULL and @anonymous_subid <> 0x00
  8488.                and @reinitanon = 0
  8489.             begin
  8490.                 -- Agent has be cleaned up, return error.
  8491.                 raiserror(21072, 16, -1)
  8492.                 return(1)
  8493.             end
  8494.             -- Generate a new subid only when the subscription is not 
  8495.             -- reinitialized
  8496.             if @reinitanon = 0
  8497.             begin
  8498.                 select @anonymous_subid = newid()
  8499.             end
  8500.             SELECT @distribution_type = 3
  8501.  
  8502.             SELECT @profile_id = profile_id
  8503.             FROM msdb..MSagent_profiles
  8504.             WHERE agent_type = @distribution_type
  8505.                 AND def_profile = 1
  8506.  
  8507.             IF @profile_id IS NULL
  8508.             RETURN (1)
  8509.  
  8510.             INSERT into MSdistribution_agents (name, publisher_database_id, publisher_id, publisher_db, publication, 
  8511.                         subscriber_id, subscriber_db, subscription_type, local_job, job_id, subscription_guid, profile_id, anonymous_subid, 
  8512.                         subscriber_name, virtual_agent_id, anonymous_agent_id)
  8513.                         
  8514.                  VALUES (convert(nvarchar(40), @anonymous_subid), @publisher_database_id, @publisher_id, @publisher_db, @publication, 
  8515.                             @subscriber_id, @subscriber_db, @anonymous, 0, @anonymous_subid,
  8516.                             @anonymous_subid, @profile_id, @anonymous_subid, @subscriber_name,
  8517.                             @virtual_agent_id, @anonymous_agent_id)
  8518.             select @agent_id = @@identity
  8519.         END
  8520.         
  8521. GO
  8522.  
  8523.  
  8524. raiserror(15339,-1,-1,'sp_MSsubscription_status')
  8525. GO
  8526. CREATE PROCEDURE sp_MSsubscription_status
  8527. @agent_id int
  8528. as
  8529.  
  8530.     set nocount on
  8531.  
  8532.     declare @status tinyint
  8533.     declare @inactive tinyint
  8534.     declare @active tinyint
  8535.     declare @subscribed tinyint
  8536.     declare @initiated tinyint
  8537.     declare @article_id int
  8538.     declare @publication sysname
  8539.     declare @article sysname
  8540.     declare @msg nvarchar(255)
  8541.     declare @automatic tinyint
  8542.     declare @none tinyint
  8543.     declare @success int
  8544.     declare @retention int
  8545.     declare @last_sync datetime
  8546.     declare @publication_id int
  8547.  
  8548.     select @success = 2
  8549.     select @inactive = 0
  8550.     select @subscribed = 1
  8551.     select @active = 2
  8552.     select @initiated = 3
  8553.     SELECT @automatic = 1
  8554.     select @none = 2
  8555.  
  8556.     -- If one article is inactive, and no_sync subscription fail.
  8557.     if exists (select * from MSsubscriptions where
  8558.         status = @inactive and
  8559.         sync_type = @none and
  8560.         agent_id = @agent_id)
  8561.     begin
  8562.         -- The subscription was deactivated.
  8563.         raiserror(21396, 16,-1)
  8564.         return(1)
  8565.     end
  8566.     
  8567.     -- If one article is inactive, fail.
  8568.     if exists (select * from MSsubscriptions where
  8569.         status = @inactive and
  8570.         sync_type = @automatic and
  8571.         agent_id = @agent_id)
  8572.     begin
  8573.         -- The subscription was deactivated.
  8574.         raiserror(21074, 16,-1)
  8575.         return(1)
  8576.     end
  8577.  
  8578.     select top 1 @article_id = article_id,
  8579.         @publication_id = publication_id
  8580.         from MSsubscriptions where
  8581.         agent_id = @agent_id and
  8582.         sync_type = @automatic and
  8583.         status = @subscribed
  8584.  
  8585.     if @publication_id is not null
  8586.     begin
  8587.         -- Get the publication name to use later in the formated message
  8588.         select @publication = publication from MSpublications where
  8589.             publication_id = @publication_id
  8590.  
  8591.         -- If there's more than one article in subscribed state
  8592.         -- Send a general waiting message.
  8593.         -- Otherwise, indicate the article name
  8594.         if exists (select * from MSsubscriptions where
  8595.             agent_id = @agent_id and
  8596.             status = @subscribed and
  8597.             sync_type = @automatic and
  8598.             article_id <> @article_id)
  8599.         begin
  8600.             -- Snapshot not available message
  8601.             if @publication is not null
  8602.                 select @msg = formatmessage(21075, @publication)
  8603.             else -- It is null for 6.5
  8604.                 select @msg = formatmessage(21088)
  8605.         end
  8606.         else
  8607.         begin
  8608.             -- article_id is unique across pub db for tran
  8609.             -- but merge article may use the same id
  8610.             select @article = article from MSarticles where
  8611.                 article_id = @article_id and
  8612.                 publication_id = @publication_id
  8613.             -- It is null for 6.5
  8614.             if @article is not null
  8615.                 select @msg = formatmessage(21076, @article)
  8616.             else
  8617.             begin
  8618.                 -- Snapshot not available message
  8619.                 if @publication is not null
  8620.                     select @msg = formatmessage(21075, @publication)
  8621.                 else -- It is null for 6.5
  8622.                     select @msg = formatmessage(21088)
  8623.             end
  8624.         end
  8625.  
  8626.         -- If one article is active, the status is active
  8627.         if exists ( select * from MSsubscriptions where
  8628.             agent_id = @agent_id and
  8629.             sync_type = @automatic and
  8630.             status = @active)
  8631.             set @status = @active
  8632.         else
  8633.             set @status = @subscribed
  8634.     end
  8635.     else
  8636.     -- For concurrent snapshot, logreader has to run first.
  8637.     begin
  8638.          select top 1 @publication_id = publication_id, @status = status from MSsubscriptions s where
  8639.                 s.status = @initiated and
  8640.                 s.agent_id = @agent_id and
  8641.                 s.sync_type = @automatic
  8642.  
  8643.         if @publication_id is not null
  8644.         begin
  8645.             select @publication = publication from MSpublications where
  8646.                 publication_id = @publication_id
  8647.             select @msg = formatmessage(21388, @publication)
  8648.         end
  8649.     end
  8650.  
  8651.     -- If nothing returned, all articles are active.
  8652.     select 'msg' = @msg, 'status' = @status 
  8653.         where @msg is not null
  8654.  
  8655. GO
  8656.  
  8657.  
  8658.  
  8659.  
  8660. raiserror(15339,-1,-1,'sp_MSget_last_transaction')
  8661. GO
  8662. CREATE PROCEDURE sp_MSget_last_transaction
  8663. @publisher_id int = NULL,
  8664. @publisher_db sysname,
  8665. @publisher sysname = NULL,
  8666. @max_xact_seqno varbinary(16) = NULL output
  8667. ,@for_truncate bit = 0
  8668.  
  8669. AS
  8670.     declare @publisher_database_id int
  8671.     declare @max_xact_id varbinary(16)
  8672.     declare @sync_bit int
  8673.     declare @sync_with_backup bit
  8674.     
  8675.     set nocount on 
  8676.     
  8677.     SELECT @sync_bit = 32
  8678.  
  8679.     if @publisher_id is NULL
  8680.         select @publisher_id = srvid from master..sysservers where
  8681.             UPPER(srvname) = UPPER(@publisher)
  8682.  
  8683.     -- Get publisher database id.
  8684.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  8685.         publisher_db = @publisher_db
  8686.     
  8687.     if exists ( select * from master.dbo.sysdatabases where 
  8688.             name = db_name() and
  8689.             category & @sync_bit = 0) 
  8690.         select @sync_with_backup = 0
  8691.     else
  8692.         select @sync_with_backup = 1
  8693.  
  8694.  
  8695.  
  8696.     if @for_truncate = 0
  8697.     begin
  8698.         select top 1 @max_xact_id = rt.xact_id, @max_xact_seqno = rt.xact_seqno
  8699.           from
  8700.           MSrepl_transactions rt
  8701.           where 
  8702.              rt.publisher_database_id = @publisher_database_id and
  8703.              not xact_id = 0x0
  8704.              order by xact_seqno desc
  8705.     end
  8706.     -- If (1) requesting truncate lsn (distbackuplsn), (2) sync with backup is set
  8707.     -- query the values from MSrepl_backup_lsn
  8708.     else if    @sync_with_backup = 1
  8709.     begin
  8710.         -- Get the last backed up lsn if available.
  8711.         select top 1 @max_xact_id = valid_xact_id, @max_xact_seqno = valid_xact_seqno
  8712.           from
  8713.           MSrepl_backup_lsns 
  8714.           where 
  8715.              publisher_database_id = @publisher_database_id 
  8716.     end
  8717.     
  8718.     -- If @publisher is not null, we are calling this sp from sp_replrestart
  8719.     -- Don't return result set.
  8720.     if @publisher is null
  8721.         select @max_xact_id, @max_xact_seqno 
  8722.             -- Don't return any result when requsting a truncate lsn and
  8723.             -- the database is not in 'sync with backup' mode, which signal the 
  8724.             -- distribution agent to use last dist lsn to call sp_repldone.
  8725.             where not (@sync_with_backup = 0 and @for_truncate = 1)
  8726.   
  8727. GO
  8728.  
  8729. raiserror(15339,-1,-1,'sp_MSadd_subscriber_info')
  8730. GO
  8731. CREATE PROCEDURE sp_MSadd_subscriber_info
  8732. @publisher sysname,
  8733. @subscriber sysname,
  8734. @type tinyint = 0,
  8735. @login sysname = 'sa',
  8736. @password nvarchar(524) = NULL,
  8737. @commit_batch_size int = 100,
  8738. @status_batch_size int = 100,
  8739. @flush_frequency int = 0,
  8740. @frequency_type int = 4,
  8741. @frequency_interval int = 1,
  8742. @frequency_relative_interval int = 1,
  8743. @frequency_recurrence_factor int = 0,
  8744. @frequency_subday int = 4,
  8745. @frequency_subday_interval int = 5,
  8746. @active_start_time_of_day int = 0,
  8747. @active_end_time_of_day int = 235959,
  8748. @active_start_date int = 0,
  8749. @active_end_date int = 99991231,
  8750. @retryattempts int = 0,    
  8751. @retrydelay int = 0,
  8752. @description nvarchar (255) = NULL,
  8753. @security_mode int = 1, /* 0 standard; 1 integrated */
  8754. @encrypted_password bit = 0
  8755.  
  8756. AS
  8757.    set nocount on
  8758.  
  8759.    declare @retcode int
  8760.    declare @oledbprovider nvarchar(256)
  8761.    declare @platform_nt binary
  8762.  
  8763.    select @platform_nt = 0x1
  8764.  
  8765.     IF (UPPER(@subscriber) = UPPER(@@SERVERNAME) and ( @platform_nt != platform() & @platform_nt ) and @security_mode = 1)
  8766.         BEGIN
  8767.             RAISERROR(21038, 16, -1)
  8768.             RETURN (1)
  8769.         END
  8770.  
  8771. /* Add the subscriber to sysservers as a RPC server, if it does not
  8772.    ** already exist.
  8773.    */
  8774.    if not exists (select * from  master..sysservers where  UPPER(srvname) = UPPER(@subscriber))
  8775.       begin
  8776.           exec @retcode = dbo.sp_addserver @subscriber
  8777.           if @retcode <> 0
  8778.              return 1
  8779.       end
  8780.    
  8781.     -- Encrypt the password
  8782.     IF @encrypted_password = 0
  8783.     BEGIN
  8784.         EXEC @retcode = master.dbo.xp_repl_encrypt @password OUTPUT
  8785.         IF @@error <> 0 OR @retcode <> 0
  8786.             return 1
  8787.     END
  8788.  
  8789.     if (@type = 3)
  8790.     begin
  8791.         select @oledbprovider = providername from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  8792.         if (@oledbprovider = 'sqloledb')
  8793.             select @security_mode = 1
  8794.         else
  8795.             select @security_mode = 0
  8796.     end
  8797.  
  8798.    /* Delete any existing row */
  8799.    delete from MSsubscriber_info where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  8800.    if @@error <> 0
  8801.      return 1
  8802.    delete from MSsubscriber_schedule where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  8803.    if @@error <> 0
  8804.      return 1
  8805.  
  8806.    begin tran
  8807.    save TRAN addsub_info
  8808.  
  8809.    insert MSsubscriber_info (publisher, subscriber, type, login, password, description, security_mode)
  8810.          values (@publisher, @subscriber, @type, @login, @password, @description, @security_mode)
  8811.     if @@error <> 0
  8812.     goto UNDO
  8813.  
  8814.     /*
  8815.     ** Schedule information is added for backward compartibility reason, agent_type = 0
  8816.     */
  8817.    insert MSsubscriber_schedule values(@publisher, @subscriber, 0, @frequency_type,
  8818.                                         @frequency_interval,
  8819.                                         @frequency_relative_interval,
  8820.                                         @frequency_recurrence_factor ,
  8821.                                         @frequency_subday ,
  8822.                                         @frequency_subday_interval,
  8823.                                         @active_start_time_of_day,
  8824.                                         @active_end_time_of_day ,
  8825.                                         @active_start_date ,
  8826.                                         @active_end_date )
  8827.     if @@error <> 0
  8828.     goto UNDO
  8829.     COMMIT TRAN
  8830.  
  8831.     Return (0)
  8832. UNDO:
  8833.     if @@TRANCOUNT > 0
  8834.     begin
  8835.         ROLLBACK TRAN addsub_info
  8836.         COMMIT TRAN
  8837.     end
  8838.     return (1)
  8839. GO
  8840.  
  8841. raiserror(15339,-1,-1,'sp_MSadd_subscriber_schedule')
  8842. GO
  8843. CREATE PROCEDURE sp_MSadd_subscriber_schedule
  8844. @publisher sysname,
  8845. @subscriber sysname,
  8846. @agent_type smallint = 0,   -- 0 for distribution agent, 1 for merge agent
  8847. @frequency_type int = 4,
  8848. @frequency_interval int = 1,
  8849. @frequency_relative_interval int = 1,
  8850. @frequency_recurrence_factor int = 0,
  8851. @frequency_subday int = 4,
  8852. @frequency_subday_interval int = 5,
  8853. @active_start_time_of_day int = 0,
  8854. @active_end_time_of_day int = 235959,
  8855. @active_start_date int = 0,
  8856. @active_end_date int = 99991231
  8857.  
  8858. AS
  8859.    set nocount on
  8860.  
  8861.    declare @retcode int
  8862.  
  8863.    /* Add the subscriber to sysservers as a RPC server, if it does not
  8864.    ** already exist.
  8865.    */
  8866.    if not exists (select * from  master..sysservers where  UPPER(srvname) = UPPER(@subscriber))
  8867.       begin
  8868.           exec @retcode = dbo.sp_addserver @subscriber
  8869.           if @retcode <> 0
  8870.              return 1
  8871.       end
  8872.  
  8873.    /* Delete any existing row */
  8874.    if exists (select * from MSsubscriber_schedule where
  8875.        UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type=@agent_type)
  8876.        begin
  8877.            delete from MSsubscriber_schedule 
  8878.            where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type=@agent_type
  8879.           if @@error <> 0
  8880.              return 1
  8881.        end
  8882.  
  8883.    insert MSsubscriber_schedule (publisher, subscriber, agent_type, 
  8884.       frequency_type, frequency_interval, frequency_relative_interval,
  8885.       frequency_recurrence_factor, frequency_subday, frequency_subday_interval,
  8886.       active_start_time_of_day, active_end_time_of_day, active_start_date,
  8887.       active_end_date)
  8888.       
  8889.       values (@publisher, @subscriber, @agent_type, 
  8890.       @frequency_type, @frequency_interval, @frequency_relative_interval,
  8891.       @frequency_recurrence_factor, @frequency_subday, @frequency_subday_interval,
  8892.       @active_start_time_of_day, @active_end_time_of_day, @active_start_date,
  8893.       @active_end_date)
  8894.    if @@error <> 0
  8895.       return 1
  8896. GO
  8897.  
  8898.  
  8899.  
  8900. raiserror(15339,-1,-1,'sp_MSupdate_subscriber_info')
  8901. GO
  8902. CREATE PROCEDURE sp_MSupdate_subscriber_info
  8903. @publisher sysname,
  8904. @subscriber sysname,
  8905. @type tinyint = NULL,
  8906. @login sysname = NULL,
  8907. @password nvarchar(524) = '%',
  8908. @commit_batch_size int = NULL,
  8909. @status_batch_size int = NULL,
  8910. @flush_frequency int = NULL,
  8911. @frequency_type int = NULL,
  8912. @frequency_interval int = NULL,
  8913. @frequency_relative_interval int = NULL,
  8914. @frequency_recurrence_factor int = NULL,
  8915. @frequency_subday int = NULL,
  8916. @frequency_subday_interval int = NULL,
  8917. @active_start_time_of_day int = NULL,
  8918. @active_end_time_of_day int = NULL,
  8919. @active_start_date int = NULL,
  8920. @active_end_date int = NULL,
  8921. @retryattempts int = NULL,
  8922. @retrydelay int = NULL,
  8923. @description nvarchar (255) = NULL,
  8924. @security_mode int = NULL
  8925.  
  8926. AS
  8927.    set nocount on
  8928.    
  8929.    declare @cmd1 nvarchar (255)
  8930.    declare @retcode int
  8931.    declare @platform_nt binary
  8932.  
  8933.    select @platform_nt = 0x1
  8934.  
  8935.    IF (UPPER(@subscriber) = UPPER(@@SERVERNAME) and ( @platform_nt != platform() & @platform_nt ) and @security_mode = 1)
  8936.         BEGIN
  8937.             RAISERROR(21038, 16, -1)
  8938.             RETURN (1)
  8939.         END
  8940.  
  8941.  
  8942.    begin transaction
  8943.    save transaction update_subscriber
  8944.    
  8945.    /* Check if subscriber exists */
  8946.    if not exists (select * from MSsubscriber_info 
  8947.                   where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber))
  8948.        goto FAILED
  8949.  
  8950.    if not exists (select * from MSsubscriber_schedule 
  8951.                   where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0)
  8952.        goto FAILED    
  8953.    
  8954.    if @type is not NULL
  8955.       update MSsubscriber_info set type = @type 
  8956.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  8957.       if @@error <> 0
  8958.          goto FAILED
  8959.    
  8960.    if @security_mode is not NULL
  8961.       update MSsubscriber_info set security_mode = @security_mode 
  8962.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  8963.       if @@error <> 0
  8964.          goto FAILED
  8965.   
  8966.    if @login is not NULL
  8967.       update MSsubscriber_info set login = @login 
  8968.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  8969.       if @@error <> 0
  8970.          goto FAILED
  8971.    
  8972.    if @password <> '%'
  8973.    begin
  8974.         -- Encrypt the password
  8975.         EXEC @retcode = master.dbo.xp_repl_encrypt @password OUTPUT
  8976.         IF @@error <> 0 OR @retcode <> 0
  8977.             goto FAILED
  8978.         update MSsubscriber_info set password = @password 
  8979.             where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  8980.         if @@error <> 0
  8981.             goto FAILED
  8982.    end
  8983.  
  8984.    
  8985.    if @frequency_type is not NULL
  8986.       update MSsubscriber_schedule set frequency_type = @frequency_type 
  8987.         where  UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  8988.       if @@error <> 0
  8989.          goto FAILED
  8990.    
  8991.    if @frequency_interval is not NULL
  8992.       update MSsubscriber_schedule set frequency_interval = @frequency_interval 
  8993.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  8994.       if @@error <> 0
  8995.          goto FAILED
  8996.    
  8997.    if @frequency_relative_interval is not NULL
  8998.       update MSsubscriber_schedule set frequency_relative_interval = @frequency_relative_interval 
  8999.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9000.        if @@error <> 0
  9001.          goto FAILED
  9002.    
  9003.    if @frequency_recurrence_factor is not NULL
  9004.       update MSsubscriber_schedule set frequency_recurrence_factor = @frequency_recurrence_factor 
  9005.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9006.       if @@error <> 0
  9007.          goto FAILED
  9008.    
  9009.    if @frequency_subday is not NULL
  9010.       update MSsubscriber_schedule set frequency_subday = @frequency_subday 
  9011.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9012.       if @@error <> 0
  9013.          goto FAILED
  9014.    
  9015.    if @frequency_subday_interval is not NULL
  9016.       update MSsubscriber_schedule set frequency_subday_interval = @frequency_subday_interval 
  9017.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9018.       if @@error <> 0
  9019.          goto FAILED
  9020.    
  9021.    if @active_start_time_of_day is not NULL
  9022.       update MSsubscriber_schedule set active_start_time_of_day = @active_start_time_of_day 
  9023.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9024.       if @@error <> 0
  9025.          goto FAILED
  9026.    
  9027.    if @active_end_time_of_day is not NULL
  9028.       update MSsubscriber_schedule set active_end_time_of_day = @active_end_time_of_day 
  9029.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9030.       if @@error <> 0
  9031.          goto FAILED
  9032.    
  9033.    if @active_start_date is not NULL
  9034.       update MSsubscriber_schedule set active_start_date = @active_start_date 
  9035.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9036.       if @@error <> 0
  9037.          goto FAILED
  9038.    
  9039.    if @active_end_date is not NULL
  9040.       update MSsubscriber_schedule set active_end_date = @active_end_date 
  9041.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 0
  9042.       if @@error <> 0
  9043.          goto FAILED
  9044.    
  9045.    if @description is not NULL
  9046.       update MSsubscriber_info set description = @description 
  9047.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  9048.       if @@error <> 0
  9049.          goto FAILED
  9050.  
  9051.     if @security_mode is not NULL
  9052.       update MSsubscriber_info set security_mode = @security_mode 
  9053.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  9054.       if @@error <> 0
  9055.          goto FAILED
  9056.  
  9057.    commit transaction
  9058.    return (0)
  9059.    
  9060. FAILED:
  9061.     if @@trancount > 0
  9062.     begin
  9063.         rollback transaction update_subscriber
  9064.         commit tran -- to finish off the tran we started in this proc (though 
  9065.                     -- work was rolled back to savepoint)
  9066.     end
  9067.    return (1)
  9068. GO
  9069.  
  9070. raiserror(15339,-1,-1,'sp_MScheck_Jet_Subscriber')
  9071. GO
  9072. CREATE PROCEDURE sp_MScheck_Jet_Subscriber
  9073. @subscriber                sysname,
  9074. @is_jet                    int OUTPUT,
  9075. @Jet_datasource_path    sysname OUTPUT
  9076. AS
  9077.  
  9078. select @is_jet = 0
  9079. IF EXISTS (select * from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  9080.                 and upper(providername) = 'MICROSOFT.JET.OLEDB.4.0')
  9081. begin
  9082.     select @is_jet = 1
  9083.     select @Jet_datasource_path = datasource from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  9084. end
  9085. return (0)
  9086. GO
  9087.  
  9088. /*
  9089. ** this procedure is to check if merge agent is has expired based on retention
  9090. ** period. Note that if it does, a reinitialization would make it work.
  9091. */
  9092. raiserror(15339,-1,-1,'sp_MScheckretention')
  9093. GO
  9094. CREATE PROCEDURE sp_MScheckretention
  9095. @agent_id                int,
  9096. @schemachangever        int
  9097. AS
  9098. declare     @publisher_id            int
  9099. declare     @publisher_db        sysname
  9100. declare     @publication        sysname
  9101. declare        @expired            int
  9102. declare        @min_valid_day        datetime
  9103. declare        @retention            int
  9104. declare     @success            int
  9105.  
  9106. select @expired  = 0
  9107. select @success = 2
  9108.  
  9109. select @publisher_id=publisher_id, @publisher_db=publisher_db, @publication=publication 
  9110. from MSmerge_agents 
  9111. where id = @agent_id
  9112.  
  9113. select @retention = retention 
  9114. from MSpublications 
  9115. where publisher_id=@publisher_id and publisher_db=@publisher_db and publication=@publication 
  9116.  
  9117. if @retention is not NULL and @retention > 0 and @schemachangever >0
  9118. begin
  9119.     select @min_valid_day = dateadd(day, @retention * (-1), getdate()) 
  9120.     if exists (select * from MSmerge_history where agent_id=@agent_id) 
  9121.             and not exists (select * from MSmerge_history where agent_id=@agent_id and time > @min_valid_day)
  9122.         select @expired = 1
  9123. end
  9124. select @expired 
  9125. GO
  9126.  
  9127. raiserror(15339,-1,-1,'sp_MSupdate_subscriber_schedule')
  9128. GO
  9129. CREATE PROCEDURE sp_MSupdate_subscriber_schedule
  9130. @publisher sysname,
  9131. @subscriber sysname,
  9132. @agent_type tinyint = NULL,
  9133. @frequency_type int = NULL,
  9134. @frequency_interval int = NULL,
  9135. @frequency_relative_interval int = NULL,
  9136. @frequency_recurrence_factor int = NULL,
  9137. @frequency_subday int = NULL,
  9138. @frequency_subday_interval int = NULL,
  9139. @active_start_time_of_day int = NULL,
  9140. @active_end_time_of_day int = NULL,
  9141. @active_start_date int = NULL,
  9142. @active_end_date int = NULL
  9143.  
  9144. AS
  9145.    set nocount on
  9146.    
  9147.    declare @cmd1 nvarchar (255)
  9148.    declare @retcode int
  9149.    
  9150.  
  9151.    begin transaction
  9152.    save transaction update_subscriber_schedule
  9153.    
  9154.    /* Check if subscriber exists */
  9155.    if not exists (select * from MSsubscriber_info 
  9156.             where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber))
  9157.        goto FAILED
  9158.        
  9159.     if not exists (select * from MSsubscriber_schedule 
  9160.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type)
  9161.        goto FAILED
  9162.     
  9163.    
  9164.    if @frequency_type is not NULL
  9165.       update MSsubscriber_schedule set frequency_type = @frequency_type 
  9166.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9167.       if @@error <> 0
  9168.          goto FAILED
  9169.    
  9170.    if @frequency_interval is not NULL
  9171.       update MSsubscriber_schedule set frequency_interval = @frequency_interval 
  9172.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9173.       if @@error <> 0
  9174.          goto FAILED
  9175.    
  9176.    if @frequency_relative_interval is not NULL
  9177.       update MSsubscriber_schedule set frequency_relative_interval = @frequency_relative_interval 
  9178.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9179.       if @@error <> 0
  9180.          goto FAILED
  9181.    
  9182.    if @frequency_recurrence_factor is not NULL
  9183.       update MSsubscriber_schedule set frequency_recurrence_factor = @frequency_recurrence_factor 
  9184.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9185.        if @@error <> 0
  9186.          goto FAILED
  9187.    
  9188.    if @frequency_subday is not NULL
  9189.       update MSsubscriber_schedule set frequency_subday = @frequency_subday 
  9190.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9191.       if @@error <> 0
  9192.          goto FAILED
  9193.    
  9194.    if @frequency_subday_interval is not NULL
  9195.       update MSsubscriber_schedule set frequency_subday_interval = @frequency_subday_interval 
  9196.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9197.       if @@error <> 0
  9198.          goto FAILED
  9199.    
  9200.    if @active_start_time_of_day is not NULL
  9201.       update MSsubscriber_schedule set active_start_time_of_day = @active_start_time_of_day 
  9202.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9203.       if @@error <> 0
  9204.          goto FAILED
  9205.    
  9206.    if @active_end_time_of_day is not NULL
  9207.       update MSsubscriber_schedule set active_end_time_of_day = @active_end_time_of_day 
  9208.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9209.       if @@error <> 0
  9210.          goto FAILED
  9211.    
  9212.    if @active_start_date is not NULL
  9213.       update MSsubscriber_schedule set active_start_date = @active_start_date 
  9214.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9215.       if @@error <> 0
  9216.          goto FAILED
  9217.    
  9218.    if @active_end_date is not NULL
  9219.       update MSsubscriber_schedule set active_end_date = @active_end_date 
  9220.       where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = @agent_type
  9221.       if @@error <> 0
  9222.          goto FAILED
  9223.  
  9224.    commit transaction
  9225.    return (0)
  9226.    
  9227. FAILED:
  9228.     if @@trancount > 0
  9229.     begin
  9230.         rollback transaction update_subscriber_schedule
  9231.         commit transaction      -- to finish off the tran we started in this proc (though 
  9232.                                 -- work was rolled back to savepoint)
  9233.     end
  9234.    return (1)
  9235. GO
  9236.  
  9237.  
  9238. raiserror(15339,-1,-1,'sp_MSdrop_subscriber_info')
  9239. GO
  9240. CREATE PROCEDURE sp_MSdrop_subscriber_info
  9241. @publisher sysname,
  9242. @subscriber sysname
  9243.  
  9244. AS
  9245.     set nocount on
  9246.  
  9247.     declare @srvid smallint
  9248.     declare @publisher_id smallint
  9249.     declare @publisher_db sysname
  9250.   
  9251.     if exists (select * from MSsubscriber_info where
  9252.         UPPER(subscriber) = UPPER(@subscriber))
  9253.     begin
  9254.  
  9255.         select @srvid = srvid from master..sysservers where lower(srvname) = lower(@subscriber)
  9256.  
  9257.         -- For SQL server publishers, drop the existing subscriptions.
  9258.         -- This has to be done for 65 upgrade.
  9259.         -- For third party, check for error.
  9260.         if exists (select * from msdb..MSdistpublishers where 
  9261.             lower(name) = lower(@publisher) and
  9262.             thirdparty_flag = 0)
  9263.         begin
  9264.             -- This is needed for 6.5 upgrade.
  9265.             -- Remove subscription entries for this publisher and subscriber pair
  9266.             -- Get dist publisher ID
  9267.             exec dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  9268.             delete MSsubscriptions where subscriber_id = @srvid and 
  9269.                 publisher_id = @publisher_id
  9270.         end
  9271.         else
  9272.         begin
  9273.             if exists (select * from MSsubscriptions where subscriber_id = @srvid)
  9274.             begin
  9275.                 raiserror(20100, 16, -1, @subscriber)
  9276.                 return (1)
  9277.             end
  9278.         end
  9279.  
  9280.         delete MSsubscriber_info where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  9281.         if @@error <> 0
  9282.             return 1
  9283.         delete MSsubscriber_schedule where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  9284.         if @@error <> 0
  9285.             return 1    
  9286.     end
  9287. GO
  9288.  
  9289. -- delete the agent rows that are orphaned for some external reasons, e.g., publishing database dropped,
  9290. -- the agent entry for anonymous TRAN/MERGE subscriptions. 
  9291. -- Can be called directly by user to explicitly cleanup metadata in distribution database
  9292.  
  9293. raiserror(15339,-1,-1,'sp_MScleanup_agent_entry')
  9294. GO
  9295. CREATE PROCEDURE sp_MScleanup_agent_entry
  9296. AS
  9297.     
  9298.     declare @min_valid_day         datetime
  9299.  
  9300.     declare @publisher_id         int
  9301.     declare @subscriber_id         int
  9302.     declare @publication         sysname
  9303.     declare @publisher_db         sysname
  9304.     declare @subscriber_db         sysname
  9305.     declare @retention             int
  9306.     declare @publication_type     int
  9307.     declare @agent_id            int
  9308.         , @num_dropped    int
  9309.         , @retcode int
  9310.  
  9311.     set nocount on
  9312.     select @num_dropped = 0
  9313.  
  9314.     declare PC CURSOR LOCAL FAST_FORWARD for 
  9315.         select distinct publisher_id, publisher_db, publication, retention, publication_type from MSpublications
  9316.             where retention<>0
  9317.     open PC
  9318.     fetch PC into @publisher_id, @publisher_db, @publication, @retention, @publication_type
  9319.     while (@@fetch_status <> -1)
  9320.     begin    
  9321.         if @publication_type = 2  --merge publication
  9322.         begin
  9323.             select @min_valid_day = dateadd(day, @retention * (-2), getdate()) 
  9324.  
  9325.             declare hC CURSOR LOCAL FAST_FORWARD FOR 
  9326.                 select id from MSmerge_agents where creation_date < @min_valid_day
  9327.                     and not exists (select * from MSmerge_history where agent_id = id and time > @min_valid_day)
  9328.                     and publisher_id=@publisher_id
  9329.                     and publisher_db = @publisher_db
  9330.                     and publication = @publication   
  9331.                     -- Only do this for anonymous agents
  9332.                     and subscriber_name is not null         
  9333.             for read only
  9334.             open hC
  9335.             fetch hC into @agent_id
  9336.             while (@@fetch_status <> -1)
  9337.             begin
  9338.                 exec @retcode = dbo.sp_MSdrop_merge_agentid @agent_id
  9339.                 if @retcode <> 0 or @@error <> 0
  9340.                     return (1)
  9341.                 select @num_dropped = @num_dropped + 1
  9342.                 fetch hC into @agent_id
  9343.             end
  9344.             close hC
  9345.             deallocate hC
  9346.         end
  9347.            else if @publication_type in (0,1) --Tran level publication
  9348.               begin  
  9349.                 select @min_valid_day = dateadd(hour, @retention * (-1), getdate())    
  9350.                 -- Only do this for anonymous agents
  9351.                 declare hC CURSOR LOCAL FAST_FORWARD FOR 
  9352.                     select id from MSdistribution_agents where creation_date < @min_valid_day
  9353.                         and not exists (select * from MSdistribution_history where agent_id = id and time > @min_valid_day)
  9354.                         and publisher_id=@publisher_id
  9355.                         and publisher_db = @publisher_db
  9356.                         and publication = @publication            
  9357.                         -- Only do this for anonymous agents
  9358.                         and subscriber_name is not null                             
  9359.                 for read only
  9360.                 open hC
  9361.                 fetch hC into @agent_id
  9362.                 while (@@fetch_status <> -1)
  9363.                 begin
  9364.                     exec @retcode = dbo.sp_MSdrop_distribution_agentid @agent_id
  9365.                     if @retcode <> 0 or @@error <> 0
  9366.                         return (1)
  9367.                     select @num_dropped = @num_dropped + 1
  9368.                     fetch hC into @agent_id
  9369.                 end
  9370.             close hC
  9371.             deallocate hC
  9372.             end
  9373.           fetch PC into @publisher_id, @publisher_db, @publication, @retention, @publication_type
  9374.     end
  9375.     close PC
  9376.     deallocate PC
  9377.     if @num_dropped > 0
  9378.         RAISERROR(20597, 10, -1, @num_dropped) 
  9379.        return (0)
  9380. FAILURE:
  9381.     close PC
  9382.     deallocate PC
  9383.        return (1)        
  9384. GO
  9385.  
  9386. raiserror(15339,-1,-1,'sp_MShelp_subscription_status')
  9387. GO
  9388. CREATE PROCEDURE sp_MShelp_subscription_status(
  9389. @publisher          sysname,
  9390. @publisher_db       sysname,
  9391. @publication        sysname,
  9392. @subscriber         sysname,
  9393. @subscriber_db      sysname,
  9394. @retention          int,
  9395. @out_of_date        int OUTPUT,
  9396. @independent_agent  bit = 0
  9397. )AS
  9398.  
  9399. declare @subscriber_id          int
  9400. declare @publisher_id           int
  9401. declare @publication_id         int
  9402. declare @retcode                int
  9403. declare @agent_id               int
  9404. declare @min_valid_day          datetime
  9405. declare @subscription_time      datetime
  9406. declare @last_history            datetime
  9407. declare @last_status            int
  9408.  
  9409. select @out_of_date = 0 -- Default value set to in-sync
  9410. select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  9411. select @subscriber_id = srvid from master..sysservers where UPPER(srvname)=UPPER(@subscriber)
  9412.  
  9413. select  @publication_id = publication_id
  9414.         from MSpublications where
  9415.         publisher_id = @publisher_id and
  9416.         publisher_db = @publisher_db and
  9417.         publication = @publication
  9418.  
  9419. select @subscription_time = subscription_time
  9420.         from MSsubscriptions where
  9421.             publisher_id = @publisher_id and
  9422.             publisher_db = @publisher_db and
  9423.             publication_id = @publication_id and
  9424.             subscriber_id = @subscriber_id and
  9425.             subscriber_db = @subscriber_db
  9426.             
  9427. select @min_valid_day = dateadd(hour, -@retention, getdate())
  9428.         
  9429. BEGIN TRAN
  9430.     select @agent_id = id from MSdistribution_agents 
  9431.         where   publisher_id = @publisher_id and 
  9432.                 publisher_db = @publisher_db and 
  9433.                 ((publication = @publication and @independent_agent = 1 ) 
  9434.                     or (LOWER(publication) = 'all' and @independent_agent = 0)) and
  9435.                 subscriber_id = @subscriber_id and  
  9436.                 subscriber_db = @subscriber_db
  9437.  
  9438.     if @agent_id is NOT NULL
  9439.         begin
  9440.             select Top 1 @last_status = runstatus, @last_history = time 
  9441.                 from MSdistribution_history where agent_id = @agent_id
  9442.                     order by timestamp DESC
  9443.                     
  9444.             -- if failure then get the last success; if any; else use the existing value                    
  9445.             
  9446.             if @last_status = 6 and EXISTS (select * from MSdistribution_history where agent_id = @agent_id and runstatus = 2) 
  9447.                 select Top 1 @last_history = time 
  9448.                     from MSdistribution_history where agent_id = @agent_id and runstatus = 2
  9449.                         order by timestamp DESC    
  9450.             
  9451.             if EXISTS (select * from MSdistribution_history where agent_id = @agent_id) and (@last_history < @min_valid_day)
  9452.                 and (@retention <> 0)
  9453.                 select @out_of_date = 1
  9454.             else 
  9455.                 if (not EXISTS (select * from MSdistribution_history where agent_id = @agent_id)) and
  9456.                         (@subscription_time < @min_valid_day) and (@retention <> 0)
  9457.                 select @out_of_date = 1
  9458.         end
  9459.         
  9460. COMMIT TRAN
  9461. return (0)
  9462.  
  9463. FAILURE:
  9464.     if @@TRANCOUNT = 1
  9465.         ROLLBACK TRAN
  9466.     else
  9467.         COMMIT TRAN
  9468.     return (1)
  9469. GO
  9470.  
  9471.  
  9472.  
  9473. raiserror(15339,-1,-1,'sp_MShelp_subscriber_info')
  9474. GO
  9475. CREATE PROCEDURE sp_MShelp_subscriber_info
  9476. @publisher sysname = '%',
  9477. @subscriber sysname = '%',
  9478. @found int = NULL    OUTPUT,
  9479. @show_password bit = 1
  9480.  
  9481. AS
  9482.    set nocount on
  9483.    
  9484.    DECLARE @no_rows bit
  9485.  
  9486.     -- push agents (dist or merge) may call this.
  9487.     -- raise an message indicating that users may forget to specify -SubscriptionType
  9488.     if is_member(N'db_owner') <> 1
  9489.     begin
  9490.         raiserror (20604, 16, -1)
  9491.         return 1
  9492.     end
  9493.  
  9494.     /*
  9495.     ** Initializations.
  9496.     */
  9497.     IF @found is NULL
  9498.     BEGIN
  9499.         SELECT @no_rows=0
  9500.     END
  9501.     ELSE
  9502.     BEGIN
  9503.         SELECT @no_rows=1
  9504.     END
  9505.  
  9506.    if exists (select * from MSsubscriber_info 
  9507.                where (@publisher = '%' or UPPER(publisher) = UPPER(@publisher)) 
  9508.                  and (@subscriber = '%' or UPPER(subscriber) = UPPER(@subscriber)))
  9509.    begin
  9510.         select @found = 1
  9511.         if @no_rows <>0 return(0)
  9512.    end
  9513.    else
  9514.    begin
  9515.         select @found = 0
  9516.         if @no_rows <>0 return(0)
  9517.    end
  9518.  
  9519.    if exists (select * from MSsubscriber_schedule 
  9520.                where (@publisher = N'%' or UPPER(publisher) = UPPER(@publisher))
  9521.                  and (@subscriber = N'%' or UPPER(subscriber) = UPPER(@subscriber)))
  9522.     begin
  9523.     
  9524.      select Sinfo.publisher,
  9525.             Sinfo.subscriber,
  9526.             Sinfo.type,
  9527.             Sinfo.login,
  9528.             case when @show_password = 1 then Sinfo.password
  9529.             else convert(sysname, NULL) end,
  9530.             100,  -- commit_batch_size, no longer supported
  9531.             100,  -- status_batch_size, no longer supported
  9532.             1,    -- flush_frequency, no longer supported
  9533.             sch1.frequency_type, 
  9534.             sch1.frequency_interval,
  9535.             sch1.frequency_relative_interval,
  9536.             sch1.frequency_recurrence_factor,
  9537.             sch1.frequency_subday,
  9538.             sch1.frequency_subday_interval,
  9539.             sch1.active_start_time_of_day,
  9540.             sch1.active_end_time_of_day,
  9541.             sch1.active_start_date,
  9542.             sch1.active_end_date,
  9543.             4, -- retryattempt, no longer exist
  9544.             4,  -- retrydelay, no longer exist
  9545.             Sinfo.description,
  9546.             Sinfo.security_mode,
  9547.             sch2.frequency_type, 
  9548.             sch2.frequency_interval,
  9549.             sch2.frequency_relative_interval,
  9550.             sch2.frequency_recurrence_factor,
  9551.             sch2.frequency_subday,
  9552.             sch2.frequency_subday_interval,
  9553.             sch2.active_start_time_of_day,
  9554.             sch2.active_end_time_of_day,
  9555.             sch2.active_start_date,
  9556.             sch2.active_end_date
  9557.             
  9558.     from (MSsubscriber_info as Sinfo LEFT OUTER JOIN MSsubscriber_schedule as sch1 
  9559.         on UPPER(Sinfo.publisher)=UPPER(sch1.publisher) AND UPPER(Sinfo.subscriber)=UPPER(sch1.subscriber) and sch1.agent_type=0)
  9560.         LEFT OUTER JOIN MSsubscriber_schedule as sch2
  9561.             on UPPER(Sinfo.publisher)=UPPER(sch2.publisher) AND UPPER(Sinfo.subscriber)=UPPER(sch2.subscriber) 
  9562.                     and sch2.agent_type=1
  9563.     where (@publisher = N'%' or UPPER(Sinfo.publisher) = UPPER(@publisher)) and 
  9564.           (@subscriber = N'%' or UPPER(Sinfo.subscriber) = UPPER(@subscriber))                 
  9565.     
  9566.     end
  9567. GO
  9568.  
  9569. raiserror(15339,-1,-1,'sp_MSdistribution_counters')
  9570. go
  9571. CREATE PROCEDURE sp_MSdistribution_counters
  9572. @publisher sysname      /* publication server name */
  9573. AS
  9574.  
  9575.     set nocount on
  9576.  
  9577.     declare @publisher_id smallint
  9578.     declare @subscriber_id smallint
  9579.     declare @active_status tinyint
  9580.     declare @snapshot_bit int
  9581.     declare @undelivered_commands int
  9582.     declare @delivered_commands int
  9583.     declare @delivery_rate float
  9584.     declare @delivery_latency int
  9585.     declare @xact_seqno varbinary(16)
  9586.     declare @agent_id int
  9587.     
  9588.     select @active_status = 2
  9589.     select @snapshot_bit = 0x80000000
  9590.  
  9591.  
  9592.     -- Make sure publisher is defined on distributor
  9593.     --
  9594.     select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  9595.     if @publisher_id is null
  9596.        return (1)
  9597.  
  9598.     create table #dist_trans (subscriber_id smallint NOT NULL, undelivered_commands int NOT NULL, 
  9599.         delivered_commands int NOT NULL, delivery_rate float NOT NULL, 
  9600.         delivery_latency int NOT NULL)
  9601.  
  9602.     declare hc CURSOR LOCAL FAST_FORWARD FOR select distinct agent_id
  9603.         from MSsubscriptions
  9604.         where
  9605.         publisher_id = @publisher_id and
  9606.         subscriber_id >= 0 and
  9607.         status = 2
  9608.         for read only
  9609.  
  9610.     open hc
  9611.     fetch hc into  @agent_id
  9612.     while (@@fetch_status <> -1)
  9613.     begin
  9614.         -- Get the lastest numbers from distribution_history
  9615.         select  @xact_seqno = NULL
  9616.  
  9617.         -- Get latest seqno, rate and latency
  9618.         set rowcount 1
  9619.         select  @xact_seqno = xact_seqno,
  9620. --              @delivered_commands = delivered_commands,
  9621.                 @delivery_rate = current_delivery_rate,
  9622.                 @delivery_latency = current_delivery_latency
  9623.             -- from MSdistribution_history  (READPAST)
  9624.             from MSdistribution_history 
  9625.             where
  9626.             agent_id = @agent_id and
  9627.             xact_seqno <> 0x0
  9628.             order by timestamp DESC
  9629.         set rowcount 0
  9630.  
  9631.         if @xact_seqno IS NULL
  9632.             select  @xact_seqno = 0x00,
  9633.                     @delivery_rate = 0,
  9634.                     @delivery_latency = 0
  9635.  
  9636.  
  9637.         set rowcount 1
  9638.         select @subscriber_id = subscriber_id FROM MSsubscriptions
  9639.             where agent_id = @agent_id
  9640.         set rowcount 0
  9641.         
  9642.         -- Get the delivered trans number
  9643.         select @delivered_commands = 0
  9644.         select @delivered_commands = isnull(count(*), 0)
  9645.             from
  9646.             -- MSrepl_commands rc (READPAST), MSsubscriptions s
  9647.             MSrepl_commands rc, MSsubscriptions s
  9648.             where
  9649.             /*
  9650.             ** Query from sp_MSget_repl_commands
  9651.             */
  9652.             s.agent_id = @agent_id and
  9653.             s.status = @active_status and
  9654.             rc.publisher_database_id = s.publisher_database_id and
  9655. --          rc.publisher_id = s.publisher_id and
  9656. --          rc.publisher_db = s.publisher_db and
  9657.             rc.xact_seqno <= @xact_seqno and
  9658.             rc.article_id = s.article_id and
  9659.             rc.partial_command = 0
  9660.             and
  9661.             ((rc.xact_seqno >= s.subscription_seqno and (rc.type & @snapshot_bit) <> @snapshot_bit) or
  9662.             rc.xact_seqno = s.subscription_seqno)
  9663.  
  9664.         -- Get the undelivered trans number
  9665.         select @undelivered_commands = 0
  9666.         select @undelivered_commands = isnull(count(*), 0)
  9667.             from
  9668.             -- MSrepl_commands rc (READPAST), MSsubscriptions s
  9669.             MSrepl_commands rc , MSsubscriptions s
  9670.             where
  9671.             /*
  9672.             ** Query from sp_MSget_repl_commands
  9673.             */
  9674.             s.agent_id = @agent_id and
  9675.             s.status = @active_status and
  9676.             rc.publisher_database_id = s.publisher_database_id and
  9677.             rc.xact_seqno > @xact_seqno and
  9678.             rc.article_id = s.article_id and
  9679.             rc.partial_command = 0
  9680.             and
  9681.             ((rc.xact_seqno >= s.subscription_seqno and (rc.type & @snapshot_bit) <> @snapshot_bit) or
  9682.             rc.xact_seqno = s.subscription_seqno)
  9683.  
  9684.         insert into #dist_trans values (@subscriber_id, @undelivered_commands,
  9685.             @delivered_commands, @delivery_rate, @delivery_latency)
  9686.         
  9687.         fetch hc into  @agent_id
  9688.     end
  9689.  
  9690.     close hc
  9691.     deallocate hc
  9692.  
  9693.     select 'subscriber' = srvname, 
  9694.             'delivered commands' = sum(delivered_commands),
  9695.             'undelivered_commands' = sum(undelivered_commands),
  9696.             'delivery_rate' = sum(delivery_rate),
  9697.             'delivery_latency' = (select isnull(avg(delivery_latency), 0) from #dist_trans, master.dbo.sysservers where
  9698.                 srvname = s1.srvname and delivery_latency > 0)
  9699.         from #dist_trans, master.dbo.sysservers s1
  9700.         where subscriber_id = srvid
  9701.         group by srvname
  9702.  
  9703.     drop table #dist_trans
  9704.         
  9705. GO
  9706.  
  9707. raiserror(15339,-1,-1,'sp_MSremove_published_jobs')
  9708. go
  9709. CREATE PROCEDURE sp_MSremove_published_jobs
  9710. @server sysname,
  9711. @database sysname
  9712. AS
  9713.     -- 6.5 publisher and 7.0 publisher will call this
  9714.     -- publisher_database_id will be drop in sp_MSdrop_publication.
  9715.     return(0)
  9716. go
  9717.  
  9718. raiserror(15339,-1,-1,'sp_MSset_snapshot_xact_seqno')
  9719. go
  9720.  
  9721. CREATE PROCEDURE sp_MSset_snapshot_xact_seqno
  9722. @publisher_id int,
  9723. @publisher_db sysname,
  9724. @article_id int, 
  9725. @xact_seqno varbinary(16),
  9726. @reset bit = 0,         /* @reset = 1 is used for Scheduled Snapshot publications by snapshot */
  9727. @publication sysname = NULL,
  9728. @publisher_seqno varbinary(16) = 0x00,
  9729. @ss_cplt_seqno varbinary(16) = NULL
  9730. /* 
  9731. ** Required for 6x publishers!
  9732. */
  9733. AS
  9734.  
  9735.     DECLARE @virtual smallint     /* const: virtual subscriber id */
  9736.     DECLARE @virtual_anonymous smallint /* const: virtual anonymous subscriber id */
  9737.     DECLARE @old_xact_seqno varbinary(16)
  9738.     DECLARE @old_publisher_seqno varbinary(16)
  9739.     DECLARE @subscribed tinyint
  9740.     DECLARE @automatic tinyint
  9741.     DECLARE @old_snapshot_seqno_flag bit
  9742.     DECLARE @publication_id int
  9743.     DECLARE @initiated tinyint
  9744.  
  9745.     SELECT @virtual = -1
  9746.     SELECT @virtual_anonymous = -2
  9747.     SELECT @subscribed = 1
  9748.     SELECT @automatic = 1
  9749.     SELECT @initiated = 3
  9750.     
  9751.     if @ss_cplt_seqno is null 
  9752.     begin
  9753.         select @ss_cplt_seqno = @xact_seqno;
  9754.     end
  9755.  
  9756.     -- 6.5 only!!! @publication is not null only if the publisher is 6.5 sever!
  9757.     -- Set the publication_id and sync_type in MSsubscriptions.
  9758.     -- It will be used in sp_MSupdate_subscriptions 
  9759.     IF @publication IS NOT NULL
  9760.     BEGIN
  9761.         -- Get the publication id
  9762.         SELECT @publication_id = publication_id FROM MSpublications
  9763.             WHERE   publisher_id = @publisher_id AND
  9764.                     publisher_db = @publisher_db AND    
  9765.                     publication  = @publication
  9766.  
  9767.         -- Set the pubid and the sync_type
  9768.         -- Avoid update rows with no change to reduce update locks.
  9769.         
  9770.         UPDATE MSsubscriptions SET publication_id = @publication_id
  9771.             WHERE   publisher_id = @publisher_id AND
  9772.                     publisher_db = @publisher_db AND    
  9773.                     article_id  = @article_id and
  9774.                     status = @subscribed and
  9775.                     publication_id <> @publication_id
  9776.         
  9777.         -- Have to do this to avoid no sync subs from 6.5 publisher being
  9778.         -- updated.
  9779.         UPDATE MSsubscriptions SET sync_type = @automatic
  9780.             WHERE   publisher_id = @publisher_id AND
  9781.                     publisher_db = @publisher_db AND    
  9782.                     article_id  = @article_id and
  9783.                     status = @subscribed and
  9784.                     sync_type <> @automatic
  9785.     END
  9786.  
  9787.     begin tran
  9788.     save TRANSACTION MSset_snapshot_xact_seqno
  9789.  
  9790.     /* 
  9791.     ** Set snapshot_xact_seqno for all new subscriptions,
  9792.     ** plus the virtual subscription or all subscriptions if @reset = 1
  9793.     ** Note virtual anonymous subscription will not be set
  9794.     ** (2 virtual subscriptions of anonymous publication will be activated
  9795.     ** immediately without snapshot
  9796.     ** 
  9797.     ** @reset = 1 is used for Scheduled Snapshot publications by snapshot
  9798.     */
  9799.     UPDATE MSsubscriptions SET subscription_seqno = @xact_seqno,
  9800.         publisher_seqno = @publisher_seqno,
  9801.         snapshot_seqno_flag = 1,
  9802.         subscription_time = getdate(),
  9803.         ss_cplt_seqno = @ss_cplt_seqno
  9804.       WHERE 
  9805.          MSsubscriptions.publisher_id = @publisher_id and
  9806.          MSsubscriptions.publisher_db = @publisher_db and
  9807.          MSsubscriptions.article_id = @article_id and 
  9808.          /* virtual subscriptions are automatic sync type */
  9809.          MSsubscriptions.sync_type = @automatic and 
  9810.          (MSsubscriptions.status in(@subscribed,@initiated) or 
  9811.          MSsubscriptions.subscriber_id = @virtual or
  9812.          -- Set for virtual anonymous account if snapshot_seqno_flag
  9813.          -- is 0.
  9814.          -- The virtual anonymous account is activated immediately at subscription
  9815.          -- time for no init option for anonymous agent.
  9816.          (MSsubscriptions.subscriber_id = @virtual_anonymous and 
  9817.          (MSsubscriptions.snapshot_seqno_flag = 0 or 
  9818.          MSsubscriptions.status in(@subscribed,@initiated))) or
  9819.          @reset = 1) 
  9820.  
  9821.     IF @@ERROR <> 0
  9822.     BEGIN
  9823.         if @@trancount > 0
  9824.         begin
  9825.             ROLLBACK TRANSACTION MSset_snapshot_xact_seqno
  9826.             commit tran
  9827.         end
  9828.         RETURN (1)
  9829.     END
  9830.  
  9831.     COMMIT TRANSACTION
  9832. GO
  9833.  
  9834.  
  9835. raiserror(15339,-1,-1,'sp_MSdrop_article')
  9836. go
  9837. CREATE PROCEDURE sp_MSdrop_article
  9838. @publisher sysname,
  9839. @publisher_db sysname,
  9840. @publication sysname,
  9841. @article sysname
  9842.  
  9843. as
  9844.  
  9845.     set nocount on
  9846.  
  9847.     declare @publisher_id smallint
  9848.     declare @publication_id int
  9849.     declare @article_id int
  9850.     declare @retcode int
  9851.     declare @thirdparty_flag bit
  9852.     declare @immediate_sync bit
  9853.  
  9854.     -- Check if publisher is a defined as a distribution publisher in the current database
  9855.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  9856.     if @retcode <> 0
  9857.     begin
  9858.         return(1)
  9859.     end
  9860.  
  9861.     -- Make sure publication exists
  9862.     select @publication_id = publication_id, @thirdparty_flag = thirdparty_flag,
  9863.         @immediate_sync = immediate_sync
  9864.         from MSpublications where 
  9865.         publication = @publication and
  9866.         publisher_id = @publisher_id and 
  9867.         publisher_db = @publisher_db
  9868.     if @publication_id is NULL
  9869.     begin
  9870.         raiserror(20026, 16, -1, @publication)
  9871.         return (1)
  9872.     end
  9873.  
  9874.     -- Make sure article exists
  9875.     declare @source_object sysname
  9876.     select @article_id = article_id, @source_object = source_object
  9877.         from MSarticles where 
  9878.         publication_id = @publication_id and
  9879.         publisher_id = @publisher_id and 
  9880.         publisher_db = @publisher_db and 
  9881.         article = @article
  9882.     if @article_id is NULL
  9883.     begin
  9884.         if @thirdparty_flag = 1
  9885.         begin
  9886.             raiserror(20027, 16, -1, @article)
  9887.             return (1)
  9888.         end
  9889.         else
  9890.             return (0)
  9891.     end
  9892.  
  9893.     -- Check to make sure that there are no subscriptions on the article
  9894.     if exists (select * from MSsubscriptions where 
  9895.         publisher_id = @publisher_id and
  9896.         publisher_db = @publisher_db and
  9897.         publication_id = @publication_id and
  9898.         article_id = @article_id and
  9899.         subscriber_id >= 0)             -- ignore virtual subscriptions
  9900.     begin
  9901.         raiserror(14046, 16, -1)
  9902.         return(1)
  9903.     end
  9904.  
  9905.     begin tran
  9906.     save tran MSdrop_article
  9907.  
  9908.     -- For third party publications drop immediate sync and anonymous virtual subscriptions
  9909.     -- SQL Server publications will do this via RPC calls to sp_MSadd_subscription
  9910.     if @thirdparty_flag = 1 and @immediate_sync = 1
  9911.     begin
  9912.         begin
  9913.             exec @retcode = dbo.sp_MSdrop_subscription
  9914.                 @publisher = @publisher,
  9915.                 @publisher_db = @publisher_db,
  9916.                 @publication = @publication,
  9917.                 @article_id = @article_id,
  9918.                 @subscriber = NULL                  -- virtual subscription
  9919.             if @retcode <> 0 or @@error <> 0
  9920.             begin
  9921.                 if @@trancount > 0
  9922.                 begin
  9923.                     rollback tran MSdrop_article
  9924.                     commit tran
  9925.                 end
  9926.                 return (1)
  9927.             end
  9928.         end
  9929.     end
  9930.  
  9931.     delete from MSarticles where
  9932.         publisher_id = @publisher_id and
  9933.         publisher_db = @publisher_db and
  9934.         publication_id = @publication_id and
  9935.         article_id = @article_id
  9936.     if @@error <> 0
  9937.     begin
  9938.         if @@trancount > 0
  9939.         begin
  9940.             rollback tran MSdrop_article
  9941.             commit tran
  9942.         end
  9943.         return (1)
  9944.     end
  9945.  
  9946.     if not exists (select * from MSarticles  where 
  9947.         publisher_id = @publisher_id and
  9948.         publisher_db = @publisher_db and
  9949.         source_object = @source_object)
  9950.     begin
  9951.         delete MSrepl_identity_range where 
  9952.             publisher = @publisher and
  9953.             publisher_db = @publisher_db and
  9954.             tablename = @source_object
  9955.         if @@ERROR <> 0 begin
  9956.             if @@trancount > 0
  9957.                 ROLLBACK TRAN
  9958.             RETURN (1)
  9959.         end
  9960.     end
  9961.  
  9962.     commit tran
  9963. go
  9964.  
  9965. raiserror(15339,-1,-1,'sp_MSdrop_snapshot_agent')
  9966. GO
  9967. CREATE PROCEDURE sp_MSdrop_snapshot_agent (
  9968.     @publisher sysname,
  9969.     @publisher_db sysname,
  9970.     @publication sysname
  9971. ) AS
  9972.  
  9973.  
  9974.     SET NOCOUNT ON
  9975.  
  9976.     /*
  9977.     ** Declarations.
  9978.     */
  9979.     DECLARE @retcode    int
  9980.     DECLARE @job_id     binary(16)
  9981.     DECLARE @local_job  bit
  9982.     DECLARE @publisher_id smallint
  9983.     DECLARE @name       nvarchar(100)
  9984.     DECLARE @agent_id   int
  9985.  
  9986.     /*
  9987.     ** Initializations
  9988.     */
  9989.     select @publisher_id = srvid from master..sysservers where
  9990.         UPPER(srvname) = UPPER(@publisher)
  9991.  
  9992.  
  9993.  
  9994.     SELECT @job_id = job_id, @local_job = local_job, @name = name, @agent_id = id  FROM MSsnapshot_agents WHERE
  9995.         publisher_id = @publisher_id AND
  9996.         publisher_db = @publisher_db AND
  9997.         publication = @publication
  9998.  
  9999.     -- Delete Perfmon instance
  10000.     dbcc deleteinstance ("SQL Replication Snapshot", @name)
  10001.  
  10002.     -- Return if not exists
  10003.     IF @local_job IS NULL
  10004.         RETURN(0)
  10005.  
  10006.     BEGIN TRAN
  10007.  
  10008.     IF @local_job = 1
  10009.     BEGIN
  10010.         -- Don't drop the job for third party publications.
  10011.         if exists (select * from msdb..MSdistpublishers where 
  10012.             UPPER(name) = UPPER(@publisher) and
  10013.             thirdparty_flag = 0)
  10014.         begin                            
  10015.             IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  10016.             BEGIN
  10017.                 EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  10018.                 IF @@ERROR <> 0 or @retcode <> 0
  10019.                     GOTO UNDO
  10020.             END
  10021.         end
  10022.     END
  10023.  
  10024.     DELETE MSsnapshot_agents WHERE id = @agent_id
  10025.     IF @@ERROR <> 0 
  10026.         GOTO UNDO
  10027.  
  10028.     -- Remove history
  10029.     DELETE MSsnapshot_history WHERE agent_id = @agent_id
  10030.     IF @@ERROR <> 0 
  10031.         GOTO UNDO
  10032.  
  10033.     IF @@ERROR <> 0 
  10034.         GOTO UNDO
  10035.  
  10036.     -- Update global replication status table
  10037.     EXEC dbo.sp_MSupdate_replication_status
  10038.         @publisher,
  10039.         @publisher_db,
  10040.         @publication,
  10041.         @agent_type = 1,
  10042.         @agent_name = @name,
  10043.         @status = -1    -- delete status
  10044.  
  10045.     COMMIT TRAN
  10046.  
  10047.     RETURN(0)
  10048.  
  10049. UNDO:
  10050.     if @@TRANCOUNT = 1
  10051.         ROLLBACK TRAN
  10052.     else
  10053.         COMMIT TRAN
  10054.     return(1)
  10055. GO
  10056.  
  10057.  
  10058. raiserror(15339,-1,-1,'sp_MSdrop_logreader_agent')
  10059. GO
  10060. CREATE PROCEDURE sp_MSdrop_logreader_agent (
  10061.     @publisher sysname,
  10062.     @publisher_db sysname,
  10063.     @publication sysname  --Only used by 3rd party publisher
  10064. ) AS
  10065.  
  10066.  
  10067.     SET NOCOUNT ON
  10068.  
  10069.     /*
  10070.     ** Declarations.
  10071.     */
  10072.     DECLARE @retcode    int
  10073.     DECLARE @job_id     binary(16)
  10074.     DECLARE @local_job  bit
  10075.     DECLARE @publisher_id smallint
  10076.     DECLARE @name       nvarchar(100)
  10077.     DECLARE @agent_id   int
  10078.  
  10079.     /*
  10080.     ** Initializations
  10081.     */
  10082.     select @publisher_id = srvid from master..sysservers where
  10083.         UPPER(srvname) = UPPER(@publisher)
  10084.  
  10085.  
  10086.     SELECT @job_id = job_id, @local_job = local_job, @name = name, @agent_id = id FROM MSlogreader_agents WHERE
  10087.         publisher_id = @publisher_id AND
  10088.         publisher_db = @publisher_db AND
  10089.         publication = @publication
  10090.  
  10091.     -- Delete Perfmon instance
  10092.     dbcc deleteinstance ("SQL Replication Logreader", @name)
  10093.  
  10094.     -- Return if not exists
  10095.     IF @local_job IS NULL
  10096.         RETURN(0)
  10097.  
  10098.     BEGIN TRAN
  10099.  
  10100.     IF @local_job = 1
  10101.     BEGIN
  10102.         -- Don't drop the job for third party publications.
  10103.         if exists (select * from msdb..MSdistpublishers where 
  10104.             UPPER(name) = UPPER(@publisher) and
  10105.             thirdparty_flag = 0)
  10106.         begin                            
  10107.             IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  10108.             BEGIN
  10109.                 EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  10110.                 IF @@ERROR <> 0 or @retcode <> 0
  10111.                     GOTO UNDO
  10112.             END
  10113.         end
  10114.     END
  10115.  
  10116.     DELETE MSlogreader_agents WHERE id = @agent_id
  10117.     IF @@ERROR <> 0 
  10118.         GOTO UNDO
  10119.  
  10120.     -- Remove history
  10121.     DELETE MSlogreader_history WHERE
  10122.         agent_id = @agent_id
  10123.  
  10124.     IF @@ERROR <> 0 
  10125.         GOTO UNDO
  10126.  
  10127.     -- Update global replication status table
  10128.     EXEC dbo.sp_MSupdate_replication_status
  10129.         @publisher,
  10130.         @publisher_db,
  10131.         @publication,
  10132.         @agent_type = 2,
  10133.         @agent_name = @name,
  10134.         @status = -1    -- delete status
  10135.  
  10136.     COMMIT TRAN
  10137.  
  10138.     RETURN(0)
  10139.  
  10140. UNDO:
  10141.     if @@TRANCOUNT = 1
  10142.         ROLLBACK TRAN
  10143.     else
  10144.         COMMIT TRAN
  10145.     return(1)
  10146. GO
  10147.  
  10148. raiserror(15339,-1,-1,'sp_MSdrop_publication')
  10149. go
  10150. CREATE PROCEDURE sp_MSdrop_publication
  10151. @publisher sysname,
  10152. @publisher_db sysname,
  10153. @publication sysname
  10154. as
  10155.  
  10156.     set nocount on
  10157.  
  10158.     declare @publisher_id smallint
  10159.     declare @publication_id int
  10160.     declare @retcode int
  10161.     declare @article sysname
  10162.     declare @thirdparty_flag bit
  10163.     DECLARE @working_dir nvarchar(255)
  10164.     DECLARE @pub_dir nvarchar(255)
  10165.  
  10166.  
  10167.     -- Check if publisher is a defined as a distribution publisher in the current database
  10168.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  10169.     if @retcode <> 0
  10170.     begin
  10171.         return(1)
  10172.     end
  10173.  
  10174.     -- Make sure publication exists
  10175.     select @publication_id = publication_id, @thirdparty_flag = thirdparty_flag 
  10176.         from MSpublications where publication = @publication and
  10177.         publisher_id = @publisher_id and publisher_db = @publisher_db
  10178.     if @publication_id is NULL
  10179.     begin
  10180.         -- We don't know whether or not it is a third party or not so we can not 
  10181.         -- return error.
  10182.         -- raiserror(20026, 16, -1, @publication)
  10183.         -- return (1)
  10184.         return (0)
  10185.     end
  10186.  
  10187.     -- Make sure that there are no subscriptions on the publication.
  10188.     if exists (select * from MSsubscriptions s, MSpublications p where 
  10189.         p.publisher_id = @publisher_id and
  10190.         p.publisher_db = @publisher_db and
  10191.         p.publication = @publication and
  10192.         s.publisher_id = @publisher_id and
  10193.         s.publisher_db = @publisher_db and
  10194.         s.publication_id = p.publication_id and
  10195.         s.subscriber_id >= 0)               -- ignore virtual subscriptions
  10196.     begin
  10197.         raiserror(14005, 16, -1)
  10198.         return(1)
  10199.     end
  10200.  
  10201.     SELECT @working_dir = working_directory FROM msdb..MSdistpublishers
  10202.         where UPPER(name) = UPPER(@publisher)
  10203.  
  10204.     IF @working_dir IS NOT NULL
  10205.     BEGIN
  10206.  
  10207.         -- Remove the pub dir under UNC and FTP if it exists
  10208.         -- Note: sp_MSreplremoveuncdir will convert unc path to local path.
  10209.         -- This is required. Otherwise we will see 'Access denied' error.
  10210.         SELECT @pub_dir = @working_dir + '\unc\' + 
  10211.                     @publisher + '_' +
  10212.                     @publisher_db + '_' +
  10213.                     @publication
  10214.         exec @retcode = sp_MSreplremoveuncdir @pub_dir
  10215.         if @retcode <> 0 or @@error <> 0
  10216.             return(1)
  10217.  
  10218.  
  10219.         SELECT @pub_dir = @working_dir + '\ftp\' + 
  10220.                     @publisher + '_' +
  10221.                     @publisher_db + '_' +
  10222.                     @publication 
  10223.         exec @retcode = sp_MSreplremoveuncdir @pub_dir
  10224.         if @retcode <> 0 or @@error <> 0
  10225.             return(1)
  10226.     END
  10227.  
  10228.     begin tran
  10229.     save tran MSdrop_publication
  10230.  
  10231.     -- Delete all articles if a third party publication
  10232.     if @thirdparty_flag = 1 
  10233.     begin
  10234.         -- Delete all articles in the publication
  10235.         declare hCarticles CURSOR LOCAL FAST_FORWARD FOR select article from MSarticles where 
  10236.             publisher_id = @publisher_id and
  10237.             publisher_db = @publisher_db and
  10238.             publication_id = 
  10239.                 (select publication_id from MSpublications where 
  10240.                     publisher_id = @publisher_id and
  10241.                     publisher_db = @publisher_db and
  10242.                     publication = @publication)
  10243.         open hCarticles
  10244.         fetch hCarticles into @article
  10245.         while (@@fetch_status <> -1)
  10246.         begin
  10247.             exec @retcode = dbo.sp_MSdrop_article @publisher, @publisher_db, @publication, @article
  10248.             if @retcode != 0 or @@error != 0
  10249.             begin
  10250.                 close hCarticles
  10251.                 deallocate hCarticles
  10252.                 if @@trancount > 0
  10253.                 begin
  10254.                     rollback tran MSdrop_publication
  10255.                     commit tran
  10256.                 end
  10257.                 return (1)
  10258.             end
  10259.                 
  10260.             fetch hCarticles into @article
  10261.         end
  10262.         close hCarticles
  10263.         deallocate hCarticles
  10264.     end
  10265.  
  10266.     delete from MSpublications where 
  10267.         publisher_id = @publisher_id and
  10268.         publisher_db = @publisher_db and
  10269.         publication = @publication
  10270.     if @@error <> 0
  10271.     begin
  10272.         if @@trancount > 0
  10273.         begin
  10274.             rollback tran MSdrop_publication
  10275.             commit tran
  10276.         end
  10277.         raiserror (14006, 16, -1)
  10278.         return (1)
  10279.     end
  10280.  
  10281.     -- Drop snapshot agent
  10282.     exec @retcode = dbo.sp_MSdrop_snapshot_agent
  10283.             @publisher = @publisher,
  10284.             @publisher_db = @publisher_db,
  10285.             @publication = @publication
  10286.     if @@ERROR<> 0 or @retcode <> 0
  10287.     begin
  10288.         if @@trancount > 0
  10289.         begin
  10290.             rollback tran MSdrop_publication
  10291.             commit tran
  10292.         end
  10293.         return (1)
  10294.     end
  10295.  
  10296.     -- Drop the logreader agent if
  10297.     -- 1. thirdparty publisher OR 
  10298.     -- 2. no publication left in the publisher database
  10299.     if @thirdparty_flag = 1 OR
  10300.         not exists (select * from MSpublications where 
  10301.             publisher_id = @publisher_id and
  10302.             publisher_db = @publisher_db)
  10303.     begin
  10304.         exec @retcode = dbo.sp_MSdrop_logreader_agent
  10305.                 @publisher = @publisher,
  10306.                 @publisher_db = @publisher_db,
  10307.                 @publication = @publication
  10308.         if @@ERROR<> 0 or @retcode <> 0
  10309.         begin
  10310.             if @@trancount > 0
  10311.             begin
  10312.                 rollback tran MSdrop_publication
  10313.                 commit tran
  10314.             end
  10315.             return (1)
  10316.         end
  10317.     end
  10318.  
  10319.     -- Delete anonymous agents
  10320.     delete MSdistribution_agents where
  10321.         publisher_id = @publisher_id and
  10322.         publisher_db = @publisher_db and
  10323.         publication = @publication
  10324.     if @@ERROR<> 0 or @retcode <> 0
  10325.     begin
  10326.         if @@trancount > 0
  10327.             rollback tran MSdrop_publication
  10328.         return (1)
  10329.     end
  10330.  
  10331.     delete MSmerge_agents where
  10332.         publisher_id = @publisher_id and
  10333.         publisher_db = @publisher_db and
  10334.         publication = @publication
  10335.     if @@ERROR<> 0 or @retcode <> 0
  10336.     begin
  10337.         if @@trancount > 0
  10338.             rollback tran MSdrop_publication
  10339.         return (1)
  10340.     end
  10341.  
  10342.     -- Cleanup publication access list table
  10343.     delete MSpublication_access where
  10344.         publication_id = @publication_id
  10345.     if @@ERROR<> 0 or @retcode <> 0
  10346.     begin
  10347.         if @@trancount > 0
  10348.             rollback tran MSdrop_publication
  10349.         return (1)
  10350.     end
  10351.  
  10352.     -- Remove publisher_id, publisher_db pair if no other publication is using it. 
  10353.     if not exists (select * from MSpublications where publisher_id = @publisher_id and
  10354.         publisher_db = @publisher_db)
  10355.     begin
  10356.         declare @publisher_database_id int
  10357.  
  10358.         select @publisher_database_id = id from MSpublisher_databases where 
  10359.             publisher_id = @publisher_id and 
  10360.             publisher_db = @publisher_db
  10361.  
  10362.         delete from MSrepl_backup_lsns where 
  10363.             publisher_database_id = @publisher_database_id
  10364.  
  10365.         delete from MSpublisher_databases where 
  10366.             publisher_id = @publisher_id and publisher_db = @publisher_db
  10367.         if @@error <> 0
  10368.         begin
  10369.             if @@trancount > 0
  10370.             begin
  10371.                 rollback tran MSdrop_publication
  10372.                 commit tran
  10373.             end
  10374.             return (1)
  10375.         end
  10376.  
  10377.         -- Cleaning up MSrepl_originators
  10378.         delete MSrepl_originators where
  10379.             publisher_database_id = @publisher_database_id
  10380.         if @@error <> 0
  10381.         begin
  10382.             if @@trancount > 0
  10383.                 rollback tran MSdrop_publication
  10384.             return (1)
  10385.         end
  10386.  
  10387.     end
  10388.  
  10389.     commit tran
  10390. go
  10391. raiserror(15339,-1,-1,'sp_MSadd_snapshot_agent')
  10392. GO
  10393. CREATE PROCEDURE sp_MSadd_snapshot_agent (
  10394.     @name nvarchar(100) = NULL,
  10395.     @publisher sysname,
  10396.     @publisher_db sysname,
  10397.     @publication sysname,  
  10398.     @publication_type int = 0,              -- 0 Transactional 1 Snapshot 2 Merge
  10399.     @local_job bit,  
  10400.     @freqtype  int = 4 ,                  /* 4== Daily */
  10401.     @freqinterval int  = 1,             /* Every day */
  10402.     @freqsubtype int =  4,                 /* Sub interval = Minute */
  10403.     @freqsubinterval int = 5,              /* Every five minutes */
  10404.     @freqrelativeinterval int = 1, 
  10405.     @freqrecurrencefactor int = 0, 
  10406.     @activestartdate int = 0,             /* 12:00 am - 11:59 pm */
  10407.     @activeenddate int =99991231 ,         /* No start date */    
  10408.     @activestarttimeofday int = 0,         
  10409.     @activeendtimeofday int = 235959,     /* No end time */    
  10410.     @command nvarchar(4000) = NULL,
  10411.     @job_existing bit = 0,   -- for 6x publisher
  10412.     @snapshot_jobid binary(16) = NULL OUTPUT
  10413. ) AS
  10414.  
  10415.  
  10416.     SET NOCOUNT ON
  10417.  
  10418.     /*
  10419.     ** Declarations.
  10420.     */
  10421.     DECLARE @retcode            int
  10422.     DECLARE @publisher_id       smallint
  10423.     DECLARE @profile_id         int
  10424.     DECLARE @snapshot_type      int
  10425.     DECLARE @databasename       sysname
  10426.     DECLARE @agent_id           int
  10427.  
  10428.     DECLARE @distributor_security_mode      int                     /* 0 standard; 1 integrated */
  10429.     DECLARE @distributor_login              sysname 
  10430.     DECLARE @distributor_password           nvarchar(524)
  10431.     DECLARE @category_name      sysname
  10432.     DECLARE @platform_nt        binary
  10433.  
  10434.     /*
  10435.     ** Initializations
  10436.     */
  10437.     select @platform_nt = 0x1
  10438.  
  10439.     select @publisher_id = srvid from master..sysservers where
  10440.         UPPER(srvname) = UPPER(@publisher)
  10441.  
  10442.     -- Always use integrated security on winNT
  10443.     if (@platform_nt = platform() & @platform_nt)
  10444.         set @distributor_security_mode = 1
  10445.     else
  10446.     begin
  10447.         select  @distributor_security_mode = 0,
  10448.                 @distributor_login  = login,
  10449.                 @distributor_password = password
  10450.             from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername)
  10451.     end
  10452.  
  10453.     select @command = @command + ' -DistributorSecurityMode ' + 
  10454.         convert(nvarchar(10),@distributor_security_mode) +  ' ' 
  10455.     if @distributor_security_mode <> 1
  10456.     begin
  10457.         if @distributor_login is not NULL
  10458.             select @command = @command + '-DistributorLogin ' + @distributor_login + ' '
  10459.         if @distributor_password is not NULL
  10460.             select @command = @command + '-DistributorEncryptedPassword ' + quotename(@distributor_password) + ' '
  10461.     end
  10462.  
  10463.     -- if @name is not null and @job_existing = 1, the proc is from DMO scripting
  10464.     -- check to see if the job is there or not, if not, reset @job_existing
  10465.     -- value. This is for the case when the user generate the script at
  10466.     -- the publisher but did not re-create repl jobs at the distributor.
  10467.     -- We don't want to reset the @name parameter to null here because 
  10468.     -- the user probably expects us to create a job with the given name.
  10469.     if @local_job = 1 and @job_existing = 1 and @name is not null and 
  10470.        @name <> N''
  10471.     begin
  10472.         if not exists (select * from msdb..sysjobs_view where 
  10473.             name = @name and
  10474.             UPPER(originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName'))))
  10475.         begin
  10476.             set @job_existing = 0
  10477.         end
  10478.     end
  10479.  
  10480.     BEGIN TRAN
  10481.     
  10482.     /* Code for snapshot agent type in MSagent_profiles */
  10483.     SELECT @snapshot_type = 1
  10484.  
  10485.     -- Get the default profile ID for the snapshot agent type. If a third party publication
  10486.     -- no profile is used.
  10487.     if exists (select * from MSpublications where 
  10488.                 publisher_id = @publisher_id and
  10489.                 publisher_db = @publisher_db and
  10490.                 publication = @publication and
  10491.                 thirdparty_flag = 1)
  10492.     begin
  10493.         set @profile_id = 0
  10494.     end
  10495.     else
  10496.     begin
  10497.          SELECT @profile_id = profile_id FROM msdb..MSagent_profiles WHERE 
  10498.             agent_type = @snapshot_type and
  10499.             def_profile = 1
  10500.     end
  10501.  
  10502.  
  10503.     if not exists (select * from MSsnapshot_agents where
  10504.         publisher_id = @publisher_id and
  10505.         publisher_db = @publisher_db and
  10506.         publication = @publication)
  10507.     begin
  10508.         /* 
  10509.         ** Insert row
  10510.         */
  10511.         INSERT INTO MSsnapshot_agents (name, publisher_id, publisher_db, publication, publication_type,
  10512.                                 local_job, profile_id)
  10513.              VALUES ('',@publisher_id, @publisher_db, @publication, @publication_type, @local_job, @profile_id)
  10514.         IF @@ERROR <> 0
  10515.             GOTO UNDO
  10516.  
  10517.         set @agent_id = @@IDENTITY
  10518.     end
  10519.     else
  10520.         select @agent_id = id from MSsnapshot_agents where
  10521.             publisher_id = @publisher_id and
  10522.             publisher_db = @publisher_db and
  10523.             publication = @publication
  10524.  
  10525.     DECLARE @name_is_generated bit
  10526.     SELECT @name_is_generated = 0     
  10527.     IF @name IS NULL OR @name = N''
  10528.     BEGIN
  10529.         SELECT @name_is_generated = 1
  10530.         SELECT @name = CONVERT(nvarchar(28),@publisher ) + '-' + CONVERT(nvarchar(28),@publisher_db) + '-' + 
  10531.                         CONVERT(nvarchar(28),@publication) + '-'  + CONVERT(nvarchar, @agent_id)
  10532.     END
  10533.  
  10534.     -- If the generated name already exists, re-generate the name with a 
  10535.     -- guid appended
  10536.     IF @name_is_generated = 1
  10537.     BEGIN
  10538.         IF EXISTS (SELECT * FROM msdb..sysjobs_view 
  10539.                     WHERE name = @name 
  10540.                       AND UPPER(originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName'))))
  10541.         BEGIN
  10542.             SELECT @name = fn_repluniquename(newid(), @publisher, @publisher_db, 
  10543.                 @publication, null)
  10544.         END            
  10545.     END
  10546.  
  10547.     -- Add Perfmon instance
  10548.     dbcc addinstance ("SQL Replication Snapshot", @name)
  10549.  
  10550.     IF @local_job = 1 and @job_existing = 0
  10551.     BEGIN
  10552.  
  10553.     -- ********WORKAROUND********
  10554.         DECLARE @nullchar nchar(20)
  10555.         SELECT @nullchar = NULL
  10556.     -- ********WORKAROUND********
  10557.  
  10558.         set @databasename = db_name()
  10559.         -- Get Snapshot category name (assumes category_id = 15)
  10560.         select @category_name = name FROM msdb.dbo.syscategories where category_id = 15
  10561.  
  10562.         EXECUTE @retcode = dbo.sp_MSadd_repl_job 
  10563.             @name = @name, 
  10564.             @subsystem = 'Snapshot', 
  10565.             @server = @publisher, 
  10566.             @databasename = @databasename, 
  10567.             @enabled = 1, 
  10568.             @freqtype = @freqtype, 
  10569.             @freqinterval = @freqinterval, 
  10570.             @freqsubtype = @freqsubtype, 
  10571.             @freqsubinterval = @freqsubinterval, 
  10572.             @freqrelativeinterval = @freqrelativeinterval, 
  10573.             @freqrecurrencefactor = @freqrecurrencefactor, 
  10574.             @activestartdate = @activestartdate, 
  10575.             @activeenddate = @activeenddate, 
  10576.             @activestarttimeofday = @activestarttimeofday, 
  10577.             @activeendtimeofday = @activeendtimeofday, 
  10578.             @nextrundate = 0,
  10579.             @nextruntime = 0,
  10580.             @runpriority = 0,
  10581.             @emailoperatorname = @nullchar,
  10582.             @retryattempts = 10, 
  10583.             @retrydelay = 1, 
  10584.             @command = @command, 
  10585.             @loghistcompletionlevel = 0, 
  10586.             @emailcompletionlevel = 0, 
  10587.             @description = @nullchar,
  10588.             @tagadditionalinfo = @nullchar,
  10589.             @tagobjectid = 0, 
  10590.             @tagobjecttype = 0, 
  10591.             @category_name = @category_name,
  10592.             @failure_detection = 1,
  10593.             @agent_id = @agent_id,
  10594.             @job_id = @snapshot_jobid OUTPUT
  10595.  
  10596.   
  10597.        IF @@ERROR <> 0 or @retcode <> 0
  10598.             GOTO UNDO
  10599.     END
  10600.  
  10601.     if @local_job = 1 and @job_existing = 1 
  10602.     begin
  10603.         if @snapshot_jobid is null
  10604.         begin
  10605.             select @snapshot_jobid = job_id from msdb..sysjobs_view where 
  10606.                 name = @name and
  10607.                 UPPER(originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName')))
  10608.             if @snapshot_jobid IS NULL
  10609.             begin
  10610.                 -- Message from msdb.dbo.sp_verify_job_identifiers
  10611.                 RAISERROR(14262, -1, -1, 'Job', @name)          
  10612.                 GOTO UNDO
  10613.             end
  10614.         end
  10615.         else
  10616.         begin
  10617.             if not exists (select * from msdb..sysjobs_view where 
  10618.                 job_id = @snapshot_jobid and
  10619.                 UPPER(originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName'))))
  10620.             begin
  10621.                 -- Message from msdb.dbo.sp_verify_job_identifiers
  10622.                 RAISERROR(14262, -1, -1, 'Job', @name)          
  10623.                 GOTO UNDO
  10624.             end
  10625.         end
  10626.     end
  10627.  
  10628. /* Moved up
  10629.     -- Get the job id if it already exists
  10630.     if @local_job = 1 and @job_existing = 1 
  10631.     begin
  10632.         select @snapshot_jobid = job_id from msdb..sysjobs_view where 
  10633.             job_id = @snapshot_jobid and
  10634.             UPPER(originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName')))
  10635.         if @snapshot_jobid IS NULL
  10636.         begin
  10637.             -- Message from msdb.dbo.sp_verify_job_identifiers
  10638.             RAISERROR(14262, -1, -1, 'Job', @name)          
  10639.             GOTO UNDO
  10640.         end
  10641.     end
  10642. */
  10643.  
  10644.     -- Generate a job GUID for remote agents. This will be used by the UI to uniquely
  10645.     -- identify rows returned by the enums
  10646.     if @local_job = 0
  10647.     begin
  10648.         -- Third party publication will pass in snapshot agent name which is created as
  10649.         -- a SQLServerAgent job.
  10650.         if @name is not null 
  10651.             select @snapshot_jobid = job_id from msdb..sysjobs_view where
  10652.                 name = @name
  10653.         if @snapshot_jobid is null
  10654.             set @snapshot_jobid = newid()
  10655.         -- Reset @local_job to 1 so that repl monitor can start the job.
  10656.         -- In sp_MSdrop_snapshot_agent, we will not drop the job if the publication 
  10657.         -- is from third party.
  10658.         else
  10659.             set @local_job = 1
  10660.     end
  10661.  
  10662.     -- Caution: @local job might be changed from the passed in value.
  10663.     UPDATE MSsnapshot_agents SET 
  10664.         name = @name,
  10665.         job_id = @snapshot_jobid,
  10666.         -- Update the following fields because the row maybe added before this sp call
  10667.         -- by sp_MSadd_publication.
  10668.         publication_type = @publication_type,
  10669.         local_job = @local_job, 
  10670.         profile_id = @profile_id
  10671.         WHERE
  10672.         id = @agent_id
  10673.  
  10674.     IF @@ERROR <> 0
  10675.         GOTO UNDO
  10676.  
  10677.     -- Update global replication status table
  10678.     EXEC dbo.sp_MSupdate_replication_status
  10679.         @publisher,
  10680.         @publisher_db,
  10681.         @publication,
  10682.         @publication_type,
  10683.         @agent_type = 1,
  10684.         @agent_name = @name,
  10685.         @status = 0     -- not running status
  10686.  
  10687.     COMMIT TRAN
  10688.  
  10689.     RETURN(0)
  10690.  
  10691. UNDO:
  10692.     if @@TRANCOUNT = 1
  10693.         ROLLBACK TRAN
  10694.     else
  10695.         COMMIT TRAN
  10696.     return(1)
  10697. GO
  10698.  
  10699. raiserror(15339,-1,-1,'sp_MSadd_logreader_agent')
  10700. GO
  10701. CREATE PROCEDURE sp_MSadd_logreader_agent (
  10702.     @name nvarchar(100) = NULL,
  10703.     @publisher sysname,
  10704.     @publisher_db sysname,
  10705.     @publication sysname,   --Only used by 3rd party publisher
  10706.     @local_job bit,
  10707.     @job_existing bit = 0,
  10708.     @job_id binary(16) = NULL
  10709. ) AS
  10710.  
  10711.  
  10712.     SET NOCOUNT ON
  10713.  
  10714.     /*
  10715.     ** Declarations.
  10716.     */
  10717.     DECLARE @retcode            int
  10718.     DECLARE @agent_args         nvarchar(255)
  10719.     DECLARE @publisher_id       smallint
  10720.     DECLARE @profile_id         int
  10721.     DECLARE @logreader_type     int
  10722.     DECLARE @databasename       sysname
  10723.     DECLARE @agent_id           int
  10724.     DECLARE @distributor_security_mode      int                     /* 0 standard; 1 integrated */
  10725.     DECLARE @distributor_login              sysname 
  10726.     DECLARE @distributor_password           nvarchar(524)
  10727.     DECLARE @category_name      sysname
  10728.     DECLARE @platform_nt binary
  10729.  
  10730.     /*
  10731.     ** Initializations
  10732.     */
  10733.     select @platform_nt = 0x1
  10734.  
  10735.     select @publisher_id = srvid from master..sysservers where
  10736.         UPPER(srvname) = UPPER(@publisher)
  10737.     
  10738.     -- Always use integrated security on winNT
  10739.     if (@platform_nt = platform() & @platform_nt)
  10740.         set @distributor_security_mode = 1
  10741.     else
  10742.     begin
  10743.         select  @distributor_security_mode = 0,
  10744.                 @distributor_login  = login,
  10745.                 @distributor_password = password
  10746.             from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername)
  10747.     end
  10748.  
  10749.     -- if @name is not null and @job_existing = 1, the proc is from DMO scripting
  10750.     -- check to see if the job is there are not, if not, reset @job_existing and
  10751.     -- @name values. This is for the case when the user generate the script at
  10752.     -- the publisher but did not re-create repl jobs at the distributor.
  10753.     if @local_job = 1 and @job_existing = 1 and @name is not null and 
  10754.        @name <> N''
  10755.     begin
  10756.         if not exists (select * from msdb..sysjobs_view where 
  10757.             name = @name and
  10758.             UPPER(originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName'))))
  10759.         begin
  10760.             set @job_existing = 0
  10761.             set @name = null
  10762.         end
  10763.     end
  10764.  
  10765.     BEGIN TRAN
  10766.  
  10767.     -- If creating locally, try to drop it first
  10768.     IF @local_job = 1 and @job_existing = 0
  10769.     begin
  10770.         EXEC dbo.sp_MSdrop_logreader_agent 
  10771.             @publisher = @publisher,
  10772.             @publisher_db = @publisher_db,
  10773.             @publication = @publication  
  10774.         IF @@ERROR <> 0
  10775.             GOTO UNDO
  10776.     end
  10777.  
  10778.     /* Code for log reader agent type in MSagent_profiles */
  10779.     SELECT @logreader_type = 2
  10780.  
  10781.     -- Get the default profile ID for the logreader agent type. If a third party publication
  10782.     -- no profile is used.
  10783.     if exists (select * from MSpublications where 
  10784.                 publisher_id = @publisher_id and
  10785.                 publisher_db = @publisher_db and
  10786.                 publication = @publication and
  10787.                 thirdparty_flag = 1)
  10788.     begin
  10789.         set @profile_id = 0
  10790.     end
  10791.     else
  10792.     begin
  10793.         SELECT @profile_id = profile_id FROM msdb..MSagent_profiles WHERE 
  10794.             agent_type = @logreader_type and
  10795.             def_profile = 1
  10796.     end
  10797.  
  10798.     /* 
  10799.     ** Insert row
  10800.     */
  10801.     INSERT INTO MSlogreader_agents (name, publisher_id, publisher_db, publication, 
  10802.                     local_job, profile_id)
  10803.          VALUES ('',@publisher_id, @publisher_db, @publication, @local_job, @profile_id)
  10804.     IF @@ERROR <> 0
  10805.         GOTO UNDO
  10806.  
  10807.     set @agent_id = @@IDENTITY
  10808.         
  10809.     DECLARE @name_is_generated bit
  10810.     SELECT @name_is_generated = 0     
  10811.     IF @name IS NULL OR @name = N''
  10812.     BEGIN
  10813.         SELECT @name_is_generated = 1
  10814.         SELECT @name = CONVERT(nvarchar(43),@publisher ) + '-' + CONVERT(nvarchar(43),@publisher_db) + '-' + CONVERT(nvarchar, @@IDENTITY)
  10815.     END
  10816.  
  10817.     -- If the generated name already exists, re-generate the name with a 
  10818.     -- guid appended
  10819.     IF @name_is_generated = 1
  10820.     BEGIN
  10821.         IF EXISTS (SELECT * FROM msdb..sysjobs_view 
  10822.                     WHERE name = @name 
  10823.                       AND UPPER(originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName'))))
  10824.         BEGIN
  10825.             SELECT @name = fn_repluniquename(newid(), @publisher, @publisher_db, null, null)
  10826.         END            
  10827.     END
  10828.     
  10829.     -- Add Perfmon instance
  10830.     dbcc addinstance ("SQL Replication Logreader", @name)
  10831.  
  10832.     IF @local_job = 1 and @job_existing = 0
  10833.     BEGIN            
  10834.         SELECT @agent_args = '-Publisher ' + QUOTENAME(@publisher)
  10835.         SELECT @agent_args = @agent_args + ' -PublisherDB ' + QUOTENAME(@publisher_db)
  10836.         SELECT @agent_args = @agent_args + ' -Distributor ' + QUOTENAME(@@SERVERNAME)
  10837.  
  10838.         select @agent_args = @agent_args + ' -DistributorSecurityMode ' + 
  10839.             convert(nvarchar(10),@distributor_security_mode) +  ' ' 
  10840.         if @distributor_security_mode <> 1
  10841.         begin
  10842.             if @distributor_login is not NULL
  10843.                 select @agent_args = @agent_args + '-DistributorLogin ' + @distributor_login + ' '
  10844.             if @distributor_password is not NULL
  10845.                 select @agent_args = @agent_args + '-DistributorEncryptedPassword ' + quotename(@distributor_password) + ' '
  10846.         end
  10847.  
  10848. --    *******WORKAROUND*******
  10849.         DECLARE @nullchar nchar(20)
  10850.         SELECT @nullchar = NULL
  10851. --    *******WORKAROUND*******
  10852.  
  10853.         set @databasename = db_name()
  10854.         -- Get Logreader category name (assumes category_id = 13)
  10855.         select @category_name = name FROM msdb.dbo.syscategories where category_id = 13
  10856.  
  10857.         EXECUTE @retcode = dbo.sp_MSadd_repl_job
  10858.         @name = @name,
  10859.         @subsystem = 'LogReader',
  10860.         @server = @publisher,
  10861.         @databasename = @databasename,
  10862.         @enabled = 1,
  10863.         @freqtype = 64,       /* Auto-Start */
  10864.         @freqinterval                   = 1,
  10865.         @freqsubtype                    = 1,
  10866.         @freqsubinterval                = 1,
  10867.         @freqrelativeinterval= 1,
  10868.         @freqrecurrencefactor   = 1,
  10869.         @activestartdate                = 0,
  10870.         @activeenddate                  = 0,
  10871.         @activestarttimeofday   = 0,
  10872.         @activeendtimeofday     = 0,
  10873.         @nextrundate                    = 12355,
  10874.         @nextruntime                    = 13423,
  10875.         @runpriority                    = 0,
  10876.         @emailoperatorname              = @nullchar,
  10877.         @retryattempts = 10,            
  10878.         @retrydelay = 1,    
  10879.         @command = @agent_args,
  10880.         @loghistcompletionlevel = 0,
  10881.         @category_name = @category_name,
  10882.         @failure_detection = 1,
  10883.         @agent_id = @agent_id,
  10884.         @job_id = @job_id OUTPUT
  10885.  
  10886.   
  10887.        IF @@ERROR <> 0 or @retcode <> 0
  10888.             GOTO UNDO
  10889.     END
  10890.  
  10891.     if @local_job = 1 and @job_existing = 1 
  10892.     begin
  10893.         if @job_id is null
  10894.         begin
  10895.             select @job_id = job_id from msdb..sysjobs_view where 
  10896.                 name = @name and
  10897.                 UPPER(originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName')))
  10898.             if @job_id IS NULL
  10899.             begin
  10900.                 -- Message from msdb.dbo.sp_verify_job_identifiers
  10901.                 RAISERROR(14262, -1, -1, 'Job', @name)          
  10902.                 GOTO UNDO
  10903.             end
  10904.         end
  10905.         else
  10906.         begin
  10907.             if not exists (select * from msdb..sysjobs_view where 
  10908.                 job_id = @job_id and
  10909.                 UPPER(originating_server) = UPPER(CONVERT(NVARCHAR(30), SERVERPROPERTY('ServerName'))))
  10910.             begin
  10911.                 -- Message from msdb.dbo.sp_verify_job_identifiers
  10912.                 RAISERROR(14262, -1, -1, 'Job', @name)          
  10913.                 GOTO UNDO
  10914.             end
  10915.         end
  10916.     end
  10917.  
  10918.     -- Generate a job GUID for remote agents. This will be used by the UI to uniquely
  10919.     -- identify rows returned by the enums
  10920.     if @local_job = 0
  10921.     begin
  10922.         -- Third party publication will pass in logreader agent name which is created as
  10923.         -- a SQLServerAgent job.
  10924.         if @name is not null 
  10925.             select @job_id = job_id from msdb..sysjobs_view where
  10926.                 name = @name
  10927.         if @job_id is null
  10928.             set @job_id = newid()
  10929.         -- Reset @local_job to 1 so that repl monitor can start the job.
  10930.         -- In sp_MSdrop_logreader_agent, we will not drop the job if the publication 
  10931.         -- is from third party.
  10932.         else
  10933.             set @local_job = 1
  10934.     end
  10935.  
  10936.     UPDATE MSlogreader_agents SET name = @name,
  10937.         job_id = @job_id WHERE
  10938.         id = @agent_id
  10939.     IF @@ERROR <> 0
  10940.         GOTO UNDO
  10941.  
  10942.     -- Update global replication status table
  10943.     EXEC dbo.sp_MSupdate_replication_status
  10944.         @publisher,
  10945.         @publisher_db,
  10946.         @publication,
  10947.         @agent_type = 2,
  10948.         @agent_name = @name,
  10949.         @status = 0     -- not running status
  10950.  
  10951.  
  10952.     COMMIT TRAN
  10953.  
  10954.     RETURN(0)
  10955.  
  10956. UNDO:
  10957.     if @@TRANCOUNT = 1
  10958.         ROLLBACK TRAN
  10959.     else
  10960.         COMMIT TRAN
  10961.     return(1)
  10962. GO
  10963.  
  10964. raiserror(15339,-1,-1,'sp_MSadd_publication')
  10965. go
  10966. CREATE PROCEDURE sp_MSadd_publication (
  10967.     @publisher sysname,
  10968.     @publisher_db sysname,
  10969.     @publication sysname,
  10970.     @publication_id int = 0,                    -- REMOVE
  10971.     @publication_type int = 1,                  -- 0 = Transactional 1 = Snapshot  2 = Merge
  10972.     @independent_agent bit = 0,
  10973.     @immediate_sync bit = 0,
  10974.     @allow_push bit = 1,
  10975.     @allow_pull bit = 0,
  10976.     @allow_anonymous bit = 0,
  10977.     @snapshot_agent nvarchar(100) = NULL,
  10978.     @logreader_agent nvarchar (100) = NULL,
  10979.     @description nvarchar(255) = NULL,
  10980.     @retention int =60,
  10981.     @vendor_name nvarchar(100) = 'Microsoft SQL Server',
  10982.     @sync_method int = 0,
  10983.     @allow_subscription_copy bit = 0,
  10984.     @thirdparty_options int = NULL,
  10985.      @allow_queued_tran bit = 0,
  10986.      @queue_type int = NULL
  10987. )
  10988. as
  10989. BEGIN
  10990.     set nocount on
  10991.  
  10992.     declare @thirdparty_flag bit                    -- 0 = SQL Server 1 = Third Party
  10993.             ,@publisher_id smallint
  10994.             ,@retcode int
  10995.             ,@platform_nt binary
  10996.             ,@platform_desktop int
  10997.             ,@agentname nvarchar(100)
  10998.             ,@max_distretention int
  10999.  
  11000.     select @platform_nt = 0x1
  11001.             ,@platform_desktop = 0x100
  11002.  
  11003.     -- Check if publisher is a defined as a distribution publisher in the current database
  11004.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  11005.     if @retcode <> 0
  11006.     begin
  11007.         return(1)
  11008.     end
  11009.  
  11010.     EXEC @retcode = sp_helpdistributor @max_distretention = @max_distretention OUTPUT
  11011.     if @retcode <>0
  11012.     begin
  11013.         return (1)
  11014.     end
  11015.  
  11016.     -- Get third party flag
  11017.     select @thirdparty_flag = thirdparty_flag from msdb..MSdistpublishers
  11018.         where UPPER(name) = UPPER(@publisher)
  11019.     
  11020.     /*
  11021.     ** Parameter Check: @publication. (For 3rd party publications.)
  11022.     ** The @publication name must conform to the rules for identifiers,
  11023.     ** and must not be the keyword 'all'.
  11024.     */
  11025.  
  11026.     IF @publication IS NULL
  11027.         BEGIN
  11028.             RAISERROR (14043, 16, -1, '@publication')
  11029.             RETURN (1)
  11030.         END
  11031.  
  11032.     exec @retcode = dbo.sp_MSreplcheck_name @publication
  11033.     if @@ERROR <> 0 or @retcode <> 0
  11034.         return(1)
  11035.  
  11036.     IF LOWER (@publication) = 'all'
  11037.         BEGIN
  11038.             RAISERROR (14034, 16, -1)
  11039.             RETURN (1)
  11040.         END
  11041.  
  11042.  
  11043.     -- Parameter Check: @publication_type
  11044.     -- Make sure that the publication type is one of the following:
  11045.     -- 0  transactional
  11046.     -- 1  snapshot
  11047.     -- 2  merge
  11048.     if @publication_type not in (0,1,2)
  11049.     begin
  11050.         raiserror(20033, 16, -1)
  11051.         return (1)
  11052.     end
  11053.  
  11054.     -- disable tran/queued publishing on Win9x
  11055.     if (@publication_type = 0 or @allow_queued_tran = 1) and (platform() & @platform_nt != @platform_nt)
  11056.     begin
  11057.         -- Note 21052 was deleted and then changed. This message should go into messages.sql post shiloh
  11058.         --raiserror(21052, 16, -1)
  11059.         raiserror('Distributor for transactional or queued publications has to run on Windows NT platforms only.', 16, 1)
  11060.         return (1)
  11061.     end
  11062.  
  11063.     if (@publication_type = 0) and (platform() & @platform_desktop = @platform_desktop)
  11064.     begin
  11065.         raiserror(21108, 16, -1)
  11066.         return (1)
  11067.     end
  11068.  
  11069.     -- Parameter Check: @immediate_sync
  11070.     -- The publication must support independent_agent to support immediate_sync
  11071.     if @immediate_sync = 1 and @independent_agent != 1
  11072.     begin
  11073.         raiserror(21022, 16, -1)
  11074.         return (1)
  11075.     end
  11076.  
  11077.     -- Parameter Check: @allow_anonymous
  11078.     -- The publication must support immediate_sync to support anonymous.
  11079.     if @allow_anonymous = 1 and @immediate_sync != 1
  11080.     begin
  11081.         raiserror(20011, 16, -1)
  11082.         return (1)
  11083.     end
  11084.     
  11085.     -- Make sure publication does not already exist
  11086.     if exists (select * from MSpublications where publication = @publication and
  11087.         publisher_id = @publisher_id and publisher_db = @publisher_db)
  11088.     begin
  11089.         if @thirdparty_flag = 1
  11090.         begin
  11091.             raiserror(14016, 16, -1, @publication)
  11092.             return (1)
  11093.         end
  11094.         else
  11095.         begin
  11096.             exec @retcode = dbo.sp_MSdrop_publication 
  11097.                 @publisher = @publisher,
  11098.                 @publisher_db = @publisher_db,
  11099.                 @publication = @publication
  11100.             if @@error <> 0 or @retcode <> 0
  11101.                 return (1)
  11102.         end
  11103.     end
  11104.  
  11105.      --
  11106.      -- For MSMQ queue type - Distributor needs to support MSMQ 2.0
  11107.      --
  11108.      if (@queue_type = 1 and @allow_queued_tran = 1)
  11109.      begin
  11110.          --
  11111.          -- Now we use xp_MSver to detect NT OS version
  11112.          -- MSMQ subscription only allowed for platforms that support MSMQ 2.0
  11113.          -- version 5.0.2195 or higher
  11114.          --
  11115.          create table #tosversion ( propid int, propname sysname collate database_default, value int, charvalue nvarchar(255) collate database_default)
  11116.          insert into #tosversion (propid, propname, value, charvalue)
  11117.              exec master.dbo.xp_msver N'WindowsVersion'
  11118.  
  11119.          declare @vervalue int
  11120.              ,@lobyte tinyint
  11121.              ,@hibyte tinyint
  11122.              ,@loword smallint
  11123.              ,@hiword smallint
  11124.  
  11125.          --
  11126.          -- low order byte of low order word = OSmajor, high order byte of low order word = OSminor
  11127.          -- high order word = OSbuild
  11128.          --
  11129.          select @vervalue = value from #tosversion where propname = N'WindowsVersion'
  11130.          select @loword = (@vervalue & 0xffff)
  11131.                  ,@hiword = (@vervalue / 0x10000) & 0xffff
  11132.          select @lobyte = @loword & 0xff
  11133.                  ,@hibyte = (@loword / 100) & 0xff
  11134.          drop table #tosversion
  11135.  
  11136.          --
  11137.          -- check for OS major version
  11138.          --
  11139.          if (@lobyte < 5)
  11140.          begin
  11141.              raiserror(21334, 16, 4, '2.0')
  11142.              return (1)
  11143.          end
  11144.  
  11145.          --
  11146.          -- check for OS build version
  11147.          --
  11148.          if (@lobyte = 5 and @hiword < 2195)
  11149.          begin
  11150.              raiserror(21334, 16, 5, '2.0')
  11151.              return (1)
  11152.          end
  11153.      end
  11154.     
  11155.     begin tran
  11156.     save tran MSadd_publication
  11157.  
  11158.     insert into MSpublications values (@publisher_id, @publisher_db, @publication, 
  11159.         @publication_type, @thirdparty_flag, @independent_agent, @immediate_sync, @allow_push,
  11160.         @allow_pull, @allow_anonymous, @description, @vendor_name, @retention, 
  11161.         @sync_method, @allow_subscription_copy, @thirdparty_options, @allow_queued_tran)
  11162.     if @@error <> 0
  11163.         goto UNDO
  11164.  
  11165.     -- Enable the distribution cleanup agent if transactional or snapshot publicational
  11166.     if @publication_type = 0 or @publication_type = 1
  11167.     begin
  11168.         select @agentname = name from msdb..sysjobs j, msdb..sysjobsteps s where 
  11169.             j.job_id = s.job_id and
  11170.             j.category_id = 11 and
  11171.             s.database_name = db_name()
  11172.  
  11173.         exec @retcode = msdb.dbo.sp_update_job @job_name=@agentname, @enabled=1
  11174.         if @@error <> 0 or @retcode <> 0
  11175.             goto UNDO
  11176.     end
  11177.  
  11178.     -- Add snapshot and logreader agent
  11179.     
  11180.     -- Always add a non local snapshot agent. This is to cover the case
  11181.     -- when there's no SQLServerAgent job for the snapshot agent (For example, in Access).
  11182.     -- The agent entry is needed for initance check.
  11183.     -- sp_addpublication_snapshot will drop the entry and recreat it.
  11184.     exec @retcode = dbo.sp_MSadd_snapshot_agent
  11185.         @name = @snapshot_agent,
  11186.         @publisher = @publisher,
  11187.         @publisher_db = @publisher_db,
  11188.         @publication = @publication,
  11189.         @publication_type = @publication_type,
  11190.         @local_job = 0
  11191.     if @@error <> 0 or @retcode <> 0
  11192.         goto UNDO
  11193.  
  11194.  
  11195.     -- If null is passed in, we know that the agent is created already. (For SQL server).
  11196.     -- If not null is passed in, add the agents without creating local jobs (For third party).
  11197.     if @logreader_agent is not null
  11198.     begin
  11199.         exec @retcode = dbo.sp_MSadd_logreader_agent
  11200.             @name = @logreader_agent,
  11201.             @publisher = @publisher,
  11202.             @publisher_db = @publisher_db,
  11203.             @publication = @publication,
  11204.             @local_job = 0
  11205.         if @@error <> 0 or @retcode <> 0
  11206.             goto UNDO
  11207.     end
  11208.  
  11209.     -- If publisher_id, publisher_db pair is not in MSpublisher_databases then add it.  This will be used
  11210.     -- to store a publisher_database_id in the MSrepl_transactions and MSrepl_commands table.
  11211.     if not exists (select * from MSpublisher_databases where publisher_id = @publisher_id and
  11212.         publisher_db = @publisher_db)
  11213.     begin
  11214.         insert into MSpublisher_databases (publisher_id, publisher_db) values (@publisher_id, @publisher_db)
  11215.         if @@error <> 0
  11216.             goto UNDO
  11217.         insert into MSrepl_backup_lsns (publisher_database_id) values (@@identity)
  11218.         if @@error <> 0
  11219.             goto UNDO
  11220.     end
  11221.  
  11222.     commit tran
  11223.  
  11224.     return(0)
  11225.  
  11226. UNDO:
  11227.     if @@TRANCOUNT > 0
  11228.     begin
  11229.         ROLLBACK TRAN MSadd_publication
  11230.         COMMIT TRAN
  11231.     end
  11232.     return(1)
  11233. END
  11234. GO
  11235.  
  11236. /* 
  11237. **  History runstatus values defined in sqlrepl.h
  11238. **
  11239. **  Start       1
  11240. **  Succeed     2
  11241. **  Inprogress  3
  11242. **  Idle        4
  11243. **  Retry       5
  11244. **  Failure     6
  11245. */
  11246. GO
  11247.  
  11248. raiserror(15339,-1,-1,'sp_MSrepl_raiserror')
  11249. go
  11250. create proc sp_MSrepl_raiserror
  11251. @agent sysname,
  11252. @agent_name nvarchar(100),
  11253. @status int,
  11254. @message nvarchar(255),
  11255. @subscriber sysname = NULL,
  11256. @publication sysname = NULL,
  11257. @article sysname = NULL
  11258. as
  11259.     if @status = 2      --Succeeded
  11260.         raiserror (14150, 10, -1, @agent, @agent_name, @message)
  11261.     else if @status = 5 --Retry Failure
  11262.         raiserror (14152, 10, -1, @agent, @agent_name, @message)
  11263.     else if @status = 6 --Failure
  11264.     begin
  11265.         raiserror (14151, 18, -1, @agent, @agent_name, @message)
  11266.     end
  11267.     else if @status = 7
  11268.     begin
  11269.         raiserror (20574, 10, -1, @subscriber, @article, @publication)
  11270.     end
  11271.     else if @status = 8
  11272.     begin
  11273.         raiserror (20575, 10, -1, @subscriber, @article, @publication)
  11274.     end
  11275.     else if @status = 9
  11276.     begin
  11277.         raiserror (14158, 10, -1, @agent, @agent_name, @message)
  11278.     end
  11279. go
  11280.  
  11281. raiserror(15339,-1,-1,'sp_MSget_new_errorid')
  11282. GO
  11283.  
  11284. CREATE PROCEDURE sp_MSget_new_errorid
  11285. @errorid int OUTPUT,
  11286. @xact_seqno varbinary(16) = NULL,
  11287. @command_id int = NULL
  11288. AS
  11289.     set nocount on
  11290.  
  11291.     SELECT @errorid = NULL
  11292.  
  11293.     BEGIN TRAN sp_MSget_new_errorid
  11294.  
  11295.     SET ROWCOUNT 1
  11296.     SELECT @errorid = id FROM MSrepl_errors (UPDLOCK PAGLOCK)
  11297.         ORDER BY id DESC
  11298.     SET ROWCOUNT 0
  11299.  
  11300.     IF @errorid IS NULL
  11301.         SELECT @errorid = 1
  11302.     ELSE
  11303.         SELECT @errorid = @errorid + 1
  11304.  
  11305.     INSERT INTO MSrepl_errors VALUES (@errorid, 
  11306.         GETDATE(), NULL, /* Error with type NULL is placeholder, refer to sp_MSget_repl_error */
  11307.         NULL, NULL, NULL, NULL, @xact_seqno, @command_id)
  11308.  
  11309.     /* return an 0 error_id if failed to insert the row */
  11310.     IF @@ERROR <> 0
  11311.         SELECT @errorid = 0
  11312.  
  11313.     SELECT @errorid
  11314.  
  11315.     COMMIT TRAN
  11316. GO   
  11317.  
  11318. raiserror(15339,-1,-1,'sp_MSadd_qreader_history')
  11319. go
  11320. CREATE PROCEDURE sp_MSadd_qreader_history (
  11321.     @agent_id int,
  11322.     @pubid int = NULL,
  11323.     @runstatus int, 
  11324.     @comments nvarchar(255) = NULL,
  11325.     @transaction_id nvarchar(40) = NULL,
  11326.     @transaction_status int = 0,
  11327.     @transactions_processed int =0,
  11328.     @commands_processed int = 0,
  11329.     @seconds_elapsed int = 0,
  11330.     @subscriber sysname = NULL,
  11331.     @subscriberdb sysname = NULL,
  11332.     @perfmon_increment bit = 1,
  11333.     @log_error bit = 0,
  11334.     @update_existing_row bit = 0,
  11335.     @do_raiserror bit = 1)
  11336. AS
  11337. BEGIN
  11338.     DECLARE @current_time datetime
  11339.             ,@start_time datetime
  11340.             ,@duration int
  11341.             ,@agent_name nvarchar(100)
  11342.             ,@publisher sysname
  11343.             ,@publisher_db sysname
  11344.             ,@publication sysname
  11345.             ,@lastrow_timestamp timestamp
  11346.             ,@retcode int
  11347.             ,@cmdprocessed_rate float
  11348.             ,@transaction_rate float
  11349.             ,@error_id int
  11350.             ,@idle int
  11351.             ,@succeed int
  11352.             ,@startup int
  11353.             ,@retry int
  11354.             ,@failure int
  11355.             ,@inprogress int
  11356.             ,@database sysname
  11357.             ,@statobjid int
  11358.             ,@agentclassname sysname
  11359.  
  11360.     --
  11361.     -- Status const defined in sqlrepl.h 
  11362.     --
  11363.     select @startup = 1
  11364.             ,@succeed = 2
  11365.             ,@inprogress = 3
  11366.             ,@idle = 4
  11367.             ,@retry = 5
  11368.             ,@failure = 6
  11369.  
  11370.     -- intializations
  11371.     if (@pubid = 0)
  11372.         select @pubid = NULL
  11373.     if (@comments = '')
  11374.         select @comments = NULL
  11375.     if (@transaction_id = '')
  11376.         select @transaction_id = NULL
  11377.     if (@commands_processed is NULL)
  11378.         select @commands_processed = 0
  11379.     if (@subscriber = '')
  11380.         select @subscriber = NULL
  11381.     if (@subscriberdb = '')
  11382.         select @subscriberdb = NULL        
  11383.  
  11384.     SELECT @database = db_name()
  11385.             ,@current_time = GETDATE()
  11386.  
  11387.     -- Get named information
  11388.     select @agent_name = name from MSqreader_agents where id = @agent_id
  11389.     if (@agent_name IS NULL)
  11390.     begin
  11391.         --
  11392.         -- When Queue reader is shutting down due to the last queued subscription
  11393.         -- being dropped it may happen that before the Queue reader logs the shutdown 
  11394.         -- message, the subscription drop process deletes the agent entry from MSqreader_agents
  11395.         --
  11396.         select @agent_name = quotename(@@servername) + '.' + cast(db_id() as nvarchar)
  11397.     end
  11398.     if (@pubid is NULL)
  11399.     begin
  11400.         select @publisher = NULL
  11401.                 ,@publisher_db = NULL
  11402.                 ,@publication = NULL
  11403.     end
  11404.     else
  11405.     begin
  11406.         select @publisher = a.srvname, @publisher_db = b.publisher_db, @publication = b.publication
  11407.         from master..sysservers a, MSpublications b
  11408.         where
  11409.             b.publisher_id= @pubid and
  11410.             b.publisher_id = a.srvid
  11411.     end
  11412.  
  11413.     -- Update Perfmon counter
  11414.     if @perfmon_increment = 1
  11415.     begin
  11416.         if @runstatus = @startup
  11417.             dbcc incrementinstance ("SQL Replication Agents", "Running", "QueueReader", 1)
  11418.         else if (@runstatus = @succeed or @runstatus = @retry or @runstatus = @failure)
  11419.             dbcc incrementinstance ("SQL Replication Agents", "Running", "QueueReader", -1)
  11420.     end
  11421.  
  11422.     -- Get start_time for latest agent run
  11423.     IF (@runstatus = @startup)
  11424.         SELECT @start_time = @current_time
  11425.     ELSE
  11426.     BEGIN
  11427.         SELECT TOP 1 @start_time = start_time, @lastrow_timestamp = timestamp
  11428.         FROM MSqreader_history (rowlock)
  11429.         WHERE 
  11430.         agent_id = @agent_id
  11431.         ORDER BY timestamp DESC
  11432.  
  11433.         if (@start_time is NULL)
  11434.         begin
  11435.             select @runstatus = @startup,
  11436.                 @start_time = @current_time
  11437.         end
  11438.     END
  11439.  
  11440.     -- Calculate agent run duration
  11441.     SELECT @duration = DATEDIFF(second, @start_time, @current_time) 
  11442.  
  11443.     -- Calculate rate of processing
  11444.     IF (@seconds_elapsed IS NOT NULL and @seconds_elapsed > 0)
  11445.     BEGIN
  11446.         SELECT @cmdprocessed_rate = (@commands_processed * 1.0)/@seconds_elapsed
  11447.                 ,@transaction_rate = (@transactions_processed * 1.0)/@seconds_elapsed
  11448.     END
  11449.     ELSE
  11450.     BEGIN
  11451.         SELECT @cmdprocessed_rate = 0.0
  11452.                 ,@transaction_rate = 0.0
  11453.     END
  11454.  
  11455.     -- Set Perfmon counters
  11456.     if @runstatus = @idle or @runstatus = @inprogress
  11457.     begin
  11458.         dbcc addinstance ("SQL Replication QueueReader", @agent_name)
  11459. --        dbcc incrementinstance ("SQL Replication QueueReader", "QueueReader:Delivered Cmds/sec", @agent_name, @cmdprocessed_rate)
  11460. --        dbcc incrementinstance ("SQL Replication QueueReader", "QueueReader:Delivered Trans/sec", @agent_name, @transaction_rate)
  11461.     end
  11462.  
  11463.     --
  11464.     -- Set error id to 0 unless the user want to log errors associate with this 
  11465.     -- history message.
  11466.     --
  11467.     IF (@log_error = 1)
  11468.     begin
  11469.         select @runstatus = @failure
  11470.         EXEC dbo.sp_MSget_new_errorid @error_id OUTPUT
  11471.     end
  11472.     ELSE
  11473.         SELECT @error_id = 0    
  11474.         
  11475.     -- Insert idle record or update if history record is already 'idle'
  11476.     IF (@runstatus = @idle or @update_existing_row = 1)
  11477.     begin
  11478.         -- Attempt to update the last row if it is IDLE
  11479.         UPDATE MSqreader_history 
  11480.         SET     publication_id = @pubid,
  11481.                 runstatus = @runstatus, 
  11482.                 time = @current_time, 
  11483.                 duration = @duration,
  11484.                 comments = @comments,
  11485.                 transaction_id = @transaction_id,
  11486.                 transaction_status = @transaction_status,
  11487.                 transactions_processed = @transactions_processed,
  11488.                 commands_processed = @commands_processed,
  11489.                 delivery_rate = @cmdprocessed_rate,
  11490.                 transaction_rate = @transaction_rate,
  11491.                 subscriber = @subscriber,
  11492.                 subscriberdb = @subscriberdb,
  11493.                 error_id = case @error_id when 0 then error_id else @error_id end
  11494.                 WHERE
  11495.                 agent_id = @agent_id and
  11496.                 timestamp = @lastrow_timestamp and
  11497.                 runstatus = @runstatus
  11498.  
  11499.         -- Insert idle record if there is not one
  11500.         if (@@ROWCOUNT = 0)
  11501.         begin
  11502.             INSERT INTO MSqreader_history(agent_id, publication_id, runstatus, start_time, time, 
  11503.                     duration, comments, transaction_id, transaction_status, 
  11504.                     transactions_processed, commands_processed, delivery_rate, 
  11505.                     transaction_rate, subscriber, subscriberdb, error_id)
  11506.             VALUES(@agent_id, @pubid, @runstatus, @start_time, @current_time, 
  11507.                     @duration, @comments, @transaction_id, @transaction_status,
  11508.                     @transactions_processed, @commands_processed, @cmdprocessed_rate, 
  11509.                     @transaction_rate, @subscriber, @subscriberdb, @error_id)
  11510.         end
  11511.     end
  11512.     else
  11513.     begin
  11514.         INSERT INTO MSqreader_history(agent_id, publication_id, runstatus, start_time, time, 
  11515.                 duration, comments, transaction_id, transaction_status, 
  11516.                 transactions_processed, commands_processed, delivery_rate,
  11517.                 transaction_rate, subscriber, subscriberdb, error_id)
  11518.         VALUES(@agent_id, @pubid, @runstatus, @start_time, @current_time, 
  11519.                 @duration, @comments, @transaction_id, @transaction_status, 
  11520.                 @transactions_processed, @commands_processed, @cmdprocessed_rate, 
  11521.                 @transaction_rate, @subscriber, @subscriberdb, @error_id)
  11522.     end
  11523.  
  11524.     --
  11525.     -- Update global replication agent status table
  11526.     --        
  11527.     exec @retcode = dbo.sp_MSupdate_replication_status 
  11528.         @@servername, 
  11529.         @database,
  11530.         @publication = 'ALL',
  11531.         @agent_type = 9,
  11532.         @agent_name = @agent_name,
  11533.         @status = @runstatus
  11534.     if (@retcode != 0 and @@error != 0)
  11535.         return 1
  11536.  
  11537.     -- Raise the appropriate error
  11538.     if (@do_raiserror = 1)
  11539.     begin
  11540.         select @agentclassname = formatmessage(14581)
  11541.         exec dbo.sp_MSrepl_raiserror @agentclassname, @agent_name, @runstatus, @comments
  11542.     end
  11543.  
  11544.     IF (@@ERROR != 0)
  11545.         RETURN (1)
  11546. END
  11547. GO   
  11548.  
  11549. raiserror(15339,-1,-1,'sp_MSadd_snapshot_history')
  11550. go
  11551. CREATE PROCEDURE sp_MSadd_snapshot_history (
  11552.     @agent_id int,
  11553.     @runstatus int, 
  11554.     @comments nvarchar(255),
  11555.     @delivered_transactions int = 0,    
  11556.     @delivered_commands int = 0,        
  11557.     @log_error bit = 0,
  11558.     @perfmon_increment bit = 1,
  11559.     @update_existing_row bit = 0,
  11560.     @do_raiserror bit = 1,
  11561.     @start_time_string nvarchar(25) = null
  11562. )
  11563. AS
  11564. BEGIN
  11565.  
  11566.     DECLARE @current_time datetime
  11567.             ,@start_time datetime
  11568.             ,@duration int
  11569.             ,@delivery_rate float
  11570.             ,@error_id int
  11571.             ,@retcode int
  11572.             ,@idle int
  11573.             ,@succeed int
  11574.             ,@startup int
  11575.             ,@retry int
  11576.             ,@failure int
  11577.             ,@inprogress int
  11578.             ,@lastrow_timestamp timestamp
  11579.             ,@publisher sysname
  11580.             ,@publisher_db sysname
  11581.             ,@publication sysname
  11582.             ,@agent_name nvarchar(100)
  11583.             ,@perfmon_delivery_rate int
  11584.             ,@agentclassname sysname
  11585.  
  11586.     /* 
  11587.     ** Status const defined in sqlrepl.h 
  11588.     */
  11589.     select @startup = 1
  11590.             ,@succeed = 2
  11591.             ,@inprogress = 3
  11592.             ,@idle = 4
  11593.             ,@retry = 5
  11594.             ,@failure = 6
  11595.             ,@current_time = GETDATE()
  11596.  
  11597.     -- Get named information 
  11598.     select @publisher = srvname, @publisher_db = publisher_db, @publication = publication,
  11599.         @agent_name = name from master..sysservers, MSsnapshot_agents where
  11600.         id = @agent_id and
  11601.         publisher_id = srvid
  11602.  
  11603.     -- Update Perfmon counter
  11604.     if @perfmon_increment = 1
  11605.     begin
  11606.         if @runstatus = @startup
  11607.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Snapshot", 1)
  11608.         else if (@runstatus = @succeed or @runstatus = @retry or @runstatus = @failure)
  11609.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Snapshot", -1)
  11610.     end
  11611.  
  11612.     /* Get start_time for latest agent run */
  11613.     IF @runstatus <> 1  -- Start status
  11614.     BEGIN
  11615.         
  11616.         IF @start_time_string IS NULL OR @start_time_string = N''
  11617.         BEGIN
  11618.             SELECT TOP 1 @start_time = start_time, @lastrow_timestamp = timestamp
  11619.                 FROM MSsnapshot_history (rowlock)
  11620.                 WHERE 
  11621.                 agent_id = @agent_id
  11622.                 ORDER BY timestamp DESC
  11623.         END
  11624.         ELSE
  11625.         BEGIN
  11626.             SELECT @start_time = @start_time_string
  11627.         END
  11628.     END
  11629.     ELSE
  11630.     BEGIN
  11631.         WAITFOR DELAY '000:00:01'
  11632.         SELECT @current_time = DATEADD(ms, CONVERT(INT, 1000.0 * (RAND(@@spid) + RAND() + RAND())/3.0), @current_time)
  11633.         SELECT @start_time = @current_time
  11634.     END
  11635.     /* Calculate agent run duration */
  11636.     SELECT @duration = DATEDIFF(second, @start_time, @current_time) 
  11637.  
  11638.     /* Calculate delivery_rate */
  11639.     IF @duration <> 0 
  11640.        SELECT @delivery_rate = (@delivered_commands * 1.0)/@duration 
  11641.     ELSE
  11642.        SELECT @delivery_rate = 0
  11643.  
  11644.     -- Set Perfmon counters
  11645.     if @runstatus = @idle or @runstatus = @inprogress
  11646.     begin
  11647.         dbcc addinstance ("SQL Replication Snapshot", @agent_name)
  11648.         dbcc incrementinstance ("SQL Replication Snapshot", "Snapshot:Delivered Cmds/sec", @agent_name, @delivered_commands)
  11649.         dbcc incrementinstance ("SQL Replication Snapshot", "Snapshot:Delivered Trans/sec", @agent_name, @delivered_transactions)
  11650.     end
  11651.  
  11652.     /* 
  11653.     ** Set error id to 0 unless the user want to log errors associate with this 
  11654.     ** history message.
  11655.     */
  11656.     SELECT @error_id = 0
  11657.     IF @log_error = 1
  11658.         -- Ignore errors here. @error_id will be set to 0 in case of errors  
  11659.         EXEC dbo.sp_MSget_new_errorid @error_id OUTPUT
  11660.  
  11661.     -- Insert idle record or update if history record is already 'idle'
  11662.     IF @runstatus = @idle or @update_existing_row = 1
  11663.     begin
  11664.         -- Attempt to update the last row if it is IDLE
  11665.         UPDATE MSsnapshot_history SET runstatus = @runstatus, time = @current_time, duration = @duration,
  11666.             comments = @comments,
  11667.             delivered_transactions = @delivered_transactions,
  11668.             delivered_commands = @delivered_commands,
  11669.             delivery_rate = @delivery_rate,
  11670.             error_id = case @error_id when 0 then error_id else @error_id end    
  11671.             WHERE
  11672.             agent_id = @agent_id and
  11673.             timestamp = @lastrow_timestamp and
  11674.             runstatus = @runstatus
  11675.  
  11676.         -- Insert idle record if there is not one
  11677.         if @@ROWCOUNT = 0
  11678.         begin
  11679.             INSERT INTO MSsnapshot_history VALUES (@agent_id, @runstatus, @start_time, 
  11680.             @current_time, @duration, @comments, @delivered_transactions, @delivered_commands, 
  11681.             @delivery_rate, @error_id, NULL)
  11682.         end
  11683.     end
  11684.     else
  11685.     begin
  11686.         INSERT INTO MSsnapshot_history VALUES (@agent_id, @runstatus, @start_time, 
  11687.             @current_time, @duration, @comments, @delivered_transactions, @delivered_commands, 
  11688.             @delivery_rate, @error_id, NULL)
  11689.     end
  11690.  
  11691.     -- Update global replication agent status table
  11692.     exec dbo.sp_MSupdate_replication_status 
  11693.         @publisher, 
  11694.         @publisher_db,
  11695.         @publication,
  11696.         @agent_type = 1,
  11697.         @agent_name = @agent_name,
  11698.         @status = @runstatus
  11699.  
  11700.     -- Raise the appropriate error
  11701.     if @do_raiserror = 1
  11702.     begin
  11703.         select @agentclassname = formatmessage(14551)
  11704.         exec dbo.sp_MSrepl_raiserror @agentclassname, @agent_name, @runstatus, @comments
  11705.     end
  11706.  
  11707.     IF @@ERROR <> 0
  11708.        RETURN (1)
  11709.  
  11710.     if @runstatus = 1
  11711.     begin
  11712.         select 'start_time' = convert(nvarchar(12), @start_time, 112) +
  11713.             substring(convert(nvarchar(24), @start_time, 121), 11, 13)
  11714.     end
  11715. END
  11716. GO   
  11717.  
  11718.  
  11719. raiserror(15339,-1,-1,'sp_MSadd_logreader_history')
  11720. go
  11721. CREATE PROCEDURE sp_MSadd_logreader_history (
  11722.     @agent_id int,
  11723.     @runstatus int,
  11724.     @comments nvarchar(255),
  11725.     @xact_seqno varbinary(16) = NULL,
  11726.     @delivery_time int = 0,                 -- Current delivery time (milliseconds)
  11727.     @delivered_transactions int = 0,        -- Running total of session
  11728.     @delivered_commands int = 0,            -- Running total of session
  11729.     @delivery_latency int = 0,              -- Current latency 
  11730.     @log_error bit = 0,
  11731.     @perfmon_increment bit = 1,
  11732.     @update_existing_row bit = 0,
  11733.     @do_raiserror bit = 1
  11734. )
  11735. AS
  11736. BEGIN
  11737.  
  11738.     DECLARE @current_time datetime
  11739.             ,@start_time datetime
  11740.             ,@duration int
  11741.             ,@average_commands int
  11742.             ,@delivery_rate float
  11743.             ,@error_id int
  11744.             ,@retcode int
  11745.             ,@idle int
  11746.             ,@succeed int
  11747.             ,@startup int
  11748.             ,@retry int
  11749.             ,@inprogress int
  11750.             ,@failure int
  11751.             ,@lastrow_timestamp timestamp
  11752.             ,@publisher sysname
  11753.             ,@publisher_db sysname
  11754.             ,@publication sysname
  11755.             ,@agent_name nvarchar(100)
  11756.             ,@last_delivered_commands int
  11757.             ,@last_delivered_transactions int
  11758.             ,@latest_delivered_commands int
  11759.             ,@latest_delivered_transactions int
  11760.             ,@latest_delivery_rate int
  11761.             ,@last_delivery_rate int             -- int for perfmon
  11762.             ,@last_delivery_latency int
  11763.             ,@last_delivery_time int
  11764.             ,@avg_delivery_rate float
  11765.             ,@avg_delivery_latency int
  11766.             ,@total_delivery_time int
  11767.             ,@agentclassname sysname
  11768.  
  11769.     /* 
  11770.     ** Status const defined in sqlrepl.h 
  11771.     */
  11772.     select @startup = 1
  11773.             ,@succeed = 2
  11774.             ,@inprogress = 3
  11775.             ,@idle = 4
  11776.             ,@retry = 5
  11777.             ,@failure = 6
  11778.             ,@current_time = GETDATE()
  11779.  
  11780.     -- Update Perfmon counter
  11781.     if @perfmon_increment = 1
  11782.     begin
  11783.         if @runstatus = @startup
  11784.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Logreader", 1)
  11785.         else if (@runstatus = @succeed or @runstatus = @retry or @runstatus = @failure)
  11786.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Logreader", -1)
  11787.     end
  11788.  
  11789.     /* Get start_time for latest agent run */
  11790.     IF @runstatus <> 1  -- Startup status
  11791.     BEGIN
  11792.         SELECT TOP 1 @start_time = start_time, 
  11793.             @lastrow_timestamp = timestamp, 
  11794.             @last_delivered_commands = isnull(delivered_commands, 0),
  11795.             @last_delivered_transactions = isnull(delivered_transactions, 0),
  11796.             @last_delivery_latency = isnull(delivery_latency, 0),
  11797.             @last_delivery_time = isnull(delivery_time, 0),
  11798.             @last_delivery_rate = isnull(delivery_rate, 0)
  11799.         FROM MSlogreader_history (rowlock)
  11800.             WHERE agent_id = @agent_id
  11801.                 ORDER BY timestamp DESC
  11802.     END
  11803.     ELSE
  11804.     BEGIN
  11805.         SELECT @start_time = @current_time
  11806.         SET @last_delivered_commands = 0
  11807.         SET @last_delivered_transactions = 0
  11808.         SET @last_delivery_latency = 0
  11809.         SET @last_delivery_time = 0
  11810.         SET @last_delivery_rate = 0
  11811.         SET @last_delivery_latency = 0
  11812.     END
  11813.  
  11814.     /* Use the current time if no corresponding start_up message logged */
  11815.     IF @start_time is NULL
  11816.        SELECT @start_time = @current_time
  11817.  
  11818.     -- Calculate number of transactions in this history
  11819.     set @latest_delivered_commands = @delivered_commands - @last_delivered_commands
  11820.  
  11821.     -- Calculate number of commands in this history
  11822.     set @latest_delivered_transactions = @delivered_transactions - @last_delivered_transactions
  11823.  
  11824.     /* Calculate agent run duration */
  11825.     SELECT @duration = DATEDIFF(second, @start_time, @current_time) 
  11826.  
  11827.     -- Calculate total delivery_time 
  11828.     if @latest_delivered_commands <> 0      -- Work around for Logreader passing in @delivery_time on shutdown.
  11829.         SELECT @total_delivery_time = @delivery_time + @last_delivery_time
  11830.     else
  11831.         SELECT @total_delivery_time = @last_delivery_time
  11832.  
  11833.     -- Calculate average delivery_rate of the session
  11834.     IF @latest_delivered_commands <> 0 and @total_delivery_time <> 0
  11835.     BEGIN
  11836.         SELECT @avg_delivery_rate = (@delivered_commands * 1.0)/(@total_delivery_time/1000.0)
  11837.  
  11838.         -- Current history delivery rate
  11839.         if @delivery_time <> 0
  11840.             SELECT @latest_delivery_rate = (@latest_delivered_commands * 1.0)/(@delivery_time/1000.0)
  11841.         else 
  11842.             SELECT @latest_delivery_rate = 0
  11843.     END
  11844.     ELSE
  11845.     BEGIN
  11846.         SELECT @avg_delivery_rate = @last_delivery_rate
  11847.         SELECT @latest_delivery_rate = 0
  11848.     END
  11849.  
  11850.     -- Calculate the average delivery_latency of the session
  11851.     if @latest_delivered_commands <> 0      -- Work around for Logreader passing in @delivery_latency on shutdown.
  11852.     BEGIN
  11853.         IF @delivery_latency <> 0
  11854.             IF @last_delivery_latency <> 0
  11855.                 SELECT @avg_delivery_latency = (@delivery_latency + @last_delivery_latency)/2
  11856.             ElSE
  11857.                 SELECT @avg_delivery_latency = @delivery_latency
  11858.         ELSE
  11859.             SELECT @avg_delivery_latency = 0
  11860.     END
  11861.     ELSE
  11862.     BEGIN
  11863.         SELECT @avg_delivery_latency = @last_delivery_latency
  11864.  
  11865.         -- Ignore latency value if no commands
  11866.         SELECT @delivery_latency = 0    
  11867.     END
  11868.  
  11869.     /*
  11870.     ** Calculate average number of commands per transaction
  11871.     */
  11872.     IF @delivered_commands <> 0
  11873.        SELECT @average_commands = @delivered_commands/@delivered_transactions
  11874.     ELSE
  11875.  
  11876.        SELECT @average_commands = 0
  11877.  
  11878.     -- Set Perfmon counters
  11879.     select @agent_name = name from MSlogreader_agents where id = @agent_id
  11880.     if @runstatus = @idle or @runstatus = @inprogress
  11881.     begin
  11882.         dbcc addinstance ("SQL Replication Logreader", @agent_name)
  11883.         dbcc incrementinstance ("SQL Replication Logreader", "Logreader:Delivered Trans/sec", @agent_name, @latest_delivered_transactions)
  11884.         dbcc incrementinstance ("SQL Replication Logreader", "Logreader:Delivered Cmds/sec", @agent_name, @latest_delivered_commands)
  11885.         dbcc setinstance ("SQL Replication Logreader", "Logreader:Delivery Latency", @agent_name, @delivery_latency)
  11886.     end
  11887.     else
  11888.     begin
  11889.         dbcc addinstance ("SQL Replication Logreader", @agent_name)
  11890.         dbcc setinstance ("SQL Replication Logreader", "Logreader:Delivery Latency", @agent_name, 0)
  11891.     end
  11892.  
  11893.     /* 
  11894.     ** Set error id to 0 unless the user want to log errors associate with this 
  11895.     ** history message.
  11896.     */
  11897.     SELECT @error_id = 0
  11898.     IF @log_error = 1
  11899.         -- Ignore errors here. @error_id will be set to 0 in case of errors  
  11900.         EXEC dbo.sp_MSget_new_errorid @error_id OUTPUT
  11901.  
  11902.     -- Insert idle record or update if history record is already 'idle'
  11903.     IF @runstatus = @idle or @update_existing_row = 1
  11904.     begin
  11905.         -- Attempt to update the last row if it is IDLE
  11906.         if (@runstatus = @idle)
  11907.         begin
  11908.             UPDATE MSlogreader_history SET runstatus = @runstatus, time = @current_time,
  11909.             duration = @duration,comments = @comments,
  11910.             error_id = case @error_id when 0 then error_id else @error_id end
  11911.             WHERE
  11912.             agent_id = @agent_id and
  11913.             timestamp = @lastrow_timestamp and
  11914.             ( runstatus = @runstatus or 
  11915.             (@update_existing_row = 1 and runstatus in (@idle, @inprogress) and @runstatus in (@idle, @inprogress)) )
  11916.         end
  11917.         else
  11918.         begin
  11919.             UPDATE MSlogreader_history SET runstatus = @runstatus, start_time = @start_time, 
  11920.             time = @current_time,
  11921.             duration = @duration, comments = @comments,
  11922.             xact_seqno = @xact_seqno,
  11923.             delivery_time = @total_delivery_time,
  11924.             delivered_transactions = @delivered_transactions,
  11925.             delivered_commands = @delivered_commands,
  11926.             average_commands = @average_commands,
  11927.             delivery_rate = @avg_delivery_rate,
  11928.             delivery_latency = @avg_delivery_latency,
  11929.             error_id = case @error_id when 0 then error_id else @error_id end
  11930.             WHERE
  11931.             agent_id = @agent_id and
  11932.             timestamp = @lastrow_timestamp and
  11933.             ( runstatus = @runstatus or 
  11934.             (@update_existing_row = 1 and runstatus in (@idle, @inprogress) and @runstatus in (@idle, @inprogress)) )
  11935.         end
  11936.  
  11937.         -- Insert idle record if there is not one
  11938.         if @@ROWCOUNT = 0
  11939.         begin
  11940.             -- Use last values because nothing was done
  11941.             INSERT INTO MSlogreader_history VALUES (@agent_id, @runstatus, @start_time, @current_time, 
  11942.                 @duration, @comments,  
  11943.                 @xact_seqno, @last_delivery_time, @delivered_transactions, @delivered_commands,
  11944.                 @average_commands, @avg_delivery_rate, @last_delivery_latency, @error_id, NULL)
  11945.         end
  11946.     end
  11947.     else
  11948.     begin
  11949.         INSERT INTO MSlogreader_history VALUES (@agent_id, @runstatus, @start_time, @current_time, 
  11950.             @duration, @comments, 
  11951.             @xact_seqno, @total_delivery_time, @delivered_transactions, @delivered_commands,
  11952.             @average_commands, @avg_delivery_rate, @avg_delivery_latency, @error_id, NULL)
  11953.     end
  11954.  
  11955.     -- Get named information 
  11956.     select @publisher = srvname, @publisher_db = publisher_db, @publication = publication,
  11957.         @agent_name = name from master..sysservers, MSlogreader_agents where
  11958.         id = @agent_id and
  11959.         publisher_id = srvid
  11960.  
  11961.     -- Update global replication agent status table
  11962.     exec dbo.sp_MSupdate_replication_status 
  11963.         @publisher, 
  11964.         @publisher_db,
  11965.         @publication = 'ALL',
  11966.         @agent_type = 2,
  11967.         @agent_name = @agent_name,
  11968.         @status = @runstatus
  11969.  
  11970.     -- Raise the appropriate error
  11971.     if @do_raiserror = 1
  11972.     begin
  11973.         select @agentclassname = formatmessage(14552)
  11974.         exec dbo.sp_MSrepl_raiserror @agentclassname, @agent_name, @runstatus, @comments
  11975.     end
  11976.  
  11977.     IF @@ERROR <> 0
  11978.     BEGIN
  11979.        RETURN (1)
  11980.     END
  11981. END
  11982. GO      
  11983.  
  11984. raiserror(15339,-1,-1,'sp_MSadd_distribution_history')
  11985. go
  11986. CREATE PROCEDURE sp_MSadd_distribution_history (
  11987.     @agent_id int,
  11988.     @runstatus int, 
  11989.     @comments nvarchar(255),
  11990.     @xact_seqno binary(16) = 0x00,      -- We use binary(16)to pad it out for the below compare
  11991.     @delivered_transactions int = 0,        -- Running total for the session
  11992.     @delivered_commands int = 0,            -- Running total for the session
  11993.     @delivery_rate float = 0,               -- Last rate (cmds/sec)
  11994.     @log_error bit = 0,
  11995.     @perfmon_increment bit = 1,
  11996.     @xactseq varbinary(16) = NULL,      
  11997.     @command_id int = NULL,
  11998.     @update_existing_row bit = 0,
  11999.     @updateable_row bit = 1,        -- used to override history verbose level to decide
  12000.                                     -- whether the row being added can be updated by another.    
  12001.     @do_raiserror bit = 1
  12002. )
  12003. AS
  12004. BEGIN
  12005.  
  12006.     set nocount on
  12007.  
  12008.     DECLARE @current_time datetime
  12009.             ,@start_time datetime
  12010.             ,@entry_time datetime
  12011.             ,@duration int                   -- milliseconds
  12012.             ,@delivery_latency int
  12013.             ,@average_commands int
  12014.             ,@total_cmds int
  12015.             ,@publisher_id smallint
  12016.             ,@publisher_db sysname
  12017.             ,@publication sysname
  12018.             ,@publisher sysname
  12019.             ,@subscriber_id smallint
  12020.             ,@subscriber sysname
  12021.             ,@subscriber_db sysname
  12022.             ,@article sysname
  12023.             ,@article_id int
  12024.             ,@publication_id int
  12025.             ,@publisher_database_id int
  12026.  
  12027.             ,@agent_name nvarchar(100)
  12028.             ,@error_id int 
  12029.             ,@startup int
  12030.             ,@succeed int
  12031.             ,@inprogress int
  12032.             ,@retry int
  12033.             ,@failure int
  12034.             ,@validation_failure int
  12035.             ,@validation_success int, @error_skipped int
  12036.             ,@requested_shutdown int
  12037.             ,@raiserror_status int
  12038.             ,@idle int
  12039.             ,@lastrow_timestamp timestamp
  12040.             ,@lastrow_xact_seqno binary(16)
  12041.             ,@new_delivered_commands int
  12042.             ,@new_delivered_transactions int
  12043.             ,@retcode int
  12044.             ,@last_delivery_rate float
  12045.             ,@last_delivery_latency int
  12046.             ,@avg_delivery_rate float
  12047.             ,@avg_delivery_latency int
  12048.             ,@perfmon_delivery_rate int
  12049.             ,@existing_row_updateble bit
  12050.             ,@this_row_updateable bit
  12051.             ,@agentclassname sysname
  12052.  
  12053.     /* 
  12054.     ** Status const defined in sqlrepl.h 
  12055.     */
  12056.     select @startup = 1
  12057.             ,@succeed = 2
  12058.             ,@inprogress = 3
  12059.             ,@idle = 4
  12060.             ,@retry = 5
  12061.             ,@failure = 6
  12062.             ,@validation_failure = 7
  12063.             ,@validation_success = 8
  12064.             ,@requested_shutdown = 9
  12065.             ,@error_skipped = 10
  12066.  
  12067.     -- To prevent cleanup up being messed up by invalid history message, only log
  12068.     -- valid history message. 
  12069.     if @runstatus > 10 or @runstatus < 1
  12070.     begin
  12071.         --Invalid history message logged
  12072.         RAISERROR (21079, 16, -1, @runstatus)
  12073.         return (1)
  12074.     end
  12075.  
  12076.     select @existing_row_updateble = 1
  12077.     select @this_row_updateable = 1
  12078.  
  12079.     select @raiserror_status = @runstatus
  12080.     if (@runstatus = @validation_failure or @runstatus = @validation_success 
  12081.         or @runstatus = @requested_shutdown or @runstatus = @error_skipped)
  12082.     begin
  12083.         select @runstatus = @inprogress
  12084.         select @this_row_updateable = 0
  12085.     end
  12086.  
  12087.     if (@updateable_row = 0)
  12088.     begin
  12089.         select @this_row_updateable = 0
  12090.     end
  12091.     
  12092.     -- Security Check
  12093.     exec @retcode = dbo.sp_MScheck_pull_access
  12094.         @agent_id = @agent_id,
  12095.         @agent_type = 0 -- distribution agent
  12096.     if @@error <> 0 or @retcode <> 0
  12097.         return (1)
  12098.  
  12099.     SELECT @current_time = GETDATE()
  12100.  
  12101.     -- Update Perfmon counter
  12102.     if @perfmon_increment = 1
  12103.     begin
  12104.         if @runstatus = @startup
  12105.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Distribution", 1)
  12106.         else if (@runstatus = @succeed or @runstatus = @retry or @runstatus = @failure)
  12107.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Distribution", -1)
  12108.     end
  12109.  
  12110.     -- Get agent name, publisher id and publisher_db
  12111.     select @agent_name = name, 
  12112.         @publisher_database_id = publisher_database_id,
  12113.         @publisher_id = publisher_id, @publisher_db = publisher_db,
  12114.         @publication =  publication, @subscriber_id = subscriber_id, @subscriber_db = subscriber_db
  12115.         from MSdistribution_agents
  12116.         where id = @agent_id
  12117.     select @publisher = srvname from master..sysservers where srvid = @publisher_id
  12118.     select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  12119.  
  12120.     /* Get start_time and xact_seqno for latest agent run */
  12121.     IF @runstatus <> 1   
  12122.     BEGIN
  12123.           
  12124.         SELECT TOP 1 
  12125.             @lastrow_xact_seqno = xact_seqno,
  12126.             @start_time = start_time, 
  12127.             @total_cmds = total_delivered_commands,
  12128.             @lastrow_timestamp = timestamp, 
  12129.             @new_delivered_transactions = @delivered_transactions - delivered_transactions,
  12130.             @new_delivered_commands = @delivered_commands - delivered_commands,
  12131.             @last_delivery_rate = delivery_rate,
  12132.             @last_delivery_latency = delivery_latency,
  12133.             @existing_row_updateble = updateable_row
  12134.         FROM MSdistribution_history (rowlock)
  12135.             WHERE agent_id = @agent_id 
  12136.             ORDER BY timestamp  DESC
  12137.     END
  12138.     ELSE
  12139.     BEGIN
  12140.         -- At least get running total of commands over all sessions.
  12141.         SELECT TOP 1 
  12142.             @lastrow_xact_seqno = xact_seqno,
  12143.             @total_cmds = total_delivered_commands
  12144.             FROM MSdistribution_history  (rowlock)
  12145.             WHERE agent_id = @agent_id
  12146.             ORDER BY timestamp  DESC
  12147.         SELECT @start_time = @current_time
  12148.         SELECT @new_delivered_commands = @delivered_commands
  12149.         SELECT @new_delivered_transactions = @delivered_transactions
  12150.         SELECT @last_delivery_rate = 0
  12151.         SELECT @last_delivery_latency = 0
  12152.     END
  12153.  
  12154.     IF @total_cmds IS NULL
  12155.         SELECT @total_cmds = 0
  12156.  
  12157.     /* Use the current time if no corresponding start_up message logged */
  12158.     IF @start_time is NULL
  12159.        SELECT @start_time = @current_time
  12160.  
  12161.     /* Calculate agent run duration */
  12162.     SELECT @duration = DATEDIFF(second, @start_time, @current_time) 
  12163.     
  12164.     IF @delivered_commands <> 0
  12165.        SELECT @average_commands = @delivered_commands/@delivered_transactions
  12166.     ELSE
  12167.        SELECT @average_commands = 0
  12168.  
  12169.     -- Get the entry time of the last distributed transaction
  12170.     if @xact_seqno <> 0x00 and @new_delivered_commands <> 0
  12171.         -- SELECT @entry_time = entry_time FROM MSrepl_transactions (READPAST)
  12172.         SELECT @entry_time = entry_time FROM MSrepl_transactions 
  12173.            WHERE xact_seqno = @xact_seqno and
  12174.                 publisher_database_id = @publisher_database_id
  12175.  
  12176.     -- Calculate the latency of the last distributed transaction
  12177.     IF @entry_time IS NOT NULL
  12178.     begin
  12179.        -- Calculte diff in minutes.
  12180.        declare @diff_min int
  12181.        select @diff_min = DATEDIFF(minute, @entry_time, @current_time)
  12182.        if @diff_min > 16666
  12183.             select @delivery_latency = 999999999
  12184.        else 
  12185.             select @delivery_latency = DATEDIFF(millisecond, @entry_time, @current_time)
  12186.     end
  12187.     ELSE
  12188.        SELECT @delivery_latency = 0
  12189.  
  12190.     -- Calculate the average delivery latency of the session
  12191.     IF @last_delivery_latency = 0
  12192.         SET @avg_delivery_latency = @delivery_latency
  12193.     ELSE IF @delivery_latency = 0
  12194.         SET @avg_delivery_latency = @last_delivery_latency
  12195.     ELSE
  12196.         SET @avg_delivery_latency = (@delivery_latency + @last_delivery_latency)/2
  12197.  
  12198.     -- Calculate average delivery rate of the session
  12199.  
  12200.     IF @last_delivery_rate = 0
  12201.         SET @avg_delivery_rate = @delivery_rate
  12202.     ELSE IF @delivery_rate = 0 or @new_delivered_commands = 0
  12203.         SET @avg_delivery_rate = @last_delivery_rate
  12204.     ELSE
  12205.         SET @avg_delivery_rate = (@delivery_rate + @last_delivery_rate)/2.0     
  12206.  
  12207.     /* Calculate grand total of delivered trans across sessions */
  12208.     SELECT @total_cmds = @total_cmds + @new_delivered_commands
  12209.  
  12210.     -- Set Perfmon counters
  12211.     if @runstatus = @idle or @runstatus = @inprogress
  12212.     begin
  12213.         dbcc addinstance ("SQL Replication Distribution", @agent_name)
  12214.         dbcc incrementinstance ("SQL Replication Distribution", "Dist:Delivered Trans/sec", @agent_name, @new_delivered_transactions)
  12215.         dbcc incrementinstance ("SQL Replication Distribution", "Dist:Delivered Cmds/sec", @agent_name, @new_delivered_commands)
  12216.         dbcc setinstance ("SQL Replication Distribution", "Dist:Delivery Latency", @agent_name, @delivery_latency)
  12217.     end
  12218.     else
  12219.     begin /* Reset latency counter */
  12220.         dbcc addinstance ("SQL Replication Distribution", @agent_name)
  12221.         dbcc setinstance ("SQL Replication Distribution", "Dist:Delivery Latency", @agent_name, 0)
  12222.     end
  12223.  
  12224.     /* 
  12225.     ** Set error id to 0 unless the user want to log errors associate with this 
  12226.     ** history message.
  12227.     */
  12228.     SELECT @error_id = 0
  12229.     IF @log_error = 1
  12230.         -- Ignore errors here. @error_id will be set to 0 in case of errors  
  12231.         EXEC dbo.sp_MSget_new_errorid @error_id OUTPUT, @xactseq, @command_id
  12232.     
  12233.     -- @xact_seqno may be uninitialized for the first several messages after
  12234.     -- the start-up of the distribtion agent. Get the correct value in that case. 
  12235.     -- We must do this because distribution cleanup will use the lastest xact_seqno
  12236.     -- as cleanup boundary.
  12237.     -- Note: @last_xact_seqno might be NULL
  12238.     -- Only do this if @xact_seqno is 0, since a smaller xact_seqno might be logged due
  12239.     -- to reinited sub for immediate_sync pub.
  12240.     -- This will prevent history being messed up by one gabage history entry.
  12241.     if @xact_seqno = 0x00 and @lastrow_xact_seqno is not null
  12242.         select @xact_seqno = @lastrow_xact_seqno 
  12243.  
  12244.     -- Insert idle record or update if history record is already 'idle'
  12245.     IF (@existing_row_updateble = 1) and (@runstatus = @idle or @update_existing_row = 1)
  12246.     begin
  12247.  
  12248.         -- Attempt to update the last row if it is IDLE
  12249.         if (@runstatus = @idle)
  12250.         begin
  12251.             UPDATE MSdistribution_history SET runstatus = @runstatus, time = @current_time,
  12252.             duration = @duration, comments = @comments,
  12253.             xact_seqno = @xact_seqno, updateable_row = @this_row_updateable,
  12254.             error_id = case @error_id when 0 then error_id else @error_id end
  12255.             WHERE
  12256.             agent_id = @agent_id and
  12257.             timestamp = @lastrow_timestamp and
  12258.             ( runstatus = @runstatus or 
  12259.             (@update_existing_row = 1 and runstatus in (@idle, @inprogress) and @runstatus in (@idle, @inprogress)) )
  12260.         end
  12261.         else
  12262.         begin
  12263.             -- Attempt to update the last row if it is IDLE
  12264.             UPDATE MSdistribution_history SET runstatus = @runstatus, start_time = @start_time,
  12265.                 time = @current_time,
  12266.                 duration = @duration,
  12267.                 xact_seqno = @xact_seqno,
  12268.                 comments = @comments,
  12269.                 delivered_transactions = @delivered_transactions,
  12270.                 delivered_commands = @delivered_commands,
  12271.                 average_commands = @average_commands,
  12272.                 delivery_rate = @avg_delivery_rate,
  12273.                 delivery_latency = @avg_delivery_latency,
  12274.                 total_delivered_commands = @total_cmds,
  12275.                 current_delivery_rate = @delivery_rate,
  12276.                 current_delivery_latency = @delivery_latency,
  12277.                 updateable_row = @this_row_updateable,
  12278.                 error_id = case @error_id when 0 then error_id else @error_id end
  12279.                 WHERE
  12280.                 agent_id = @agent_id and
  12281.                 timestamp = @lastrow_timestamp and
  12282.                 ( runstatus = @runstatus or 
  12283.                 (@update_existing_row = 1 and runstatus in (@idle, @inprogress) and @runstatus in (@idle, @inprogress)) )
  12284.         end
  12285.     
  12286.         -- Insert idle record if there is not one
  12287.         if @@ROWCOUNT = 0
  12288.         begin
  12289.             INSERT INTO MSdistribution_history (agent_id, runstatus, start_time, time, duration, comments, xact_seqno,
  12290.                 delivered_transactions, delivered_commands, average_commands, delivery_rate, delivery_latency,
  12291.                 total_delivered_commands, error_id, timestamp, current_delivery_rate, current_delivery_latency, updateable_row)
  12292.             VALUES (@agent_id, @runstatus, @start_time, @current_time, 
  12293.                 @duration, @comments, @xact_seqno, @delivered_transactions, 
  12294.                 @delivered_commands, @average_commands, @avg_delivery_rate,
  12295.                 @avg_delivery_latency, @total_cmds, @error_id, NULL, @delivery_rate, @delivery_latency, @this_row_updateable)
  12296.         end
  12297.     end
  12298.     else
  12299.     begin
  12300.         INSERT INTO MSdistribution_history (agent_id, runstatus, start_time, time, duration, comments, xact_seqno,
  12301.                 delivered_transactions, delivered_commands, average_commands, delivery_rate, delivery_latency,
  12302.                 total_delivered_commands, error_id, timestamp, current_delivery_rate, current_delivery_latency, updateable_row)
  12303.         VALUES (@agent_id, @runstatus, @start_time, @current_time, 
  12304.             @duration, @comments, @xact_seqno, @delivered_transactions, 
  12305.             @delivered_commands, @average_commands, @avg_delivery_rate,
  12306.             @avg_delivery_latency, @total_cmds, @error_id, NULL, @delivery_rate, @delivery_latency, @this_row_updateable)
  12307.     end
  12308.  
  12309.     -- Refresh repl monitor
  12310.     declare @agent_type int
  12311.     set @agent_type = dbo.fn_MSmask_agent_type (@agent_id, 3)
  12312.  
  12313.     -- Update global replication agent status table
  12314.     exec dbo.sp_MSupdate_replication_status 
  12315.         @publisher, 
  12316.         @publisher_db,
  12317.         @publication,
  12318.         @agent_type = @agent_type,
  12319.         @agent_name = @agent_name,
  12320.         @status = @runstatus
  12321.  
  12322.     if (@raiserror_status = @validation_failure or @raiserror_status = @validation_success or
  12323.         @raiserror_status = @error_skipped)
  12324.     begin
  12325.         -- Get the "real" publication name (as opposed to 'ALL') and article name
  12326.         select @article_id = article_id from MSrepl_commands
  12327.         where publisher_database_id = @publisher_database_id
  12328.         and xact_seqno = @xactseq
  12329.         and command_id = @command_id
  12330.     
  12331.         select @publication = mp.publication, @publication_id = mp.publication_id
  12332.         from MSpublications as mp, MSsubscriptions as ms
  12333.         where mp.publisher_id = ms.publisher_id
  12334.         and mp.publisher_db = ms.publisher_db
  12335.         and mp.publication_id = ms.publication_id
  12336.         and ms.publisher_id = @publisher_id
  12337.         and ms.publisher_db = @publisher_db
  12338.         and ms.subscriber_id = @subscriber_id
  12339.         and ms.subscriber_db = @subscriber_db
  12340.         and ms.article_id = @article_id
  12341.  
  12342.         select @article = article
  12343.         from MSarticles
  12344.         where article_id = @article_id
  12345.         and publisher_id = @publisher_id
  12346.         and publisher_db = @publisher_db
  12347.         and publication_id = @publication_id
  12348.     end
  12349.  
  12350.     -- Raise the appropriate error
  12351.     if @do_raiserror = 1
  12352.     begin
  12353.         select @agentclassname = formatmessage(14553)
  12354.         exec dbo.sp_MSrepl_raiserror @agentclassname, @agent_name, @raiserror_status, @comments, @subscriber=@subscriber, @publication=@publication, @article=@article
  12355.     end
  12356.     
  12357.     IF @@ERROR <> 0
  12358.        RETURN (1)
  12359. END
  12360. GO   
  12361.  
  12362. raiserror(15339,-1,-1,'sp_MSsubscription_cleanup')
  12363. GO
  12364. CREATE PROCEDURE sp_MSsubscription_cleanup
  12365.     @cutoff_time datetime
  12366.     as
  12367.  
  12368.     declare @max_time datetime
  12369.     declare @active tinyint
  12370.     declare @inactive tinyint
  12371.     declare @subscribed tinyint
  12372.     declare @virtual_anonymous smallint
  12373.     declare @virtual smallint
  12374.     declare @agent_id int
  12375.     declare @retcode int,
  12376.         @num_dropped int
  12377.  
  12378.     set nocount on
  12379.  
  12380.     select @active = 2
  12381.     select @inactive = 0
  12382.     select @subscribed = 1
  12383.     select @virtual = -1
  12384.     select @virtual_anonymous = -2
  12385.  
  12386.     select @max_time = dateadd(hour, 1, getdate())
  12387.  
  12388.     -- Refer to sp_MSmaximun_cleanup_xact_seqno to understand the logic
  12389.     -- in this sp. If you change the logic here, you may need to change
  12390.     -- that sp as well.
  12391.  
  12392.     -- Deactivate real subscriptions for agents that are working on 
  12393.     -- transactions that are older than @retention
  12394.     -- update all the subscriptions for those agents, including
  12395.     -- subscriptions that are in subscribed state!
  12396.     update MSsubscriptions  set status = @inactive where
  12397.         agent_id in (
  12398.         select a.id from 
  12399.             (select s.agent_id, s.subscription_seqno, max(isnull(h.timestamp,0x00))
  12400.                 from 
  12401.                 -- s stores the agent id and min subscription_seqno for
  12402.                 -- active well known subscriptions
  12403.                 (select s2.agent_id, min(s2.subscription_seqno) from
  12404.                     MSsubscriptions s2 
  12405.                     where
  12406.                     s2.status = @active and
  12407.                     -- Only well-known agent
  12408.                     s2.subscriber_id >= 0
  12409.                     group by s2.agent_id)
  12410.                 s (agent_id, subscription_seqno)
  12411.                 left join MSdistribution_history h
  12412.                 on (h.agent_id = s.agent_id)
  12413.                 group by s.agent_id, s.subscription_seqno)
  12414.             sh (agent_id, subscription_seqno, timestamp)
  12415.             left join MSdistribution_history dh 
  12416.             on (dh.agent_id = sh.agent_id and dh.timestamp = sh.timestamp)
  12417.             -- a is for publisher_database_id
  12418.             join MSdistribution_agents a
  12419.             on (a.id = sh.agent_id)
  12420.             where
  12421.             @cutoff_time > = (
  12422.                 -- Get the entry_time of the first tran that cannot be
  12423.                 -- cleaned up normally because of this agent.
  12424.                 -- Use history if it's larger and it is not null (exists)
  12425.                 case  when dh.xact_seqno >= sh.subscription_seqno 
  12426.                 then
  12427.                     -- Have to join with commands table because transactions that
  12428.                     -- does not have commands will not be picked up by
  12429.                     -- sp_MSget_repl_commands
  12430.                     isnull((select top 1 entry_time from MSrepl_transactions t,
  12431.                         MSrepl_commands c where
  12432.                         t.publisher_database_id = a.publisher_database_id and
  12433.                         c.publisher_database_id = a.publisher_database_id and
  12434.                         c.xact_seqno = t.xact_seqno and
  12435.                         -- history xact_seqno can be cleaned up
  12436.                         t.xact_seqno > isnull(dh.xact_seqno,0x0) and
  12437.                         c.xact_seqno > isnull(dh.xact_seqno,0x0)
  12438.                         order by t.xact_seqno asc), @max_time)
  12439.                 else
  12440.                     isnull((select top 1 entry_time from MSrepl_transactions t,
  12441.                         MSrepl_commands c where
  12442.                         t.publisher_database_id = a.publisher_database_id and
  12443.                         c.publisher_database_id = a.publisher_database_id and
  12444.                         c.xact_seqno = t.xact_seqno and
  12445.                         -- sub xact_seqno cannot be cleaned up
  12446.                         t.xact_seqno >= sh.subscription_seqno and
  12447.                         c.xact_seqno >= sh.subscription_seqno                
  12448.                         order by t.xact_seqno asc), @max_time)
  12449.                 end))
  12450.  
  12451.     if @@rowcount <> 0
  12452.         RAISERROR(21011, 10, -1) 
  12453.  
  12454.     -- Dropping all the aonymous agents that are working on
  12455.     -- transactions that are older than @retention
  12456.     -- No message raised.
  12457.     -- Don't drop agents that do not have history (true for new agents).
  12458.     -- For each publisher/publisherdb pair do cleanup
  12459.     declare hC CURSOR LOCAL FAST_FORWARD FOR 
  12460.         select distinct a.id from 
  12461.             (select s.agent_id, s.subscription_seqno, max(isnull(h.timestamp,0x00))
  12462.                 from 
  12463.                 -- s stores the agent id and min subscription_seqno of newest
  12464.                 -- snapshot for
  12465.                 -- active anonymous subscriptions
  12466.                 (select a2.id, min(s2.subscription_seqno) from
  12467.                     MSsubscriptions s2 
  12468.                     join MSdistribution_agents a2
  12469.                     on (a2.virtual_agent_id = s2.agent_id)
  12470.                     where
  12471.                     s2.status = @active 
  12472.                     group by a2.id)
  12473.                 s (agent_id, subscription_seqno)
  12474.                 join MSdistribution_history h
  12475.                 on (h.agent_id = s.agent_id)
  12476.                 group by s.agent_id, s.subscription_seqno)
  12477.             sh (agent_id, subscription_seqno, timestamp)
  12478.             join MSdistribution_history dh 
  12479.             on (dh.agent_id = sh.agent_id and dh.timestamp = sh.timestamp)
  12480.             join MSdistribution_agents a
  12481.             -- a is for publisher_database_id
  12482.             on (a.id = sh.agent_id)
  12483.             where
  12484.             @cutoff_time > = (
  12485.                 -- Get the entry_time of the first tran that cannot be
  12486.                 -- cleaned up normally because of this agent.
  12487.                 -- Use history if it's larger and it is not null (exists)
  12488.                 case  when dh.xact_seqno > 0x00
  12489.                 then
  12490.                     -- does not have commands will not be picked up by
  12491.                     -- sp_MSget_repl_commands
  12492.                     isnull((select top 1 entry_time from MSrepl_transactions t,
  12493.                         MSrepl_commands c where
  12494.                         t.publisher_database_id = a.publisher_database_id and
  12495.                         c.publisher_database_id = a.publisher_database_id and
  12496.                         c.xact_seqno = t.xact_seqno and
  12497.                         -- history xact_seqno can be cleaned up
  12498.                         t.xact_seqno > isnull(dh.xact_seqno,0x0) and
  12499.                         c.xact_seqno > isnull(dh.xact_seqno,0x0)
  12500.                         order by t.xact_seqno asc), @max_time)
  12501.                 else
  12502.                     isnull((select top 1 entry_time from MSrepl_transactions t,
  12503.                         MSrepl_commands c where
  12504.                         t.publisher_database_id = a.publisher_database_id and
  12505.                         c.publisher_database_id = a.publisher_database_id and
  12506.                         c.xact_seqno = t.xact_seqno and
  12507.                         -- sub xact_seqno cannot be cleaned up
  12508.                         t.xact_seqno >= sh.subscription_seqno and
  12509.                         c.xact_seqno >= sh.subscription_seqno
  12510.                         order by t.xact_seqno asc), @max_time)
  12511.                   end)
  12512.     for read only
  12513.     select @num_dropped = 0
  12514.     open hC
  12515.     fetch hC into @agent_id
  12516.     while (@@fetch_status <> -1)
  12517.     begin
  12518.         exec @retcode = dbo.sp_MSdrop_distribution_agentid @agent_id
  12519.         if @retcode <> 0 or @@error <> 0
  12520.             return (1)
  12521.         select @num_dropped = @num_dropped + 1
  12522.         fetch hC into @agent_id
  12523.     end
  12524.     if @num_dropped > 0
  12525.         RAISERROR(20597, 10, -1, @num_dropped) 
  12526.  
  12527.     -- Deactivating subscriptions virtual subscriptions that are older then @retention.
  12528.     update MSsubscriptions  set status = @subscribed
  12529.         where
  12530.         -- Only change active subscriptions!
  12531.         status = @active and 
  12532.         subscriber_id = @virtual and
  12533.                 -- Get the entry_time of the first tran that cannot be
  12534.                 -- cleaned up normally because of this subscription.
  12535.             isnull((select top 1 entry_time from MSrepl_transactions t where
  12536.                 t.publisher_database_id = MSsubscriptions.publisher_database_id and
  12537.                 xact_seqno >= MSsubscriptions.subscription_seqno
  12538.                 order by t.xact_seqno asc), @max_time)
  12539.             <= @cutoff_time
  12540.     if @@rowcount <> 0
  12541.         RAISERROR(21077, 10, -1) 
  12542. GO
  12543.  
  12544. raiserror(15339,-1,-1,'sp_MSreplremoveuncdir')
  12545. GO
  12546. CREATE PROCEDURE sp_MSreplremoveuncdir
  12547. @dir nvarchar(260)
  12548. as
  12549.  
  12550.     set nocount on
  12551.  
  12552.     declare @retcode int
  12553.     declare @local_dir nvarchar(260)
  12554.     declare @cmd nvarchar(1000)
  12555.     declare @machinename sysname
  12556.     /* 
  12557.     ** We have to convert UNC to drive, otherwise will get 'Access denied' error in xp_cmdshell
  12558.     */
  12559.     select @machinename = convert(sysname, SERVERPROPERTY('machinename'))
  12560.     EXEC @retcode = master.dbo.sp_MSunc_to_drive @unc_path = @dir, 
  12561.         @local_server = @machinename, @local_path = @local_dir OUTPUT
  12562.     IF @retcode <> 0 or @@ERROR <> 0 
  12563.         RETURN(1)
  12564.  
  12565.     /*
  12566.     ** Delete directory in the distributor's directory.
  12567.     ** On Win9x, we have to use deltree instead
  12568.     */
  12569.     declare @platform_nt int 
  12570.     select @platform_nt = 0x1
  12571.     IF (( platform() & @platform_nt = @platform_nt))
  12572.     BEGIN 
  12573.         SELECT @cmd = 'if exist "' + @local_dir + '" rmdir /S /Q ' + '"' + @local_dir + '"'
  12574.     END
  12575.     ELSE
  12576.     BEGIN
  12577.         -- Don't need if exists check on Win9x but we do need 
  12578.         -- to remove the trailing slash
  12579.         IF SUBSTRING(@local_dir, LEN(@local_dir), 1) = N'\'
  12580.         BEGIN
  12581.             SELECT @local_dir = LEFT(@local_dir, LEN(@local_dir)-1)
  12582.         END
  12583.         SELECT @cmd = 'deltree /Y ' + '"' + @local_dir + '"'
  12584.     END
  12585.  
  12586.     EXECUTE  @retcode = master..xp_cmdshell @cmd, NO_OUTPUT
  12587.     IF @retcode <> 0 or @@ERROR <> 0 
  12588.     begin
  12589.         raiserror(20015, 16, -1, @dir)
  12590.         RETURN(1)
  12591.     end
  12592. go
  12593.  
  12594. raiserror(15339,-1,-1,'sp_MSdrop_snapshot_dirs')
  12595. GO
  12596. CREATE PROCEDURE sp_MSdrop_snapshot_dirs
  12597. as
  12598.     declare @retcode int
  12599.     declare @snapshot_bit int
  12600.     declare @directory_type int
  12601.     declare @alt_directory_type int
  12602.     declare @publisher_database_id int
  12603.         
  12604.     declare @dir nvarchar(512)
  12605.     declare @command_id int
  12606.     declare @xact_seqno varbinary(16)
  12607.     
  12608.     select @snapshot_bit = 0x80000000
  12609.     select @directory_type = 7
  12610.     select @alt_directory_type = 25
  12611.  
  12612.     declare  hCdirs  CURSOR LOCAL FAST_FORWARD FOR select CONVERT(nvarchar(512), command),
  12613.         xact_seqno, command_id, publisher_database_id
  12614.         from MSrepl_commands where
  12615.         ((type & ~@snapshot_bit) = @directory_type) or
  12616.         ((type & ~@snapshot_bit) = @alt_directory_type)
  12617.     for read only
  12618.  
  12619.     open hCdirs
  12620.     fetch hCdirs into @dir, @xact_seqno, @command_id, @publisher_database_id
  12621.     while (@@fetch_status <> -1)
  12622.     begin
  12623.          -- Need to map unc to local drive for access problem
  12624.         exec @retcode = dbo.sp_MSreplremoveuncdir @dir
  12625.         /* Abort the operation if the delete fails */
  12626.         if (@retcode <> 0 or @@error <> 0)
  12627.             return (1)
  12628.  
  12629.         delete MSrepl_commands where 
  12630.             publisher_database_id = @publisher_database_id and
  12631.             xact_seqno = @xact_seqno and
  12632.             command_id = @command_id
  12633.  
  12634.         fetch hCdirs into @dir, @xact_seqno, @command_id, @publisher_database_id
  12635.     end
  12636.     close hCdirs
  12637.     deallocate hCdirs
  12638. GO
  12639.  
  12640. raiserror(15339,-1,-1,'sp_MSfast_delete_trans')
  12641. GO
  12642. CREATE PROCEDURE sp_MSfast_delete_trans
  12643. as
  12644.     declare @retcode int
  12645.  
  12646.     EXEC @retcode = sp_MSdrop_snapshot_dirs
  12647.     if( @retcode <> 0 or @@error <> 0 )
  12648.         return 1
  12649.  
  12650.     truncate table MSrepl_commands
  12651.     truncate table MSrepl_transactions
  12652.  
  12653. GO
  12654.  
  12655. raiserror(15339,-1,-1,'sp_MSdelete_dodelete')
  12656. go
  12657. -- New delete stored procedure WITH RECOMPILE
  12658. CREATE PROCEDURE sp_MSdelete_dodelete
  12659.     @publisher_database_id int,
  12660.     @max_xact_seqno varbinary(16),
  12661.     @last_xact_seqno varbinary(16),
  12662.     @last_log_xact_seqno varbinary(16)
  12663. WITH RECOMPILE
  12664.     as
  12665.         delete MSrepl_transactions WITH (PAGLOCK) from MSrepl_transactions where
  12666.                 publisher_database_id = @publisher_database_id and
  12667.                 xact_seqno <= @max_xact_seqno and
  12668.                 xact_seqno <> @last_xact_seqno and
  12669.                 xact_seqno <> @last_log_xact_seqno and
  12670.                 -- use nolock to avoid deadlock
  12671.                 not exists (select * from MSrepl_commands c (nolock) where
  12672.                     c.publisher_database_id = @publisher_database_id and
  12673.                     c.xact_seqno = MSrepl_transactions.xact_seqno)
  12674. GO
  12675.  
  12676. raiserror(15339,-1,-1,'sp_MSdelete_publisherdb_trans')
  12677. GO
  12678. CREATE PROCEDURE sp_MSdelete_publisherdb_trans
  12679.     @publisher_database_id int,
  12680.     @max_xact_seqno varbinary(16),
  12681.     @max_cutoff_time datetime,
  12682.     @num_transactions int OUTPUT,
  12683.     @num_commands int OUTPUT
  12684.     as
  12685.  
  12686.     set nocount on
  12687.     
  12688.     declare @snapshot_bit int
  12689.     declare @replpost_bit int
  12690.     declare @directory_type int
  12691.     declare @alt_directory_type int
  12692.     declare @scriptexec_type int
  12693.     declare @last_xact_seqno varbinary(16)
  12694.     declare @last_log_xact_seqno varbinary(16)
  12695.     declare @max_immediate_sync_seqno varbinary(16)
  12696.     declare @dir nvarchar(512)
  12697.     declare @row_count int
  12698.     declare @batchsize int
  12699.     declare @retcode int            /* Return value of xp_cmdshell */
  12700.     declare @has_immediate_sync bit
  12701.     declare @xact_seqno varbinary(16)
  12702.     declare @command_id int
  12703.     declare @type int
  12704.     declare @directory nvarchar(1024)
  12705.  
  12706.     select @snapshot_bit = 0x80000000
  12707. select @replpost_bit = 0x40000000
  12708.     select @directory_type = 7
  12709.     select @alt_directory_type = 25
  12710. select @scriptexec_type = 46
  12711.     select @num_transactions = 0
  12712.     select @num_commands = 0
  12713.  
  12714.     -- If transactions for immediate_sync publications will not be cleanup up until
  12715.     -- they are older that max retention, except for snapshot transactions.
  12716.     -- Snapshot transactions for immediate_sync publication will be cleanup up if it is
  12717.     -- not used by any subscriptions (including virtual and virtual immediate_syncymous
  12718.     -- subscriptions. Both will be reset by snapshot agent every time if the 
  12719.     -- publication is snapshot type.) The special logic for snapshot transactions
  12720.     -- is mostly for snapshop publications. It is to cleaup up the snapshot files 
  12721.     -- ASAP and not to wait for max retention.
  12722.     -- We don't need to do this for non-immediate_syncymous publications since the snapshot
  12723.     -- trans for them will be removed as soon as they are distributed and min '
  12724.     -- retention is reached.
  12725.  
  12726.     -- Detect if there are immediate_syncymous publications in this publishing db.
  12727.     if exists (select * from MSsubscriptions where
  12728.             publisher_database_id = @publisher_database_id and
  12729.             subscriber_id < 0)
  12730.         select @has_immediate_sync = 1
  12731.     else
  12732.         select @has_immediate_sync = 0
  12733.  
  12734.     if @has_immediate_sync = 1
  12735.     begin
  12736.         -- if @max_immediate_sync_seqno is null, not row will be deleted based on that.
  12737.         select @max_immediate_sync_seqno = max(xact_seqno) from MSrepl_transactions where
  12738.             publisher_database_id = @publisher_database_id and
  12739.             entry_time <= @max_cutoff_time
  12740.     end
  12741.  
  12742.     -- Note delete commands first since transaction table will be used for
  12743.     -- geting @max_xact_seqno (see sp_MSmaximum_cleanup_seqno).
  12744.     -- Delete all directories stored in directory command.
  12745.     if @has_immediate_sync = 0
  12746.         declare  hCdirs  CURSOR LOCAL FAST_FORWARD FOR select CONVERT(nvarchar(512), command),
  12747.             xact_seqno, command_id, type
  12748.             from MSrepl_commands where
  12749.             publisher_database_id = @publisher_database_id and
  12750.             xact_seqno <= @max_xact_seqno and   
  12751.             ((type & ~@snapshot_bit) = @directory_type or
  12752.             (type & ~@snapshot_bit) = @alt_directory_type)
  12753.         for read only
  12754.     else
  12755.         declare  hCdirs  CURSOR LOCAL FAST_FORWARD FOR select CONVERT(nvarchar(512), command),
  12756.             xact_seqno, command_id, type
  12757.             from MSrepl_commands c where
  12758.             publisher_database_id = @publisher_database_id and
  12759.             ((type & ~@snapshot_bit) = @directory_type  or
  12760.              (type & ~@snapshot_bit) = @alt_directory_type or
  12761.              (type & ~@replpost_bit) = @scriptexec_type) and
  12762.             xact_seqno <= @max_xact_seqno and  
  12763.             (
  12764.             -- Select the row if it is older than max retention.
  12765.             xact_seqno <= @max_immediate_sync_seqno or 
  12766.             -- Select the row if it is not used by any subscriptions.
  12767.             not exists (select * from MSsubscriptions s where
  12768.                 s.publisher_database_id = @publisher_database_id and
  12769.                 s.subscription_seqno = c.xact_seqno) OR
  12770.             -- Select the row if it is not for immediate_sync publications
  12771.             -- Note: directory command have article id 0 so it is not useful
  12772.             not exists (select * from MSpublications p where
  12773.                 p.publication_id = (select top 1 s.publication_id 
  12774.                     from MSsubscriptions s where
  12775.                     s.publisher_database_id = @publisher_database_id and
  12776.                     s.subscription_seqno = c.xact_seqno) and
  12777.                 p.immediate_sync = 1)
  12778.             )
  12779.         for read only
  12780.  
  12781.     open hCdirs
  12782.     fetch hCdirs into @dir, @xact_seqno, @command_id, @type
  12783.     while (@@fetch_status <> -1)
  12784.     begin
  12785.     if( (@type & ~@replpost_bit) = @scriptexec_type) -- script exec command, need to map to the right path.
  12786.         select @dir = left(@dir,len(@dir) - charindex(N'\', reverse(@dir)))        
  12787.     -- Need to map unc to local drive for access problem
  12788.         exec @retcode = dbo.sp_MSreplremoveuncdir @dir
  12789.         /* Abort the operation if the delete fails */
  12790.         if (@retcode <> 0 or @@error <> 0)
  12791.             return (1)
  12792.  
  12793.         delete MSrepl_commands where 
  12794.             publisher_database_id = @publisher_database_id and
  12795.             xact_seqno = @xact_seqno and
  12796.             command_id = @command_id
  12797.         -- Update output parameter
  12798.         select @num_commands = @num_commands + @@rowcount
  12799.  
  12800.         fetch hCdirs into @dir, @xact_seqno, @command_id, @type
  12801.     end
  12802.     close hCdirs
  12803.     deallocate hCdirs
  12804.  
  12805.  
  12806.     -- Delete all commans less than or equal to the @max_xact_seqno
  12807.     -- Delete in batch to reduce the transaction size
  12808.     set rowcount 2000
  12809.     WHILE 1 = 1
  12810.     BEGIN
  12811.         if @has_immediate_sync = 0
  12812.             DELETE MSrepl_commands WITH (PAGLOCK) where
  12813.                 publisher_database_id = @publisher_database_id and
  12814.                 xact_seqno <= @max_xact_seqno
  12815.         else
  12816.             -- Use nolock hint on subscription table to avoid deadlock
  12817.             -- with snapshot agent.
  12818.             DELETE MSrepl_commands WITH (PAGLOCK) where
  12819.                 publisher_database_id = @publisher_database_id and
  12820.                 xact_seqno <= @max_xact_seqno and
  12821.                 -- Don't delete directory commands. It is deleted ealier.
  12822.                 -- We have to do this because we use (nolock) hint. we have to make sure
  12823.                 -- we don't delete dir command when the file is not cleaned up in the code
  12824.                 -- above.
  12825.                 (type & ~@snapshot_bit) <> @directory_type and
  12826.                 (
  12827.                 -- Select the row if it is older than max retention.
  12828.                 xact_seqno <= @max_immediate_sync_seqno or 
  12829.                 -- Select the row if it is not for immediate_sync article
  12830.                 -- We know the command is for immediate_sync publication if
  12831.                 -- the snapshot tran include articles that has virtual
  12832.                 -- subscritptions. (use subscritpion table to avoid join with
  12833.                 -- article and publication table)
  12834.                 not exists (select * from MSsubscriptions s (nolock) where
  12835.                     s.publisher_database_id = @publisher_database_id and
  12836.                     s.article_id = MSrepl_commands.article_id and
  12837.                     s.subscriber_id < 0) or
  12838.                 -- Select the row if it is snapshot tran and 
  12839.                 -- not used by any subscriptions.
  12840.                 -- Delete the snapshot commands if there's no subscriptions that are not 
  12841.                 -- virtual anonymous have smaller or equal subscription_seqno than 
  12842.                 -- the command's xact_seqno.
  12843.                 ((type & @snapshot_bit) <> 0 and
  12844.                 not exists (select * from MSsubscriptions s (nolock) where
  12845.                     s.publisher_database_id = @publisher_database_id and
  12846.                     s.subscription_seqno <= MSrepl_commands.xact_seqno and
  12847.                     s.subscriber_id <> -2))
  12848.                 )
  12849.  
  12850.         select @row_count = @@rowcount
  12851.         -- Update output parameter
  12852.         select @num_commands = @num_commands + @row_count
  12853.     
  12854.         IF @row_count = 0 -- passed the result set.  We're done
  12855.             BREAK
  12856.     END
  12857.  
  12858.     -- Optimized query to get the max transaction row
  12859.     set rowcount 1
  12860.     select @last_log_xact_seqno = xact_seqno from MSrepl_transactions
  12861.         where
  12862.             publisher_database_id = @publisher_database_id and
  12863.             xact_id <> 0x0  -- not initial sync transaction
  12864.             order by xact_seqno desc
  12865.  
  12866.     select @last_xact_seqno = xact_seqno from MSrepl_transactions
  12867.         where
  12868.             publisher_database_id = @publisher_database_id
  12869.             order by xact_seqno desc
  12870.     set rowcount 0
  12871.  
  12872.     -- Remove all transactions less than or equal to the @max_xact_seqno and leave the 
  12873.     -- last transaction row
  12874.     -- Note @max_xact_seqno might be null, in this case don't do any thing.
  12875.     -- Delete in batchs to reduce the transaction size
  12876.     set rowcount 5000
  12877.     -- Delete all commans less than or equal to the @max_xact_seqno
  12878.     -- Delete  rows to reduce the transaction size
  12879.     WHILE 1 = 1
  12880.     BEGIN
  12881.         if @has_immediate_sync = 0
  12882.             delete MSrepl_transactions WITH (PAGLOCK) from MSrepl_transactions where
  12883.                 publisher_database_id = @publisher_database_id and
  12884.                 xact_seqno <= @max_xact_seqno and
  12885.                 xact_seqno <> @last_xact_seqno and
  12886.                 xact_seqno <> @last_log_xact_seqno
  12887.         else
  12888.             exec dbo.sp_MSdelete_dodelete @publisher_database_id, @max_xact_seqno, 
  12889.                 @last_xact_seqno, @last_log_xact_seqno 
  12890.  
  12891.         select @row_count = @@rowcount
  12892.  
  12893.         -- Update output parameter
  12894.         select @num_transactions = @num_transactions + @row_count
  12895.         if @row_count = 0
  12896.             BREAK
  12897.     END
  12898.     set rowcount 0
  12899. GO
  12900.  
  12901. raiserror(15339,-1,-1,'sp_MSmaximum_cleanup_seqno')
  12902. go
  12903. CREATE PROCEDURE sp_MSmaximum_cleanup_seqno
  12904.     @publisher_database_id int,
  12905.     @min_cutoff_time datetime,
  12906.     @max_cleanup_xact_seqno varbinary(16) OUTPUT
  12907.     as
  12908.  
  12909.     declare @min_sub_xact_seqno varbinary(16)
  12910.     declare @min_history_xact_seqno varbinary(16)
  12911.     declare @active int
  12912.     declare @initiated int
  12913.     declare @max_seqno varbinary(16)
  12914.     
  12915.     -- @max_seqn is to avoid warnging message from server on null values in aggregation.
  12916.     select @max_seqno = 0xffffffffffffffffffffffffffffffff
  12917.  
  12918.     set nocount on
  12919.  
  12920.     select @active = 2
  12921.     select @initiated = 3
  12922.  
  12923.     select  
  12924.         -- Get the min history xact_seqno that are large then or equal to starting
  12925.         -- sub seqno
  12926.         @min_history_xact_seqno = min(seqno.xact_seqno), 
  12927.         -- Get the min starting sub xact_seqno without larger history xact_seqno or without
  12928.         -- any history at all.
  12929.         @min_sub_xact_seqno = min(seqno.subscription_seqno)
  12930.         from
  12931.             -- seqno stores min sub seqno , min history seqno and choose_sub
  12932.             (select 
  12933.                 -- If history is larger and it is not null
  12934.                 -- use history.
  12935.                 case when dh.xact_seqno > = sh.subscription_seqno 
  12936.                 then dh.xact_seqno
  12937.                 -- Don't use dh in else
  12938.                 else @max_seqno
  12939.                 end,
  12940.  
  12941.                 -- If history is larger and it is not null
  12942.                 -- use history.
  12943.                 case when dh.xact_seqno > = sh.subscription_seqno 
  12944.                 -- Don't use sh
  12945.                 then @max_seqno
  12946.                 else sh.subscription_seqno
  12947.                 end
  12948.  
  12949.                 from 
  12950.                     (select s.agent_id, s.subscription_seqno, max(isnull(h.timestamp,0x00))
  12951.                     from 
  12952.                         -- s stores the agent id and min subscription_seqno for
  12953.                         -- active subscriptions on non immediate_sync subscriptions
  12954.                         (select a.id, min(s2.subscription_seqno) from
  12955.                             MSsubscriptions s2 
  12956.                             join MSdistribution_agents a
  12957.                             on (a.id = s2.agent_id) 
  12958.                             where
  12959.                             s2.status in( @active, @initiated ) and
  12960.                             /* Note must filter out virtual anonymous agents !!!
  12961.                                 a.subscriber_id <> @virtual_anonymous and */
  12962.                             -- filter out subscriptions to immediate_sync publications
  12963.                             not exists (select * from MSpublications p where
  12964.                                 s2.publication_id = p.publication_id and
  12965.                                 p.immediate_sync = 1) and
  12966.                             a.publisher_database_id = @publisher_database_id
  12967.                             group by a.id)
  12968.                         s (agent_id, subscription_seqno)
  12969.                         left join MSdistribution_history h
  12970.                         on (h.agent_id = s.agent_id)
  12971.                         group by s.agent_id, s.subscription_seqno)
  12972.                     sh (agent_id, subscription_seqno, timestamp)
  12973.                     left join MSdistribution_history dh 
  12974.                     on (dh.agent_id = sh.agent_id and dh.timestamp = sh.timestamp))
  12975.                     seqno (xact_seqno, subscription_seqno)
  12976.  
  12977.  
  12978.  
  12979. /*  This version might be faster.. Need experiments.
  12980.  
  12981.  
  12982.     -- Get the min history xact_seqno that are large then or equal to starting
  12983.     -- sub seqno
  12984.     select @min_history_xact_seqno = min(dh.xact_seqno) from
  12985.         -- h stores the agent_ids and last xact_seqno for the publisher_db 
  12986.         (select h2.agent_id, max(h2.timestamp) 
  12987.             from MSdistribution_history h2
  12988.             join MSdistribution_agents a
  12989.                 on (a.id = h2.agent_id)
  12990.             where
  12991.                 a.publisher_database_id = @publisher_database_id
  12992.                 group by h2.agent_id)
  12993.         h (agent_id, timestamp) 
  12994.         -- dh stores timestamp and xact_seqno association
  12995.         join MSdistribution_history dh 
  12996.             on (dh.agent_id = h.agent_id and dh.timestamp = h.timestamp)
  12997.         where   
  12998.             -- Only select history xact seqno larger then or equal to
  12999.             -- subscription start up seqno.
  13000.             -- Excluding agents with no active subscriptions. 
  13001.             dh.xact_seqno >=
  13002.                 (select min(s.subscription_seqno) from MSsubscritions s where
  13003.                     -- Including anonymous agents
  13004.                     (s.agent_id = a. agent_id or s.agent_id = a.anonymous_agent_id) and
  13005.                     s.status = @active)
  13006.             
  13007.     -- Get the min starting sub xact_seqno without larger history xact_seqno or without
  13008.     -- any history at all.
  13009.     -- This will happen if the subscription is reinited
  13010.     -- excluding virtual anonymous subscriptions.
  13011.     select @min_sub_xact_seqno = min(s.subscription_seqno) from
  13012.         MSsubscriptions s
  13013.         -- left join so that subscription without history will be included. 
  13014.         left join ((select h2.agent_id, max(h2.timestamp) 
  13015.             from MSdistribution_history h2
  13016.             join MSdistribution_agents a
  13017.                 on (a.id = h2.agent_id)
  13018.             where
  13019.                 a.publisher_database_id = @publisher_database_id
  13020.                 group by h2.agent_id)
  13021.             h (agent_id, timestamp) 
  13022.         -- dh stores timestamp and xact_seqno association
  13023.         join MSdistribution_history dh 
  13024.             on (dh.agent_id = h.agent_id and dh.timestamp = h.timestamp))
  13025.             on (s.agent_id = h.agent_id)
  13026.         where
  13027.         s.status = @active and
  13028.         s.subscriber_id <> @virtual_anonymous and
  13029.         s.publisher_database_id = @publisher_database_id and
  13030.         -- select only subs that has a larger starting seqno than history last seqno
  13031.         -- or with no history
  13032.         s.subscription_seqno > isnull(dh.xact_seqno, 0x0)
  13033. */  
  13034.     
  13035.     /* 
  13036.     ** Optimized query to get the maximum cleanup xact_seqno
  13037.     */
  13038.     /* 
  13039.     ** If the query below returns nothing, nothing can be deleted.
  13040.     ** Reset @max_cleanup_xact_seqno to 0.
  13041.     */
  13042.     select @max_cleanup_xact_seqno = 0x00
  13043.     -- Use top 1 to avoid warning message of "Null in aggregate..." which will make
  13044.     -- sqlserver agent job having failing status
  13045.     select top 1 @max_cleanup_xact_seqno = xact_seqno
  13046.         from MSrepl_transactions
  13047.         where
  13048.             publisher_database_id = @publisher_database_id and
  13049.             (@min_history_xact_seqno IS NULL or
  13050.             -- Delete the history xact since it is distributed already.
  13051.             xact_seqno <= @min_history_xact_seqno) and
  13052.             (@min_sub_xact_seqno IS NULL or
  13053.             -- Don't delete the sub xact since it is not distributed yet.
  13054.             xact_seqno < @min_sub_xact_seqno) and
  13055.             entry_time <= @min_cutoff_time
  13056.             order by xact_seqno desc
  13057.  
  13058. GO
  13059.  
  13060. raiserror(15339,-1,-1,'sp_MSdistribution_delete')
  13061. go
  13062. CREATE PROCEDURE sp_MSdistribution_delete
  13063.     @retention int = 0,
  13064.     -- Used for anon publications.
  13065.     @max_cutoff_time datetime
  13066.     as
  13067.     declare @min_cutoff_time datetime
  13068.     declare @subscriber sysname
  13069.     declare @subscriber_db sysname
  13070.     declare @max_cleanup_xact_seqno varbinary(16)   
  13071.     declare @num_transactions int
  13072.     declare @num_commands int
  13073.     declare @start_time datetime
  13074.     declare @num_seconds int
  13075.     declare @rate int
  13076.     declare @retcode int
  13077.     declare @publisher_database_id int
  13078.  
  13079.     set nocount on
  13080.  
  13081.     select @num_transactions = 0
  13082.     select @num_commands = 0
  13083.  
  13084.     select @start_time = getdate()
  13085.     select @min_cutoff_time = dateadd(hour, -@retention, getdate())
  13086.  
  13087.     -- For each publisher/publisherdb pair do cleanup
  13088.     declare hC CURSOR LOCAL FAST_FORWARD FOR select distinct publisher_database_id
  13089.         from MSrepl_transactions
  13090.         for read only
  13091.     -- With ANSI Defaults ON, the cursor will automatically
  13092.     -- be closed on commit.   Since this proc gets called recursively, 
  13093.     -- this can happen.  So check before opening. 
  13094.     IF CURSOR_STATUS('local','hC') = -1
  13095.     open hC
  13096.  
  13097.     fetch hC into @publisher_database_id 
  13098.     while (@@fetch_status <> -1)
  13099.     begin
  13100.  
  13101.         -- Find the maximum transaction to delete
  13102.         exec @retcode = dbo.sp_MSmaximum_cleanup_seqno @publisher_database_id, @min_cutoff_time, @max_cleanup_xact_seqno OUTPUT
  13103.         if @retcode <> 0
  13104.             goto FAIL           
  13105.  
  13106.         -- Delete transactions and commands
  13107.         exec @retcode = dbo.sp_MSdelete_publisherdb_trans @publisher_database_id, 
  13108.             @max_cleanup_xact_seqno, @max_cutoff_time,
  13109.             @num_transactions OUTPUT, @num_commands OUTPUT
  13110.         if @retcode <> 0
  13111.             goto FAIL
  13112.  
  13113.         IF CURSOR_STATUS('local','hC') = -1
  13114.             open hC
  13115.         
  13116.         fetch hC into @publisher_database_id 
  13117.     end
  13118.     close hC
  13119.     deallocate hC
  13120.  
  13121.     select @num_seconds = datediff(second, @start_time, getdate())
  13122.     if @num_seconds <> 0 
  13123.       select @rate = (@num_transactions+@num_commands)/@num_seconds
  13124.     else
  13125.       select @rate = 0
  13126.  
  13127.    RAISERROR(21010, 10, -1, @num_transactions, @num_commands, @num_seconds, @rate)
  13128.  
  13129.    return 0
  13130.  
  13131. FAIL:
  13132.    close hC
  13133.    deallocate hC
  13134.    return 1
  13135. GO
  13136.  
  13137.  
  13138. raiserror(15339,-1,-1,'sp_MSdistribution_cleanup')
  13139. GO
  13140. CREATE PROCEDURE sp_MSdistribution_cleanup
  13141.     @min_distretention int = 0,
  13142.     @max_distretention int = 24
  13143.     as
  13144.  
  13145.     declare @retcode int
  13146.     declare @agent_name nvarchar(255)
  13147.     declare @agent_type nvarchar(100)
  13148.     declare @message nvarchar(255)
  13149.     declare @cutoff_time datetime
  13150.  
  13151.      -- Check for invalid parameter values 
  13152.     if @min_distretention < 0 or @max_distretention < 0
  13153.     begin
  13154.         RAISERROR(14106, 16, -1)
  13155.         return (1)
  13156.     end
  13157.  
  13158.     -- Note: we need to use the same cut_off time for sp_MSsubscription_cleanup
  13159.     -- and sp_MSdistribution_delete since sp_MSsubscription_cleanup need to disable
  13160.     -- all the dist agents that are lag behind (their pending trans will be removed)
  13161.     select @cutoff_time = dateadd(hour, -@max_distretention, getdate())
  13162.  
  13163.     -- Deactive any subscriptions which have been inactive beyond the maximum retention
  13164.     exec @retcode = dbo.sp_MSsubscription_cleanup @cutoff_time
  13165.     if @retcode <> 0
  13166.         goto FAIL
  13167.  
  13168.     -- Remove transactions and commands
  13169.     exec @retcode = dbo.sp_MSdistribution_delete @min_distretention, 
  13170.         -- used to cleanup trans for anon publications.
  13171.         @cutoff_time
  13172.     if @retcode <> 0
  13173.         goto FAIL
  13174.  
  13175.     -- Update statistics on cleaned tables with norecompute flag
  13176.     -- to both update the statistics periodically and 
  13177.     -- to ensure that they are not updated too frequently
  13178.     -- since this slows performance.
  13179.     --
  13180.     -- Update statistics can only be performed when not in
  13181.     -- not in a tracation so predicate by transaction level
  13182.     -- to avoid error.
  13183.     --
  13184.     if @@trancount = 0
  13185.     begin
  13186.         UPDATE STATISTICS MSrepl_commands WITH NORECOMPUTE
  13187.         UPDATE STATISTICS MSrepl_transactions WITH NORECOMPUTE
  13188.     end
  13189.  
  13190.     return(0)
  13191.  
  13192. FAIL:
  13193.     -- Raise the Agent Failure error
  13194.     set @agent_type  = formatmessage(20543)
  13195.     SELECT @agent_name = db_name() + @agent_type
  13196.     set @message  = formatmessage(20552)
  13197.     exec dbo.sp_MSrepl_raiserror @agent_type, @agent_name, 5, @message
  13198.     return (1)  
  13199.  
  13200. GO
  13201.  
  13202. raiserror(15339,-1,-1,'sp_MShistory_cleanup')
  13203. GO
  13204. CREATE PROCEDURE sp_MShistory_cleanup
  13205. @history_retention int = 24
  13206. as
  13207.     declare @cutoff_time datetime
  13208.     declare @start_time datetime
  13209.     declare @num_snapshot_rows int
  13210.     declare @num_logreader_rows int
  13211.     declare @num_distribution_rows int
  13212.     declare @num_replerror_rows int
  13213.     declare @num_queuereader_rows int
  13214.         ,@num_alert_rows int
  13215.     declare @num_milliseconds int
  13216.     declare @num_seconds float
  13217.     declare @seconds_str nvarchar(10)
  13218.     declare @rate int
  13219.     declare @retcode int
  13220.     declare @total_rows int
  13221.     declare @num_merge_rows int
  13222.     declare @agent_name nvarchar(255)
  13223.     declare @agent_type nvarchar(100)
  13224.     declare @message nvarchar(255)
  13225.     declare @agent_id int
  13226.     declare @temp_error int
  13227.  
  13228.     set nocount on
  13229.  
  13230.     /* Check for invalid parameter values */
  13231.     if @history_retention < 0
  13232.     BEGIN
  13233.         RAISERROR(14106, 16, -1)
  13234.         RETURN (1)
  13235.     END
  13236.     
  13237.     -- Get start time for statistics at the end
  13238.     select @start_time = getdate()
  13239.  
  13240.     select @num_snapshot_rows = 0
  13241.     select @num_logreader_rows = 0
  13242.     select @num_distribution_rows = 0
  13243.     select @num_merge_rows = 0
  13244.     select @num_replerror_rows = 0
  13245.     select @num_queuereader_rows = 0
  13246.  
  13247.     -- Get cutoff time
  13248.     select @cutoff_time = dateadd(hour, -@history_retention, getdate())
  13249.  
  13250.     -- Delete sp_MSsnapshot_history (leave at least one row for monitoring)
  13251.     delete MSsnapshot_history where 
  13252.         time <= @cutoff_time and
  13253.         timestamp not in (select max(timestamp) from MSsnapshot_history 
  13254.             group by agent_id)
  13255.     select @temp_error = @@error, @num_snapshot_rows = @num_snapshot_rows + @@rowcount
  13256.     if @temp_error <> 0
  13257.         goto FAIL
  13258.  
  13259.     -- Delete sp_MSsnapshot_history that no longer has an MSsnapshot_agent entry
  13260.     delete from MSsnapshot_history where not exists (select * from MSsnapshot_agents
  13261.         where id = agent_id)
  13262.     select @temp_error = @@error, @num_snapshot_rows = @num_snapshot_rows + @@rowcount
  13263.     if @temp_error <> 0
  13264.         goto FAIL
  13265.  
  13266.     -- Delete sp_MSlogreader_history (leave at least one row for monitoring)
  13267.     delete MSlogreader_history where 
  13268.         time <= @cutoff_time and
  13269.         timestamp not in (select max(timestamp) from MSlogreader_history 
  13270.             group by agent_id)
  13271.     select @temp_error = @@error, @num_logreader_rows = @num_logreader_rows + @@rowcount
  13272.     if @temp_error <> 0
  13273.         goto FAIL
  13274.  
  13275.     -- Delete sp_MSlogreader_history that no longer has an MSlogreader_agent entry
  13276.     delete from MSlogreader_history where not exists (select * from MSlogreader_agents
  13277.         where id = agent_id)
  13278.     select @temp_error = @@error, @num_logreader_rows = @num_logreader_rows + @@rowcount
  13279.     if @temp_error <> 0
  13280.         goto FAIL
  13281.  
  13282.     -- Delete sp_MSdistribution_history (leave at least one row for monitoring)
  13283.     -- Leave last record ONLY if the agent is not anonymous.  The current logic is to remove all history for anonymous
  13284.     -- subscription, the agent definition will also be removed below.
  13285.     delete MSdistribution_history where 
  13286.         time <= @cutoff_time and
  13287.         timestamp not in (select max(timestamp) from MSdistribution_history group by agent_id)
  13288.     select @temp_error = @@error, @num_distribution_rows = @num_distribution_rows + @@rowcount
  13289.     if @temp_error <> 0
  13290.         goto FAIL
  13291.  
  13292.     -- Delete sp_MSdistribution_history that no longer has an MSdistribution_agent entry
  13293.     delete MSdistribution_history from MSdistribution_history dh where not exists (select * from MSdistribution_agents
  13294.         where id = dh.agent_id)
  13295.     select @temp_error = @@error, @num_distribution_rows = @num_distribution_rows + @@rowcount
  13296.     if @temp_error <> 0
  13297.         goto FAIL
  13298.  
  13299.     -- Delete MSqreader_history (leave at least one row for monitoring)
  13300.     delete MSqreader_history where 
  13301.         time <= @cutoff_time and
  13302.         timestamp not in (select max(timestamp) from MSqreader_history 
  13303.             group by agent_id)
  13304.     select @temp_error = @@error, @num_queuereader_rows = @num_queuereader_rows + @@rowcount
  13305.     if @temp_error <> 0
  13306.         goto FAIL
  13307.  
  13308.     -- Delete sp_MSlogreader_history that no longer has an MSlogreader_agent entry
  13309.     delete from MSqreader_history where not exists (select * from MSqreader_agents
  13310.         where id = agent_id)
  13311.     select @temp_error = @@error, @num_queuereader_rows = @num_queuereader_rows + @@rowcount
  13312.     if @temp_error <> 0
  13313.         goto FAIL
  13314.  
  13315.     -- Delete sp_MSmerge_history (leave at least one row for monitoring)
  13316.     -- Leave last record ONLY if the agent is not anonymous.  The current logic is to remove all history for anonymous
  13317.     -- subscription, the agent definition will also be removed below.
  13318.     delete from MSmerge_history where 
  13319.         time <= @cutoff_time and
  13320.         timestamp not in (select max(timestamp) from MSmerge_history group by agent_id)
  13321.     select @temp_error = @@error, @num_merge_rows = @num_merge_rows + @@rowcount
  13322.     if @temp_error <> 0
  13323.         goto FAIL
  13324.  
  13325.     -- Delete sp_MSmerge_history that no longer has an MSmerge_agent entry
  13326.     delete from MSmerge_history where not exists (select * from MSmerge_agents where id = agent_id)
  13327.     select @temp_error = @@error, @num_merge_rows = @num_merge_rows + @@rowcount
  13328.     if @temp_error <> 0
  13329.         goto FAIL
  13330.  
  13331.     -- Delete MSrepl_error entries
  13332.     delete from MSrepl_errors where time <= @cutoff_time 
  13333.     select @temp_error = @@error, @num_replerror_rows = @@rowcount
  13334.     if @temp_error <> 0
  13335.         goto FAIL
  13336.     
  13337.     -- Delete sysreplicationalerts table
  13338.     delete from msdb..sysreplicationalerts where time <= @cutoff_time 
  13339.     select @temp_error = @@error, @num_alert_rows = @@rowcount
  13340.     if @temp_error <> 0
  13341.         goto FAIL
  13342.  
  13343.     -- Calculate statistics for number of rows deleted
  13344.     select @num_milliseconds = datediff(millisecond, @start_time, getdate())
  13345.     if @num_milliseconds <> 0
  13346.         select @num_seconds = @num_milliseconds*1.0/1000
  13347.     else 
  13348.         select @num_seconds = 0
  13349.  
  13350.     select @total_rows = @num_snapshot_rows + @num_logreader_rows + 
  13351.         @num_distribution_rows +  @num_merge_rows + @num_replerror_rows + @num_alert_rows
  13352.  
  13353.     if @num_seconds <> 0 
  13354.         select @rate = @total_rows/@num_seconds
  13355.     else
  13356.         select @rate = @total_rows
  13357.  
  13358.     select @seconds_str = CONVERT(nchar(10), @num_seconds)
  13359.  
  13360.     RAISERROR(14108, 10, -1, @num_merge_rows, 'MSmerge_history')
  13361.     RAISERROR(14108, 10, -1, @num_snapshot_rows, 'MSsnapshot_history')
  13362.     RAISERROR(14108, 10, -1, @num_logreader_rows, 'MSlogreader_history')
  13363.     RAISERROR(14108, 10, -1, @num_distribution_rows, 'MSdistribution_history')
  13364.     RAISERROR(14108, 10, -1, @num_queuereader_rows, 'MSqreader_history')
  13365.     RAISERROR(14108, 10, -1, @num_replerror_rows, 'MSrepl_errors')
  13366.     RAISERROR(14108, 10, -1, @num_alert_rows, 'sysreplicationalerts')
  13367.     RAISERROR(14149, 10, -1, @total_rows, @seconds_str, @rate)
  13368.     
  13369.     return 0
  13370.  
  13371. FAIL:
  13372.     -- Raise the Agent Failure error
  13373.     set @agent_type  = formatmessage(20544)
  13374.     SELECT @agent_name = db_name() + @agent_type
  13375.     set @message  = formatmessage(20553)
  13376.     exec dbo.sp_MSrepl_raiserror @agent_type, @agent_name, 5, @message
  13377.  
  13378.     return (1)
  13379.  
  13380. GO
  13381.  
  13382. raiserror(15339,-1,-1,'sp_MSget_repl_version')
  13383. GO
  13384. CREATE PROCEDURE sp_MSget_repl_version
  13385. @major_version int = 0 OUTPUT,
  13386. @minor_version int = 0 OUTPUT,
  13387. @revision int = 0 OUTPUT
  13388.  
  13389. as
  13390. SELECT @major_version = major_version,
  13391.        @minor_version = minor_version,
  13392.        @revision = revision FROM MSrepl_version
  13393. GO
  13394.  
  13395. raiserror(15339,-1,-1,'sp_MSenum_subscriptions')
  13396. GO
  13397. create procedure sp_MSenum_subscriptions
  13398. @publisher sysname,
  13399. @publisher_db sysname,
  13400. @publication sysname,
  13401. @exclude_anonymous bit = 0
  13402. as
  13403.  
  13404.     declare @subscriber sysname
  13405.     declare @subscriber_id smallint
  13406.     declare @subscriber_db sysname
  13407.     declare @subscriber_name sysname
  13408.     declare @type int
  13409.     declare @status int
  13410.     declare @distribution_agent nvarchar(100)
  13411.     declare @publisher_id smallint
  13412.     declare @independent_agent bit
  13413.     declare @offload_enabled bit
  13414.     declare @offload_server sysname 
  13415.  
  13416.     declare @start_time nvarchar(24)
  13417.     declare @time nvarchar(24)
  13418.     declare @duration int
  13419.     declare @comments nvarchar(255)
  13420.     declare @delivery_time int
  13421.     declare @delivered_transactions int
  13422.     declare @delivered_commands int
  13423.     declare @average_commands int
  13424.     declare @delivery_rate int
  13425.     declare @delivery_latency int
  13426.     declare @error_id int
  13427.     declare @publication_id int
  13428.     declare @job_id binary(16)
  13429.     declare @agent_id int
  13430.     declare @local_job bit
  13431.     declare @profile_id int
  13432.     declare @last_timestamp binary(8)
  13433.             ,@subscriber_type tinyint
  13434.  
  13435.     set nocount on
  13436.  
  13437.     select @publisher_id = srvid from master..sysservers where
  13438.        UPPER(srvname) = UPPER(@publisher)
  13439.  
  13440.     select @publication_id = publication_id from MSpublications  where 
  13441.             publisher_id = @publisher_id and
  13442.             publisher_db = @publisher_db and
  13443.             publication = @publication and
  13444.             (publication_type = 0 or publication_type = 1)
  13445.  
  13446.     create table #subscriptions (subscriber sysname NOT NULL,  status int NOT NULL, 
  13447.         subscriber_db sysname NOT NULL,
  13448.         type tinyint NOT NULL, distribution_agent nvarchar(100) NOT NULL, last_action nvarchar(255) NULL, 
  13449.         action_time nvarchar(24) NULL, start_time nvarchar(24) NULL, duration int NULL, 
  13450.         delivery_rate float NULL,
  13451.         delivery_latency int NULL, delivered_transactions int NULL, 
  13452.         delivered_commands int NULL,
  13453.         delivery_time int NULL, average_commands int NULL, 
  13454.         error_id int NULL, 
  13455.         job_id binary(16) NULL, local_job bit NULL, profile_id int NOT NULL,
  13456.         agent_id int NOT NULL, last_timestamp binary(8) NOT NULL, offload_enabled bit NOT NULL, 
  13457.         offload_server sysname NULL, subscriber_type tinyint NULL)
  13458.     
  13459.     -- This is to force all queries to return rows ordered by job_id
  13460.     -- Note: There might be dist agents left for cleaning up sub, in this case
  13461.     -- they are not in sub table and we don't want to show them
  13462.     create unique clustered index ucsubscriptions ON #subscriptions (agent_id)
  13463.     declare hC CURSOR LOCAL FAST_FORWARD FOR select id, name, subscriber_id, subscriber_db,
  13464.         job_id, local_job, subscription_type, profile_id, subscriber_name, offload_enabled,
  13465.         offload_server 
  13466.         from MSdistribution_agents a
  13467.         where exists (select * from MSsubscriptions s where
  13468.             (a.id = s.agent_id or a.anonymous_agent_id = s.agent_id) and
  13469.             s.publisher_id = @publisher_id and
  13470.             s.publisher_db = @publisher_db and
  13471.             -- For 6.x publisher, we don't know the association between the publication
  13472.             -- and subscriptions. Show every dist agent under each publication.
  13473.             (s.publication_id = @publication_id or s.publication_id = 0 ) and
  13474.             (a.subscriber_id >= 0  or a.subscriber_id is NULL)) and 
  13475.             (@exclude_anonymous = 0 or a.anonymous_agent_id is null)
  13476.         for read only
  13477.  
  13478.     -- declare hC CURSOR LOCAL FAST_FORWARD FOR select a.id, a.name, a.subscriber_id, ms.subscriber_db,
  13479.     --  a.job_id, a.local_job, ms.subscription_type, a.profile_id, a.subscriber_name
  13480.     --    from MSdistribution_agents a, master..sysservers s, MSsubscriptions ms
  13481.     --    where
  13482.     --    a.publisher_id = @publisher_id and
  13483.     --    a.publisher_db = @publisher_db and
  13484.     --  (a.publication = @publication or a.publication = 'ALL') and
  13485.     --  a.subscriber_id >= 0 and
  13486.     --  ms.publisher_db = @publisher_db and
  13487.     --  ms.publication_id = @publication_id and
  13488.     --  ms.subscriber_id = a.subscriber_id and
  13489.     --  ms.subscriber_db = a.subscriber_db and
  13490.     --  s.srvid = ms.subscriber_id
  13491.     --  for read only
  13492.  
  13493.     open hC
  13494.     fetch hC into  @agent_id, @distribution_agent, @subscriber_id, @subscriber_db,
  13495.         @job_id, @local_job, @type, @profile_id, @subscriber_name, @offload_enabled, 
  13496.         @offload_server
  13497.     while (@@fetch_status <> -1)
  13498.     begin
  13499.         /* Stuff in the values for no history case */
  13500.         select @status = 0, 
  13501.             @start_time = NULL,
  13502.             @time = NULL, @duration = NULL, @comments = NULL,
  13503.             @delivery_time = NULL, @delivered_transactions = NULL,
  13504.             @delivered_commands = NULL, @average_commands = NULL,
  13505.             @delivery_rate = NULL, @delivery_latency = NULL,
  13506.             @error_id = NULL,
  13507.             @last_timestamp = 0x00000000
  13508.  
  13509.         -- Get the status of the agent
  13510.         select @status = runstatus, 
  13511.             @start_time = convert(nvarchar(12), start_time, 112) +
  13512.                           substring(convert(nvarchar(24), start_time, 121), 11, 13),
  13513.             @time = convert(nvarchar(12), time, 112) +
  13514.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  13515.             @duration = duration, 
  13516.             @comments = comments,
  13517.             @delivery_time = 0, @delivered_transactions = delivered_transactions,
  13518.             @delivered_commands = delivered_commands, @average_commands = average_commands,
  13519.             -- Note: return average rate here !!! delivery_rate column is current rate
  13520.             @delivery_rate = delivery_rate,
  13521.             @delivery_latency = delivery_latency,
  13522.             @error_id = error_id, @last_timestamp = timestamp
  13523.             from MSdistribution_history
  13524.             where
  13525.                 agent_id = @agent_id and
  13526.                 timestamp = (select max(timestamp) from MSdistribution_history 
  13527.                     where 
  13528.                     agent_id = @agent_id)
  13529.  
  13530.         -- For anonymous subscriptions, @subscriber_name is not NULL
  13531.          if @subscriber_name is NULL
  13532.          begin
  13533.             select @subscriber = srvname from master..sysservers where srvid=@subscriber_id
  13534.             select @subscriber_type = type from MSsubscriber_info where
  13535.                 UPPER(publisher) = UPPER(@publisher) and
  13536.                 UPPER(subscriber) = UPPER(@subscriber)
  13537.          end
  13538.          else 
  13539.          begin
  13540.             select @subscriber = @subscriber_name
  13541.             select @subscriber_db = @subscriber_db + '-' + convert(nvarchar(4), @agent_id)
  13542.             -- Don't know the subscriber type for anonymous
  13543.          end
  13544.  
  13545.         insert into #subscriptions values ( @subscriber, @status, @subscriber_db,
  13546.             @type, @distribution_agent, @comments, @time, @start_time, @duration,
  13547.             @delivery_rate, @delivery_latency, @delivered_transactions, 
  13548.             @delivered_commands,  @delivery_time, @average_commands,
  13549.             @error_id, @job_id, @local_job, @profile_id, @agent_id, @last_timestamp,
  13550.             @offload_enabled, @offload_server, @subscriber_type)
  13551.  
  13552.         fetch hC into  @agent_id, @distribution_agent, @subscriber_id, @subscriber_db,
  13553.             @job_id, @local_job, @type, @profile_id, @subscriber_name, @offload_enabled,
  13554.             @offload_server
  13555.       end
  13556.  
  13557.     select * from #subscriptions order by job_id asc 
  13558.  
  13559.     drop table #subscriptions
  13560.     close hC
  13561.     deallocate hC
  13562. go
  13563.  
  13564.  
  13565. raiserror(15339,-1,-1,'sp_MSIfExistsSubscription')
  13566. GO
  13567. create procedure sp_MSIfExistsSubscription
  13568. @publisher sysname,
  13569. @publisher_db sysname,
  13570. @publication sysname,
  13571. @type int /* replication type, 1 - transactional/snapshot, 2 - merge */
  13572. as
  13573.     declare @publisher_id smallint
  13574.     declare @publication_id int
  13575.  
  13576.     if @type not in (1,2)
  13577.     begin
  13578.         RAISERROR(21055, 16, -1, '@type','sp_MSIfExistsSubscription')
  13579.         RETURN (1)
  13580.     end
  13581.  
  13582.     set nocount on
  13583.  
  13584.     select @publisher_id = srvid from master..sysservers where
  13585.        UPPER(srvname) = UPPER(@publisher)
  13586.  
  13587.     if @type = 1
  13588.     begin
  13589.         select @publication_id = publication_id from MSpublications  where 
  13590.                 publisher_id = @publisher_id and
  13591.                 publisher_db = @publisher_db and
  13592.                 publication = @publication and
  13593.                 (publication_type = 0 or publication_type = 1)
  13594.     
  13595.         select TOP 1 1 from MSdistribution_agents a
  13596.             where exists (select * from MSsubscriptions s where
  13597.                 (a.id = s.agent_id or a.anonymous_agent_id = s.agent_id) and
  13598.                 s.publisher_id = @publisher_id and
  13599.                 s.publisher_db = @publisher_db and
  13600.                 -- For 6.x publisher, we don't know the association between the publication
  13601.                 -- and subscriptions. Show every dist agent under each publication.
  13602.                 (s.publication_id = @publication_id or s.publication_id = 0 ) and
  13603.                 (a.subscriber_id >= 0  or a.subscriber_id is NULL))
  13604.     end
  13605.     else
  13606.     begin
  13607.         select @publication_id = publication_id from MSpublications  where 
  13608.                 publisher_id = @publisher_id and
  13609.                 publisher_db = @publisher_db and
  13610.                 publication = @publication and
  13611.                 publication_type = 2 -- Merge 
  13612.     
  13613.         select TOP 1 1 from MSmerge_agents 
  13614.             where publisher_id = @publisher_id and 
  13615.                 publisher_db = @publisher_db and 
  13616.                 publication = @publication
  13617.     end
  13618. go
  13619.  
  13620.  
  13621. raiserror(15339,-1,-1,'sp_MSenum_snapshot')
  13622. go
  13623. create procedure sp_MSenum_snapshot
  13624. @name nvarchar(100) = '%',
  13625. @show_distdb bit = 0
  13626. as
  13627.     set nocount on
  13628.  
  13629.     declare @publisher sysname
  13630.     declare @publisher_db sysname
  13631.     declare @publication sysname
  13632.     declare @publication_id int
  13633.     declare @snapshot_agent nvarchar(100)
  13634.     declare @status int
  13635.     declare @start_time nvarchar(24)
  13636.     declare @time nvarchar(24)
  13637.     declare @duration int
  13638.     declare @comments nvarchar(255)
  13639.     declare @delivered_transactions int
  13640.     declare @delivered_commands int
  13641.     declare @delivery_rate int
  13642.     declare @publisher_id smallint
  13643.     declare @error_id int
  13644.     declare @job_id binary(16)
  13645.     declare @local_job bit
  13646.     declare @profile_id int
  13647.     declare @agent_id int
  13648.     declare @last_timestamp binary(8)
  13649.  
  13650.  
  13651.     create table #snapshot_agent (name nvarchar(100) NOT NULL, status int NOT NULL,
  13652.         publisher sysname NOT NULL, publisher_db sysname NOT NULL, publication sysname NOT NULL,
  13653.         start_time nvarchar(24)  NULL, time nvarchar(24)  NULL, duration int NULL, 
  13654.         comments nvarchar(255) NULL, delivered_transactions int NULL, delivered_commands int NULL,
  13655.         delivery_rate float  NULL, error_id int NULL, job_id binary(16) NULL, local_job bit NOT NULL,
  13656.         profile_id int NOT NULL, agent_id int NOT NULL, last_timestamp binary(8) NOT NULL)
  13657.   
  13658.  
  13659.     declare hC  CURSOR LOCAL FAST_FORWARD FOR
  13660.          select srvname, sa.publisher_db, sa.publication, sa.name, sa.publisher_id,
  13661.             sa.local_job, sa.job_id, sa.profile_id, sa.id
  13662.             from
  13663.             MSsnapshot_agents sa, master..sysservers
  13664.             where 
  13665.             name LIKE @name and
  13666.             srvid = sa.publisher_id
  13667.         for read only
  13668.  
  13669.     OPEN hC
  13670.     FETCH hC INTO @publisher, @publisher_db, @publication, @snapshot_agent, @publisher_id,
  13671.         @local_job, @job_id, @profile_id, @agent_id
  13672.     WHILE (@@fetch_status <> -1)
  13673.         begin
  13674.      
  13675.         -- Get the publication id
  13676.         select @publication_id = isnull(publication_id, 0) from MSpublications where
  13677.             publisher_id = @publisher_id and
  13678.             publisher_db = @publisher_db and
  13679.             publication = @publication
  13680.             
  13681.         -- Stuff in the values for no history case 
  13682.         select @status = 0, 
  13683.             @start_time = NULL,
  13684.             @time = NULL, @duration = NULL, @comments = NULL,
  13685.             @delivered_commands = NULL, 
  13686.             @delivery_rate = NULL, 
  13687.             @error_id = NULL,
  13688.             @last_timestamp = 0x00000000        
  13689.        
  13690.         -- Get the status of the agent
  13691.         select @status = runstatus, 
  13692.             @start_time = convert(nvarchar(12), start_time, 112) + 
  13693.                           substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  13694.             @time = convert(nvarchar(12), time, 112) + 
  13695.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  13696.             @duration = duration, 
  13697.             @comments = comments,
  13698.             @delivered_transactions = delivered_transactions,
  13699.             @delivered_commands = delivered_commands,
  13700.             @delivery_rate = delivery_rate, 
  13701.             @error_id = error_id, 
  13702.             @last_timestamp = timestamp
  13703.             from MSsnapshot_history
  13704.             where
  13705.             agent_id = @agent_id and
  13706.             timestamp = (select top 1 timestamp from MSsnapshot_history where           
  13707.                 agent_id = @agent_id
  13708.                 order by timestamp DESC) 
  13709.     
  13710.         insert into #snapshot_agent values (@snapshot_agent, @status, @publisher,
  13711.             @publisher_db, @publication, @start_time, @time, @duration, @comments,
  13712.             @delivered_transactions, @delivered_commands, @delivery_rate, @error_id, @job_id, 
  13713.             @local_job, @profile_id, @agent_id, @last_timestamp)
  13714.  
  13715.         FETCH hC INTO @publisher, @publisher_db, @publication, @snapshot_agent,
  13716.             @publisher_id, @local_job, @job_id, @profile_id, @agent_id
  13717.         end
  13718.  
  13719.     if @show_distdb = 0
  13720.         select * from #snapshot_agent 
  13721.     else 
  13722.         select 'dbname' = DB_NAME(), * from #snapshot_agent
  13723.  
  13724.     drop table #snapshot_agent
  13725.     close hC
  13726.     deallocate hC
  13727.  
  13728. GO
  13729.  
  13730. raiserror(15339,-1,-1,'sp_MSenum_snapshot_s')
  13731. go
  13732. create procedure sp_MSenum_snapshot_s
  13733. @name nvarchar(100),
  13734. @hours int = 0, /* @hours < 0 will return TOP 100 */
  13735. @session_type int = 1 /* Return all sessions */
  13736. as
  13737.     set nocount on
  13738.  
  13739.     declare @agent_id int
  13740.     declare @succeed int
  13741.     declare @retry int
  13742.     declare @failure int
  13743.     declare @min_time datetime
  13744.     declare @independent_agent bit
  13745.     declare @publisher_id smallint
  13746.     declare @publisher_db sysname
  13747.     declare @publication sysname
  13748.     declare @start_agent_comment nvarchar(100)
  13749.     declare @initializing int
  13750.     declare @latest_session_timestamps table (timestamp binary(8) primary key, action_count int)
  13751.  
  13752.     /* 
  13753.     ** Status const defined in sqlrepl.h 
  13754.     */
  13755.     select @succeed = 2
  13756.     select @retry = 5
  13757.     select @failure = 6
  13758.     select @initializing = 1
  13759.     select @start_agent_comment = formatmessage(20529)
  13760.  
  13761.  
  13762.     SELECT @publisher_id = publisher_id, @publisher_db = publisher_db, 
  13763.         @publication = publication, @agent_id = id
  13764.         from
  13765.         MSsnapshot_agents 
  13766.         where 
  13767.         name = @name 
  13768.  
  13769.     insert into @latest_session_timestamps 
  13770.         select max(timestamp), count(*)
  13771.           from MSsnapshot_history
  13772.          where (runstatus <> @initializing or
  13773.                 comments <> @start_agent_comment) 
  13774.       group by agent_id, start_time
  13775.         having agent_id = @agent_id
  13776.  
  13777.     /* Get date starting point */
  13778.     IF @hours < 0
  13779.     BEGIN
  13780.         select top 100 sh1.runstatus, 
  13781.             'start_time' = convert(nvarchar(12), sh1.start_time, 112) + 
  13782.                            substring(convert(nvarchar(24), sh1.start_time, 121), 11, 13), 
  13783.             'time' = convert(nvarchar(12), sh1.time, 112) + 
  13784.                      substring(convert(nvarchar(24), sh1.time, 121), 11, 13), 
  13785.             sh1.comments, sh1.duration,
  13786.             sh1.delivery_rate, sh1.delivered_commands,
  13787.             'action_count' = lst.action_count,
  13788.             sh1.error_id
  13789.             from MSsnapshot_history sh1
  13790.             inner join @latest_session_timestamps lst
  13791.             on sh1.timestamp = lst.timestamp
  13792.             where
  13793.             sh1.agent_id = @agent_id and
  13794.             ((@session_type = 1)  or
  13795.             sh1.runstatus = @failure) 
  13796.             order by sh1.timestamp desc
  13797.     END
  13798.     ELSE
  13799.     BEGIN
  13800.         IF @hours = 0
  13801.         BEGIN
  13802.             select @min_time = NULL
  13803.         END
  13804.         ELSE
  13805.         BEGIN
  13806.             select @min_time = dateadd(hour, -@hours, getdate())
  13807.         END
  13808.         select sh1.runstatus, 
  13809.             'start_time' = convert(nvarchar(12), sh1.start_time, 112) + 
  13810.                            substring(convert(nvarchar(24), sh1.start_time, 121), 11, 13), 
  13811.             'time' = convert(nvarchar(12), sh1.time, 112) + 
  13812.                      substring(convert(nvarchar(24), sh1.time, 121), 11, 13), 
  13813.             sh1.comments, sh1.duration,
  13814.             sh1.delivery_rate, sh1.delivered_commands,
  13815.             'action_count' = lst.action_count,
  13816.             sh1.error_id
  13817.             from MSsnapshot_history sh1
  13818.             inner join @latest_session_timestamps lst
  13819.             on sh1.timestamp = lst.timestamp
  13820.             where
  13821.             sh1.agent_id = @agent_id and
  13822.             ((@session_type = 1)  or
  13823.             sh1.runstatus = @failure) and
  13824.             (sh1.time >= @min_time OR @min_time IS NULL)
  13825.             order by sh1.timestamp desc
  13826.     END
  13827.  
  13828. GO
  13829.  
  13830.  
  13831. raiserror(15339,-1,-1,'sp_MSenum_snapshot_sd')
  13832. go
  13833. create procedure sp_MSenum_snapshot_sd
  13834. @name nvarchar(100),
  13835. @time datetime = NULL
  13836. as
  13837.     set nocount on
  13838.  
  13839.     declare @start_time datetime
  13840.     declare @time_up datetime
  13841.     declare @publisher_id smallint
  13842.     declare @publisher_db sysname
  13843.     declare @publication sysname
  13844.  
  13845.     IF @time IS NULL
  13846.         select @time = GETDATE()
  13847.     /* 
  13848.     ** If @name is given, get its publisher and subscriber pair
  13849.     ** Note: param will be overwritten
  13850.     ** If @name is NOT given, use provided param.
  13851.     */
  13852.     SELECT @publisher_id = pub.publisher_id, @publisher_db = pub.publisher_db, 
  13853.         @publication = pub.publication
  13854.         from
  13855.         MSsnapshot_agents agent, MSpublications pub
  13856.         where 
  13857.         name LIKE @name and
  13858.         agent.publisher_id = pub.publisher_id and
  13859.         agent.publication = pub.publication and
  13860.         agent.publisher_db = pub.publisher_db
  13861.     
  13862.     /*
  13863.     ** Minute-approximate @time can be used.
  13864.     **
  13865.     ** Note: The select only return datetime data with minute precisio
  13866.     */
  13867.     IF  DATEPART(second, @time) = 0 AND
  13868.         DATEPART(millisecond, @time) = 0
  13869.     BEGIN
  13870.         SELECT @time_up = DATEADD(second, +59, @time)
  13871.         SELECT @time_up = DATEADD(millisecond, +999, @time)
  13872.     END
  13873.     ELSE
  13874.         SELECT @time_up = @time
  13875.         
  13876.  
  13877.     select top 1 @start_time = sh.start_time            
  13878.          from MSsnapshot_history sh, MSsnapshot_agents sa
  13879.         where
  13880.         sa.publisher_id = @publisher_id and
  13881.         sa.publisher_db = @publisher_db and
  13882.         sa.publication  = @publication and
  13883.         sh.agent_id = sa.id and
  13884.         sh.time <= @time_up 
  13885.         order by sh.timestamp DESC
  13886.  
  13887.     select sh.runstatus, 
  13888.         'time' = convert(nvarchar(12), sh.time, 112) + 
  13889.                  substring(convert(nvarchar(24), sh.time, 121), 11, 13), 
  13890.         sh.comments, 
  13891.         sh.duration, 
  13892.         sh.delivery_rate, 
  13893.         sh.delivered_commands,
  13894.         sa.name, 
  13895.         sh.error_id         
  13896.         from MSsnapshot_history sh, MSsnapshot_agents sa
  13897.         where
  13898.         sa.publisher_id = @publisher_id and
  13899.         sa.publisher_db = @publisher_db and
  13900.         sa.publication = @publication and 
  13901.         sh.agent_id = sa.id and
  13902.         sh.start_time = @start_time 
  13903.         order by sh.timestamp desc
  13904. GO
  13905.  
  13906.  
  13907. raiserror(15339,-1,-1,'sp_MSenum_logreader')
  13908. go
  13909. create procedure sp_MSenum_logreader
  13910. @name nvarchar(100) = '%',
  13911. @show_distdb bit = 0
  13912. as
  13913.     set nocount on
  13914.  
  13915.     declare @publisher sysname
  13916.     declare @publisher_db sysname
  13917.     declare @logreader_agent nvarchar(100)
  13918.     declare @status int
  13919.     declare @start_time nvarchar(24)
  13920.     declare @time nvarchar(24)
  13921.     declare @duration int
  13922.     declare @comments nvarchar(255)
  13923.     declare @delivery_time int
  13924.     declare @delivered_transactions int
  13925.     declare @delivered_commands int
  13926.     declare @average_commands int
  13927.     declare @delivery_rate int
  13928.     declare @delivery_latency int
  13929.     declare @error_id int
  13930.     declare @job_id binary(16)
  13931.     declare @local_job bit
  13932.     declare @profile_id int
  13933.     declare @agent_id int
  13934.     declare @last_timestamp binary(8)
  13935.  
  13936.  
  13937.     create table #logreader_agent (name nvarchar(100) NOT NULL, status int NOT NULL,
  13938.         publisher sysname NOT NULL, publisher_db sysname NOT NULL,
  13939.         start_time nvarchar(24)  NULL, time nvarchar(24)  NULL, duration int  NULL, 
  13940.         comments nvarchar(255) NULL, delivery_time int NULL, 
  13941.         delivered_transactions int  NULL, delivered_commands int NULL, 
  13942.         average_commands int  NULL, delivery_rate int NULL, 
  13943.         delivery_latency int NULL, error_id int NULL, job_id binary(16) NULL,
  13944.         local_job bit NULL, profile_id int NOT NULL, agent_id int NOT NULL, last_timestamp binary(8) NOT NULL)  
  13945.    
  13946.     declare hC  CURSOR LOCAL FAST_FORWARD FOR
  13947.          select server.srvname, agent.publisher_db, name, 
  13948.             local_job, job_id, agent.profile_id, agent.id
  13949.             from
  13950.             MSlogreader_agents agent, master..sysservers server
  13951.             where 
  13952.             name LIKE @name and
  13953.             server.srvid = agent.publisher_id
  13954.         
  13955.         for read only
  13956.  
  13957.     OPEN hC
  13958.     FETCH hC INTO @publisher, @publisher_db, @logreader_agent, 
  13959.         @local_job, @job_id, @profile_id, @agent_id
  13960.     WHILE (@@fetch_status <> -1)
  13961.         begin
  13962.  
  13963.         /* Stuff in the values for no history case */
  13964.         select @status = 0, 
  13965.             @start_time = NULL,
  13966.             @time = NULL, @duration = NULL, @comments = NULL,
  13967.             @delivery_time = NULL, @delivered_transactions = NULL,
  13968.             @delivered_commands = NULL, @average_commands = NULL,
  13969.             @delivery_rate = NULL, @delivery_latency = NULL,
  13970.             @error_id = NULL,
  13971.             @last_timestamp = 0x00000000
  13972.  
  13973.         -- Get the status of the agent
  13974.         select @status = lh.runstatus, 
  13975.             @start_time = convert(nvarchar(12), start_time, 112) +
  13976.                           substring(convert(nvarchar(24), start_time, 121), 11, 13),
  13977.             @time = convert(nvarchar(12), time, 112) +
  13978.                     substring(convert(nvarchar(24),  time, 121), 11, 13), 
  13979.             @duration = duration, 
  13980.             @comments = comments,
  13981.             @delivery_time = delivery_time, @delivered_transactions = delivered_transactions,
  13982.             @delivered_commands = delivered_commands, @average_commands = average_commands,
  13983.             @delivery_rate = delivery_rate, @delivery_latency = delivery_latency,
  13984.             @error_id = error_id, @last_timestamp = timestamp
  13985.             from MSlogreader_history lh
  13986.             where
  13987.             lh.agent_id = @agent_id and
  13988.             lh.timestamp = (select max(timestamp) from MSlogreader_history
  13989.                 where
  13990.                 agent_id = lh.agent_id)
  13991.  
  13992.         insert into #logreader_agent values (@logreader_agent, @status, @publisher,
  13993.             @publisher_db, @start_time, @time, @duration, @comments,
  13994.             @delivery_time, @delivered_transactions, @delivered_commands, @average_commands,
  13995.             @delivery_rate, @delivery_latency, @error_id, @job_id, @local_job,
  13996.             @profile_id, @agent_id, @last_timestamp)
  13997.  
  13998.         FETCH hC INTO @publisher, @publisher_db, @logreader_agent, 
  13999.             @local_job, @job_id, @profile_id, @agent_id
  14000.         end
  14001.  
  14002.     if @show_distdb = 0
  14003.         select * from #logreader_agent 
  14004.     else 
  14005.         select 'dbname' = DB_NAME(), * from #logreader_agent
  14006.  
  14007.     drop table #logreader_agent
  14008.     close hC
  14009.     deallocate hC
  14010. GO
  14011.  
  14012.  
  14013. raiserror(15339,-1,-1,'sp_MSenum_logreader_s')
  14014. go
  14015.  
  14016. create procedure sp_MSenum_logreader_s
  14017. @name nvarchar(100),
  14018. @hours int = 0, /* @hours < 0 will return TOP 100 */
  14019. @session_type int = 1 /* Return all sessions */
  14020. as
  14021.     set nocount on
  14022.  
  14023.     declare @succeed int
  14024.     declare @agent_id int
  14025.     declare @retry int
  14026.     declare @failure int                                 
  14027.     declare @min_time datetime
  14028.  
  14029.     if @session_type  not in (1,2)
  14030.     begin
  14031.         return(1)
  14032.     end 
  14033.  
  14034.     select @agent_id  = (select top 1 id from MSlogreader_agents where name = @name) 
  14035.     /* 
  14036.     ** Status const defined in sqlrepl.h 
  14037.     */
  14038.     select @succeed = 2
  14039.     select @retry = 5
  14040.     select @failure = 6
  14041.  
  14042.     /* Get date starting point */
  14043.     IF @hours < 0
  14044.     BEGIN
  14045.         select top 100 runstatus, 
  14046.                 'start_time' = convert(nvarchar(12), start_time, 112) + 
  14047.                                substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  14048.                 'time' = convert(nvarchar(12), time, 112) +
  14049.                          substring(convert(nvarchar(24), time, 121), 11, 13), 
  14050.                 comments, duration, delivery_rate, delivery_latency,
  14051.             delivery_time,  delivered_transactions, delivered_commands, average_commands, 
  14052.             'action_count' = (select count(*) from MSlogreader_history where
  14053.                 start_time = rh.start_time and agent_id=@agent_id),
  14054.             error_id
  14055.             from MSlogreader_history rh
  14056.             where
  14057.             rh.agent_id = @agent_id and
  14058.             ((@session_type = 1 and (runstatus = @succeed or
  14059.                 runstatus = @retry or
  14060.                 timestamp = (select max(timestamp) from MSlogreader_history rh2 where
  14061.                     rh2.agent_id = rh.agent_id))) or
  14062.             runstatus = @failure) 
  14063.             order by timestamp desc
  14064.     END
  14065.     ELSE
  14066.     BEGIN
  14067.         IF @hours = 0
  14068.         BEGIN
  14069.             select @min_time = NULL
  14070.         END
  14071.         ELSE
  14072.         BEGIN
  14073.             select @min_time = dateadd(hour, -@hours, getdate())
  14074.         END
  14075.         select  runstatus, 
  14076.                 'start_time' = convert(nvarchar(12), start_time, 112) + 
  14077.                                substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  14078.                 'time' = convert(nvarchar(12), time, 112) +
  14079.                          substring(convert(nvarchar(24), time, 121), 11, 13), 
  14080.                 comments, duration, delivery_rate, delivery_latency,
  14081.             delivery_time,  delivered_transactions, delivered_commands, average_commands, 
  14082.             'action_count' = (select count(*) from MSlogreader_history where
  14083.                 start_time = rh.start_time),
  14084.             error_id
  14085.             from MSlogreader_history rh
  14086.             where
  14087.             rh.agent_id = (select top 1 id from MSlogreader_agents where name = @name) and
  14088.             ((@session_type = 1 and (runstatus = @succeed or
  14089.                 runstatus = @retry or
  14090.                 timestamp = (select max(timestamp) from MSlogreader_history rh2 where
  14091.                     rh2.agent_id = rh.agent_id))) or
  14092.             runstatus = @failure) and
  14093.             (time >= @min_time OR @min_time IS NULL)
  14094.             order by timestamp desc
  14095.     END
  14096.  
  14097. GO
  14098.  
  14099. raiserror(15339,-1,-1,'sp_MSenum_logreader_sd')
  14100. go
  14101.  
  14102. create procedure sp_MSenum_logreader_sd
  14103. @name nvarchar(100),
  14104. @time datetime = NULL
  14105. as
  14106.     set nocount on
  14107.  
  14108.     declare @start_time datetime
  14109.     declare @time_up datetime
  14110.  
  14111.     IF @time IS NULL
  14112.         select @time = GETDATE()
  14113.     /*
  14114.     ** Minute-approximate @time can be used.
  14115.     ** Note: The select only return datetime data with minute precision
  14116.     */
  14117.     IF  DATEPART(second, @time) = 0 AND
  14118.         DATEPART(millisecond, @time) = 0
  14119.     BEGIN
  14120.         SELECT @time_up = DATEADD(second, +59, @time)
  14121.         SELECT @time_up = DATEADD(millisecond, +999, @time)
  14122.     END
  14123.     ELSE
  14124.         SELECT @time_up = @time
  14125.         
  14126.  
  14127.     select  top 1 @start_time = start_time          
  14128.          from MSlogreader_history rh
  14129.         where
  14130.         rh.agent_id = (select top 1 id from MSlogreader_agents where name = @name) and
  14131.         time <= @time_up 
  14132.         order by timestamp DESC
  14133.  
  14134.     select  runstatus, 
  14135.             'time' = convert(nvarchar(12), time, 112) +
  14136.                      substring(convert(nvarchar(24), time, 121), 11, 13), 
  14137.             comments,duration, delivery_rate, delivery_latency,
  14138.         delivery_time,  delivered_transactions, delivered_commands, average_commands, 
  14139.         error_id        
  14140.         from MSlogreader_history rh
  14141.         where
  14142.         rh.agent_id = (select top 1 id from MSlogreader_agents where name = @name) and
  14143.         start_time = @start_time 
  14144.         order by timestamp desc
  14145. GO
  14146.  
  14147. raiserror(15339,-1,-1,'sp_MSenum_qreader')
  14148. go
  14149. create procedure sp_MSenum_qreader (
  14150.     @name nvarchar(100) = '%',
  14151.     @show_distdb bit = 0)
  14152. as
  14153. begin
  14154.     set nocount on
  14155.  
  14156.     declare @agent_name nvarchar(100)
  14157.     declare @status int
  14158.     declare @start_time nvarchar(24)
  14159.     declare @time nvarchar(24)
  14160.     declare @duration int
  14161.     declare @comments nvarchar(255)
  14162.     declare @transactions_processed int
  14163.     declare @commands_processed int
  14164.     declare @average_commands int
  14165.     declare @delivery_rate int
  14166.     declare @delivery_latency int
  14167.     declare @error_id int
  14168.     declare @job_id binary(16)
  14169.     declare @agent_id int
  14170.     declare @profile_id int
  14171.     declare @last_timestamp binary(8)
  14172.     declare @first_timestamp binary(8)
  14173.  
  14174.  
  14175.     create table #qreader_agent (name nvarchar(100) NOT NULL, status int NOT NULL,
  14176.         start_time nvarchar(24) NULL, time nvarchar(24) NULL, duration int NULL,
  14177.         comments nvarchar(255) NULL, 
  14178.         transactions_processed int NULL, commands_processed int NULL, 
  14179.         average_commands int NULL, delivery_rate int NULL, delivery_latency int NULL,
  14180.         error_id INT NULL, job_id binary(16) NULL, 
  14181.         profile_id int NULL, agent_id int NOT NULL, local_timestamp binary(8) NOT NULL)
  14182.  
  14183.     declare hC CURSOR LOCAL FAST_FORWARD FOR
  14184.         select id, name, job_id, profile_id
  14185.         from MSqreader_agents 
  14186.         where name = case when ((@name = '%') or (@name is NULL)) then name else @name end
  14187.         for read only
  14188.  
  14189.     OPEN hC
  14190.     FETCH hC INTO @agent_id, @agent_name, @job_id, @profile_id
  14191.     WHILE (@@fetch_status <> -1)
  14192.     begin       
  14193.         --
  14194.         -- Initialize
  14195.         --
  14196.         select @status = 0, 
  14197.             @delivery_latency = 0
  14198.  
  14199.         --
  14200.         -- select the last timestamp
  14201.         --
  14202.         select @last_timestamp = max(timestamp) from MSqreader_history 
  14203.             where agent_id = @agent_id
  14204.  
  14205.         --
  14206.         -- select the last time the agent was started
  14207.         --
  14208.         select @first_timestamp = max(timestamp) from MSqreader_history
  14209.             where agent_id = @agent_id and runstatus = 1
  14210.             
  14211.         --
  14212.         -- Get start time, duration
  14213.         --
  14214.         select @start_time = convert(nvarchar(12), start_time, 112) +
  14215.                             substring(convert(nvarchar(24), start_time, 121), 11, 13)
  14216.         from MSqreader_history
  14217.             where agent_id = @agent_id and timestamp = @first_timestamp
  14218.             
  14219.         --
  14220.         -- Compute the transaction processed, commands processed,
  14221.         -- avg commands, delivery rate
  14222.         --
  14223.         select @transactions_processed = sum(ISNULL(transactions_processed, 0)) 
  14224.                 ,@commands_processed = sum(ISNULL(commands_processed, 0))
  14225.                 ,@average_commands =  avg(ISNULL(commands_processed, 0))
  14226.                 ,@delivery_rate = cast(avg(ISNULL(delivery_rate, 0.0)) as int)
  14227.             from MSqreader_history
  14228.             where agent_id = @agent_id 
  14229.                 and timestamp >= @first_timestamp and timestamp <= @last_timestamp
  14230.                 and transactions_processed > 0
  14231.                 
  14232.         --
  14233.         -- Get the duration, time, status, comments, error from last log
  14234.         --
  14235.         select 
  14236.             @duration = duration,
  14237.             @time = convert(nvarchar(12), time, 112) +
  14238.                             substring(convert(nvarchar(24), time, 121), 11, 13),
  14239.             @status = isnull(runstatus, 0),
  14240.             @comments = comments,
  14241.             @error_id = error_id
  14242.         from MSqreader_history
  14243.         where 
  14244.             agent_id = @agent_id and
  14245.             timestamp = @last_timestamp
  14246.             
  14247.         insert into #qreader_agent values(@agent_name, @status, @start_time, 
  14248.             @time, @duration, @comments, @transactions_processed, @commands_processed, 
  14249.             @average_commands, @delivery_rate, @delivery_latency,
  14250.             @error_id, @job_id, @profile_id, @agent_id, isnull(@last_timestamp,0x00))            
  14251.  
  14252.         FETCH hC INTO @agent_id, @agent_name, @job_id, @profile_id
  14253.     end
  14254.  
  14255.     if @show_distdb = 0
  14256.         select * from #qreader_agent 
  14257.     else 
  14258.         select 'dbname' = DB_NAME(), * from #qreader_agent
  14259.  
  14260.     drop table #qreader_agent
  14261.     close hC
  14262.     deallocate hC
  14263. end
  14264. GO
  14265.  
  14266.  
  14267. raiserror(15339,-1,-1,'sp_MSenum_qreader_s')
  14268. go
  14269. create procedure sp_MSenum_qreader_s (
  14270.     @publication_id int = 0, 
  14271.     @hours int = 0, /* @hours < 0 will return TOP 100 */
  14272.     @session_type int = 1 /* Return all sessions */
  14273. )
  14274. as
  14275. begin
  14276.     set nocount on
  14277.  
  14278.     declare @succeed int
  14279.             ,@retry int
  14280.             ,@failure int
  14281.             ,@min_time datetime
  14282.             ,@agent_id int
  14283.             ,@maxtimestamp timestamp
  14284.             ,@session_start timestamp
  14285.             ,@next_session_start timestamp
  14286.             ,@session_end timestamp
  14287.             ,@final_ts timestamp
  14288.  
  14289.             ,@status int,
  14290.             @start_time nvarchar(24), 
  14291.             @time nvarchar(24), 
  14292.             @comments nvarchar(255), 
  14293.             @duration int, 
  14294.             @delivery_rate int, 
  14295.             @delivery_latency int,
  14296.             @transactions_processed int, 
  14297.             @commands_processed int, 
  14298.             @average_commands int, 
  14299.             @action_count int, 
  14300.             @error_id int,
  14301.             @start_datetime datetime,
  14302.             @end_datetime datetime
  14303.     
  14304.     if @session_type  not in (1,2)
  14305.     begin
  14306.         return(1)
  14307.     end
  14308.     
  14309.     /* 
  14310.     ** Status const defined in sqlrepl.h 
  14311.     */
  14312.     select @succeed = 2
  14313.     select @retry = 5
  14314.     select @failure = 6
  14315.  
  14316.     -- create the table to store sessions
  14317.     create table #qreader_session (status int NOT NULL,
  14318.         start_time nvarchar(24) NOT NULL, time nvarchar(24) NOT NULL, comments nvarchar(255) NULL, 
  14319.         duration int NULL, delivery_rate int NULL, delivery_latency int NULL,
  14320.         publication_id int NULL, transactions_processed int NULL, commands_processed int NULL, 
  14321.         average_commands int NULL, action_count int NULL, error_id INT NULL, local_timestamp binary(8) NOT NULL)
  14322.         
  14323.     -- get the agent id
  14324.     select TOP 1 @agent_id = agent_id from MSqreader_history 
  14325.  
  14326.     --
  14327.     -- If Min time specified, initilialize it
  14328.     --
  14329.     IF (@hours < 1)
  14330.         select @min_time = NULL
  14331.     ELSE
  14332.         select @min_time = dateadd(hour, -@hours, getdate())
  14333.  
  14334.     -- initialize
  14335.     select @delivery_latency = 0
  14336.             ,@next_session_start = NULL
  14337.             ,@session_end = NULL
  14338.             ,@final_ts = max(timestamp) 
  14339.     from MSqreader_history
  14340.     
  14341.     -- Get the session details
  14342.     while (@session_end != @final_ts)
  14343.     begin
  14344.         --
  14345.         -- Mark the beginning of a new session
  14346.         --
  14347.         if (@next_session_start is NULL)
  14348.         begin
  14349.             select @session_start = min(timestamp) from MSqreader_history
  14350.                 where agent_id = @agent_id and runstatus = 1
  14351.         end
  14352.         else
  14353.         begin
  14354.             select @session_start = @next_session_start 
  14355.         end
  14356.  
  14357.         --
  14358.         -- update @next_session_start
  14359.         --
  14360.         select @next_session_start = ISNULL(min(timestamp), @final_ts) 
  14361.         from MSqreader_history
  14362.         where agent_id = @agent_id and timestamp > @session_start and runstatus = 1
  14363.  
  14364.         --
  14365.         -- find session end based on @next_session_start
  14366.         --
  14367.         if (@next_session_start = @final_ts)
  14368.             select @session_end = @final_ts
  14369.         else
  14370.         begin
  14371.             select @session_end = max(timestamp)
  14372.             from MSqreader_history
  14373.             where agent_id = @agent_id and
  14374.                 timestamp > @session_start and 
  14375.                 timestamp < @next_session_start
  14376.         end
  14377.         
  14378.         --
  14379.         -- get start time for this session
  14380.         --
  14381.         select @start_datetime = start_time, 
  14382.             @start_time = convert(nvarchar(12), start_time, 112) +
  14383.                         substring(convert(nvarchar(24), start_time, 121), 11, 13)
  14384.         from MSqreader_history                        
  14385.         where agent_id = @agent_id and timestamp = @session_start                        
  14386.  
  14387.         --
  14388.         -- do we need to process this session 
  14389.         --
  14390.         if (@start_time IS NULL)
  14391.         begin
  14392.             --
  14393.             -- Check if we are done with all sessions
  14394.             --
  14395.             if (@session_end = @final_ts)
  14396.                 break
  14397.             else
  14398.                 continue
  14399.         end
  14400.  
  14401.         --
  14402.         -- get status, end time, comments, error id for this session
  14403.         --
  14404.         select @status = runstatus,
  14405.             @end_datetime = time,
  14406.             @time = convert(nvarchar(12), time, 112) +
  14407.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  14408.             @comments = comments, 
  14409.             @error_id = ISNULL(error_id, 0) 
  14410.         from MSqreader_history                        
  14411.         where agent_id = @agent_id and timestamp = @session_end                        
  14412.  
  14413.         --
  14414.         -- do we need to continue this session - min time check
  14415.         --
  14416.         if ((@min_time is NOT NULL) and (@min_time > @end_datetime))
  14417.         begin
  14418.             --
  14419.             -- Check if we are done with all sessions
  14420.             --
  14421.             if (@session_end = @final_ts)
  14422.                 break
  14423.             else
  14424.                 continue
  14425.         end
  14426.  
  14427.         --
  14428.         -- get duration, action count, tran processed, cmds processed, avg cmds, etc
  14429.         -- for this session
  14430.         --
  14431.         select @duration = DATEDIFF(second, @start_datetime, @end_datetime)
  14432.         select @action_count = ISNULL(count(*), 0)
  14433.             from MSqreader_history
  14434.             where agent_id = @agent_id 
  14435.                 and timestamp >= @session_start and timestamp <= @session_end
  14436.  
  14437.         select @transactions_processed = sum(ISNULL(transactions_processed, 0)) 
  14438.                 ,@commands_processed = sum(ISNULL(commands_processed, 0))
  14439.                 ,@average_commands =  avg(ISNULL(commands_processed, 0))
  14440.                 ,@delivery_rate = cast(avg(ISNULL(delivery_rate, 0.0)) as int)
  14441.             from MSqreader_history
  14442.             where agent_id = @agent_id 
  14443.                 and timestamp >= @session_start and timestamp <= @session_end
  14444.                 and transactions_processed > 0
  14445.  
  14446.         --
  14447.         -- insert into #qreader_session
  14448.         --
  14449.         insert into    #qreader_session values(@status, @start_time, @time, @comments, 
  14450.             @duration, @delivery_rate, @delivery_latency, NULL, @transactions_processed, 
  14451.             @commands_processed, @average_commands, @action_count, @error_id, @session_end)
  14452.  
  14453.         --
  14454.         -- Check if we are done with all sessions
  14455.         --
  14456.         if (@session_end = @final_ts)
  14457.             break
  14458.     end
  14459.  
  14460.     -- return results
  14461.     
  14462.     if (@hours < 0)
  14463.         select top 100 
  14464.             status,
  14465.             start_time,
  14466.             time, 
  14467.             comments, 
  14468.             duration,
  14469.             delivery_rate,
  14470.             delivery_latency,
  14471.             publication_id,
  14472.             transactions_processed, 
  14473.             commands_processed, 
  14474.             average_commands, 
  14475.             action_count, 
  14476.             error_id
  14477.         from #qreader_session
  14478.         where (@session_type = 2 and (status = @failure)) or 
  14479.                 (@session_type = 1)
  14480.         order by local_timestamp desc
  14481.     else
  14482.         select 
  14483.             status,
  14484.             start_time,
  14485.             time, 
  14486.             comments, 
  14487.             duration,
  14488.             delivery_rate,
  14489.             delivery_latency,
  14490.             publication_id,
  14491.             transactions_processed, 
  14492.             commands_processed, 
  14493.             average_commands, 
  14494.             action_count, 
  14495.             error_id
  14496.         from #qreader_session        
  14497.         where (@session_type = 2 and (status = @failure)) or 
  14498.                 (@session_type = 1)
  14499.         order by local_timestamp desc
  14500. end
  14501. GO
  14502.  
  14503.  
  14504. raiserror(15339,-1,-1,'sp_MSenum_qreader_sd')
  14505. go
  14506. create procedure sp_MSenum_qreader_sd (
  14507.     @publication_id int = 0, 
  14508.     @time datetime = NULL)
  14509. as
  14510. begin
  14511.     set nocount on
  14512.  
  14513.     declare @time_up datetime
  14514.             ,@agent_id int
  14515.             ,@final_ts timestamp
  14516.             ,@initial_ts timestamp
  14517.             ,@session_start timestamp
  14518.             ,@next_session_start timestamp
  14519.             ,@session_end timestamp
  14520.  
  14521.     if (@publication_id = 0)
  14522.         select @publication_id = NULL
  14523.         
  14524.     IF @time IS NULL
  14525.         select @time = GETDATE()
  14526.  
  14527.     /*
  14528.     ** Minute-approximate @time can be used.
  14529.     ** Note: The select only return datetime data with minute precision
  14530.     */
  14531.     IF ( (DATEPART(second, @time) = 0) AND
  14532.             (DATEPART(millisecond, @time) = 0) )
  14533.     BEGIN
  14534.         SELECT @time_up = DATEADD(second, +59, @time)
  14535.         SELECT @time_up = DATEADD(millisecond, +999, @time)
  14536.     END
  14537.     ELSE
  14538.         SELECT @time_up = @time
  14539.  
  14540.     --
  14541.     -- Get the agent id
  14542.     --
  14543.     select TOP 1 @agent_id = agent_id from MSqreader_history 
  14544.  
  14545.     --
  14546.     -- Get the session start, next session start timestamps
  14547.     --
  14548.     select @initial_ts = min(timestamp), @final_ts = max(timestamp) from MSqreader_history
  14549.     
  14550.     select @session_start = ISNULL(max(timestamp), @initial_ts) from MSqreader_history
  14551.             where agent_id = @agent_id and time <= @time_up and runstatus = 1
  14552.             
  14553.     select @next_session_start = ISNULL(min(timestamp), @final_ts) from MSqreader_history
  14554.             where agent_id = @agent_id and timestamp > @session_start and runstatus = 1
  14555.  
  14556.     --
  14557.     -- find session end based on @next_session_start
  14558.     --
  14559.     if (@next_session_start = @final_ts)
  14560.         select @session_end = @final_ts
  14561.     else
  14562.     begin
  14563.         select @session_end = max(timestamp)
  14564.         from MSqreader_history
  14565.         where agent_id = @agent_id and
  14566.             timestamp > @session_start and 
  14567.             timestamp < @next_session_start
  14568.     end
  14569.     
  14570.     --
  14571.     -- Do the select now
  14572.     --
  14573.     select  runstatus, 
  14574.         'time' = convert(nvarchar(12), time, 112) +
  14575.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  14576.         comments, 
  14577.         transaction_id, 
  14578.         transaction_status,
  14579.         commands_processed,
  14580.         subscriber,
  14581.         subscriberdb,
  14582.         'error_id' = ISNULL(error_id, 0)
  14583.     from MSqreader_history
  14584.     where
  14585.         agent_id = @agent_id and
  14586.         timestamp >= @session_start and
  14587.         timestamp <= @session_end
  14588.     order by timestamp desc
  14589. end
  14590. GO
  14591.  
  14592. raiserror(15339,-1,-1,'sp_MSenum_distribution')
  14593. go
  14594. create procedure sp_MSenum_distribution
  14595. @name nvarchar(100) = '%',
  14596. @show_distdb bit = 0,
  14597. @exclude_anonymous bit = 0
  14598. as
  14599.     set nocount on
  14600.  
  14601.     declare @publisher sysname
  14602.     declare @publisher_id smallint
  14603.     declare @publisher_db sysname
  14604.     declare @publication sysname
  14605.     declare @subscriber sysname
  14606.     declare @subscriber_id smallint
  14607.     declare @subscriber_db sysname
  14608.     declare @subscriber_name sysname
  14609.     declare @distribution_agent nvarchar(100)
  14610.     declare @status int
  14611.     declare @start_time nvarchar(24)
  14612.     declare @time nvarchar(24)
  14613.     declare @duration int
  14614.     declare @comments nvarchar(255)
  14615.     declare @delivery_time int
  14616.     declare @delivered_transactions int
  14617.     declare @delivered_commands int
  14618.     declare @average_commands int
  14619.     declare @delivery_rate int
  14620.     declare @delivery_latency int   
  14621.     declare @subscription_type int
  14622.     declare @error_id int
  14623.     declare @job_id binary(16)
  14624.     declare @local_job bit
  14625.     declare @agent_id int
  14626.     declare @profile_id int
  14627.     declare @last_timestamp binary(8)
  14628.     declare @offload_enabled bit
  14629.     declare @offload_server  sysname
  14630.         ,@subscriber_type tinyint
  14631.  
  14632.  
  14633.     create table #distribution_agent (name nvarchar(100) NOT NULL, status int NOT NULL,
  14634.         publisher sysname NOT NULL, publisher_db sysname NOT NULL, publication sysname NULL,
  14635.         subscriber sysname NULL, subscriber_db sysname NULL,subscription_type int NULL, 
  14636.         start_time nvarchar(24) NULL, time nvarchar(24) NULL, duration int NULL, 
  14637.         comments nvarchar(255) NULL, delivery_time int NULL, 
  14638.         delivered_transactions int NULL, delivered_commands int NULL, 
  14639.         average_commands int NULL, delivery_rate int NULL, delivery_latency int NULL,
  14640.         error_id int NULL, job_id binary(16) NULL, local_job bit NOT NULL,
  14641.         profile_id int NOT NULL, agent_id int NOT NULL, last_timestamp binary(8) NOT NULL, 
  14642.         offload_enabled BIT NOT NULL, offload_server sysname NULL,
  14643.         subscriber_type tinyint NULL)
  14644.  
  14645.     /* excluding virtual subscriptions */
  14646.     declare hC CURSOR LOCAL FAST_FORWARD FOR
  14647.         select id, name, publisher_id, publisher_db, publication, 
  14648.             subscriber_id, subscriber_db, subscription_type, local_job, job_id,
  14649.             profile_id, subscriber_name, offload_enabled, offload_server
  14650.             from
  14651.             MSdistribution_agents 
  14652.             where 
  14653.             --No virtual subscription wanted
  14654.             name LIKE @name and (subscriber_id is NULL or subscriber_id>=0) and
  14655.             (@exclude_anonymous = 0 or anonymous_agent_id is null)
  14656.         for read only
  14657.  
  14658.  
  14659.     OPEN hC
  14660.     FETCH hC INTO @agent_id, @distribution_agent, @publisher_id, @publisher_db, @publication,
  14661.         @subscriber_id, @subscriber_db, @subscription_type, @local_job, @job_id, @profile_id, @subscriber_name, @offload_enabled, @offload_server
  14662.     WHILE (@@fetch_status <> -1)
  14663.         begin
  14664.         
  14665.         /* Stuff in the values for no history case */
  14666.         select @status = 0, 
  14667.             @start_time = NULL,
  14668.             @time = NULL, @duration = NULL, @comments = NULL,
  14669.             @delivery_time = NULL, @delivered_transactions = NULL,
  14670.             @delivered_commands = NULL, @average_commands = NULL,
  14671.             @delivery_rate = NULL, @delivery_latency = NULL,
  14672.             @error_id = NULL,
  14673.             @last_timestamp = 0x00000000
  14674.  
  14675.         select @status = isnull(runstatus, 0),
  14676.             @start_time = convert(nvarchar(12), start_time, 112) +
  14677.                           substring(convert(nvarchar(24), start_time, 121), 11, 13),
  14678.             @time = convert(nvarchar(12), time, 112) +
  14679.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  14680.             @duration = duration, 
  14681.             @comments = comments,
  14682.             @delivery_time = 0, @delivered_transactions = delivered_transactions,
  14683.             @delivered_commands = delivered_commands, @average_commands = average_commands,
  14684.             @delivery_rate = delivery_rate,
  14685.             @delivery_latency = delivery_latency,
  14686.             @error_id = error_id, @last_timestamp = timestamp   
  14687.             from MSdistribution_history
  14688.             where
  14689.             agent_id = @agent_id and
  14690.             timestamp = (select max(timestamp) from MSdistribution_history 
  14691.                 where agent_id = @agent_id)
  14692.             
  14693.             select @publisher = srvname from master..sysservers where srvid = @publisher_id
  14694.         IF @subscriber_name is NULL
  14695.         begin
  14696.                 select @subscriber = srvname from master..sysservers where srvid=@subscriber_id 
  14697.                 select @subscriber_type = type from MSsubscriber_info where
  14698.                     UPPER(publisher) = UPPER(@publisher) and
  14699.                     UPPER(subscriber) = UPPER(@subscriber)
  14700.  
  14701.         end
  14702.         ELSE 
  14703.             begin
  14704.                 select @subscription_type = 2
  14705.                 select @subscriber = @subscriber_name
  14706.                 select @subscriber_db = @subscriber_db + '-' + convert(nvarchar(4), @agent_id)
  14707.             end
  14708.             
  14709.         insert into #distribution_agent values (@distribution_agent,
  14710.             @status, @publisher,
  14711.             @publisher_db, @publication, @subscriber, @subscriber_db, @subscription_type, 
  14712.             @start_time, @time, @duration, @comments,
  14713.             @delivery_time, @delivered_transactions, @delivered_commands, @average_commands,
  14714.             @delivery_rate, @delivery_latency, @error_id, @job_id, 
  14715.             @local_job, @profile_id, @agent_id, @last_timestamp, @offload_enabled, 
  14716.             @offload_server, @subscriber_type)
  14717.  
  14718.         FETCH hC INTO @agent_id, @distribution_agent, @publisher_id, @publisher_db, @publication,
  14719.             @subscriber_id, @subscriber_db, @subscription_type, @local_job, @job_id, 
  14720.             @profile_id, @subscriber_name, @offload_enabled, @offload_server
  14721.         end
  14722.  
  14723.     if @show_distdb = 0
  14724.         select * from #distribution_agent 
  14725.     else 
  14726.         select 'dbname' = DB_NAME(), * from #distribution_agent
  14727.  
  14728.     drop table #distribution_agent
  14729.     close hC
  14730.     deallocate hC
  14731.  
  14732. GO
  14733.  
  14734.  
  14735. raiserror(15339,-1,-1,'sp_MSenum_distribution_s')
  14736. go
  14737. create procedure sp_MSenum_distribution_s
  14738. @name nvarchar(100), 
  14739. @hours int = 0, /* @hours < 0 will return TOP 100 */
  14740. @session_type int = 1 /* Return all sessions */
  14741. as
  14742.     set nocount on
  14743.  
  14744.     declare @succeed int
  14745.     declare @retry int
  14746.     declare @failure int
  14747.     declare @min_time datetime
  14748.     declare @agent_id int
  14749.  
  14750.     /* 
  14751.     ** Status const defined in sqlrepl.h 
  14752.     */
  14753.     select @succeed = 2
  14754.     select @retry = 5
  14755.     select @failure = 6
  14756.  
  14757.     select @agent_id = id from MSdistribution_agents where
  14758.         name = @name
  14759.  
  14760.  
  14761.     /* Get date starting point */
  14762.     IF @hours < 0
  14763.     BEGIN
  14764.         select top 100 runstatus, 
  14765.             'start_time' = convert(nvarchar(12), start_time, 112) +
  14766.                            substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  14767.             'time' = convert(nvarchar(12), time, 112) +
  14768.                      substring(convert(nvarchar(24), time, 121), 11, 13), 
  14769.             comments, duration, 
  14770.             delivery_rate,
  14771.             delivery_latency,
  14772.             0, /*delivery_time */   
  14773.             delivered_transactions, delivered_commands, average_commands, 
  14774.             'action_count' = (select count(*) from MSdistribution_history where
  14775.                 start_time = rh.start_time and agent_id = @agent_id),
  14776.             error_id
  14777.             from MSdistribution_history rh
  14778.             where
  14779.             agent_id = @agent_id and
  14780.             ((@session_type = 1 and
  14781.             (runstatus = @succeed or
  14782.             runstatus = @retry or
  14783.             timestamp = (select max(timestamp) from MSdistribution_history rh2 where
  14784.                 rh2.agent_id = @agent_id))) or 
  14785.             runstatus = @failure)
  14786.             order by timestamp desc
  14787.     END
  14788.     ELSE
  14789.     BEGIN
  14790.         IF @hours = 0
  14791.         BEGIN
  14792.             select @min_time = NULL
  14793.         END
  14794.         ELSE
  14795.         BEGIN
  14796.             select @min_time = dateadd(hour, -@hours, getdate())
  14797.         END
  14798.         select  runstatus, 
  14799.             'start_time' = convert(nvarchar(12), start_time, 112) +
  14800.                            substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  14801.             'time' = convert(nvarchar(12), time, 112) +
  14802.                      substring(convert(nvarchar(24), time, 121), 11, 13), 
  14803.             comments, duration, 
  14804.             delivery_rate,
  14805.             delivery_latency,
  14806.             0, /*delivery_time */   
  14807.             delivered_transactions, delivered_commands, average_commands, 
  14808.             'action_count' = (select count(*) from MSdistribution_history where
  14809.                 start_time = rh.start_time and agent_id = @agent_id),
  14810.             error_id
  14811.             from MSdistribution_history rh
  14812.             where
  14813.             agent_id = @agent_id and
  14814.             ((@session_type = 1 and
  14815.             (runstatus = @succeed or
  14816.             runstatus = @retry or
  14817.             timestamp = (select max(timestamp) from MSdistribution_history rh2 where
  14818.                 rh2.agent_id = @agent_id))) or 
  14819.             runstatus = @failure) and
  14820.             (time >= @min_time or @min_time IS NULL)
  14821.             order by timestamp desc
  14822.     END
  14823.  
  14824. GO
  14825.  
  14826.  
  14827. raiserror(15339,-1,-1,'sp_MSenum_distribution_sd')
  14828. go
  14829. create procedure sp_MSenum_distribution_sd
  14830. @name nvarchar(100),
  14831. @time datetime = NULL
  14832. as
  14833.     set nocount on
  14834.  
  14835.     declare @start_time datetime
  14836.     declare @time_up datetime
  14837.     declare @agent_id int
  14838.  
  14839.     IF @time IS NULL
  14840.         select @time = GETDATE()
  14841.     
  14842.     select @agent_id = id from MSdistribution_agents where
  14843.         name = @name
  14844.  
  14845.     /*
  14846.     ** Minute-approximate @time can be used.
  14847.     ** Note: The select only return datetime data with minute precision
  14848.     */
  14849.     IF  DATEPART(second, @time) = 0 AND
  14850.         DATEPART(millisecond, @time) = 0
  14851.     BEGIN
  14852.         SELECT @time_up = DATEADD(second, +59, @time)
  14853.         SELECT @time_up = DATEADD(millisecond, +999, @time)
  14854.     END
  14855.     ELSE
  14856.         SELECT @time_up = @time
  14857.         
  14858.  
  14859.     select top 1 @start_time = start_time           
  14860.          from MSdistribution_history rh
  14861.         where
  14862.         rh.agent_id = @agent_id and
  14863.         time <= @time_up
  14864.         order by timestamp DESC
  14865.  
  14866.     select  runstatus, 
  14867.         'time' = convert(nvarchar(12), time, 112) +
  14868.                  substring(convert(nvarchar(24), time, 121), 11, 13), 
  14869.         comments, duration, 
  14870.         delivery_rate,
  14871.         delivery_latency,
  14872.         /* delivery_time */ 0,  
  14873.         delivered_transactions, delivered_commands, average_commands, 
  14874.         error_id            
  14875.         from MSdistribution_history rh
  14876.         where
  14877.         rh.agent_id = @agent_id and
  14878.         start_time = @start_time
  14879.         order by timestamp desc
  14880. GO
  14881.  
  14882.  
  14883. raiserror(15339,-1,-1,'sp_MSadd_merge_history')
  14884. go
  14885. CREATE PROCEDURE sp_MSadd_merge_history (
  14886.     @agent_id       int,        
  14887.     @runstatus      int, 
  14888.     @comments       nvarchar(255),
  14889.     @delivery_time  int = 0,                    /* Milliseconds */
  14890.     @publisher_insertcount  int = 0,
  14891.     @publisher_updatecount  int = 0,
  14892.     @publisher_deletecount  int = 0,
  14893.     @publisher_conflictcount int = 0,
  14894.     @subscriber_insertcount int = 0,
  14895.     @subscriber_updatecount int = 0,
  14896.     @subscriber_deletecount int = 0,
  14897.     @subscriber_conflictcount int = 0,
  14898.     @log_error bit = 0,
  14899.     @perfmon_increment bit = 1,
  14900.     @update_existing_row bit = 0,
  14901.     @updateable_row bit = 1,     -- used to override history verbose level to decide
  14902.                     -- whether the row being added can be updated by another.    
  14903.     @do_raiserror bit = 1
  14904. )
  14905. AS
  14906. BEGIN
  14907.  
  14908.     DECLARE @current_time datetime
  14909.             ,@start_time datetime
  14910.             ,@duration int
  14911.             ,@delivery_rate float
  14912.             ,@perfmon_delivery_rate int
  14913.             ,@perfmon_conflict_count int
  14914.             ,@delivered_rows int
  14915.             ,@changes int
  14916.             ,@delivery_time_old  int
  14917.             ,@delivered_rows_old int
  14918.             ,@publisher_insertcount_old  int 
  14919.             ,@publisher_updatecount_old  int 
  14920.             ,@publisher_deletecount_old  int 
  14921.             ,@publisher_conflictcount_old int 
  14922.             ,@subscriber_insertcount_old int 
  14923.             ,@subscriber_updatecount_old int 
  14924.             ,@subscriber_deletecount_old int 
  14925.             ,@subscriber_conflictcount_old int 
  14926.             ,@publisher_id smallint
  14927.             ,@subscriber_id smallint
  14928.             ,@error_id int 
  14929.             ,@startup int
  14930.             ,@succeed int
  14931.             ,@retry int
  14932.             ,@inprogress int
  14933.             ,@failure int
  14934.             ,@idle int
  14935.             ,@lastrow_timestamp timestamp
  14936.             ,@agent_name nvarchar(100)
  14937.             ,@publisher sysname
  14938.             ,@publisher_db sysname
  14939.             ,@publication sysname
  14940.             ,@retcode int
  14941.             ,@existing_row_updateble bit
  14942.             ,@this_row_updateable bit
  14943.             ,@agentclassname sysname
  14944.  
  14945.     /* 
  14946.     ** Status const defined in sqlrepl.h 
  14947.     */
  14948.     select @startup = 1
  14949.             ,@succeed = 2
  14950.             ,@inprogress = 3
  14951.             ,@idle = 4
  14952.             ,@retry = 5
  14953.             ,@failure = 6
  14954.             ,@delivery_time_old  = 0
  14955.             ,@publisher_insertcount_old   = 0
  14956.             ,@publisher_updatecount_old   = 0
  14957.             ,@publisher_deletecount_old   = 0
  14958.             ,@publisher_conflictcount_old  = 0
  14959.             ,@subscriber_insertcount_old  = 0
  14960.             ,@subscriber_updatecount_old  = 0
  14961.             ,@subscriber_deletecount_old  = 0
  14962.             ,@subscriber_conflictcount_old  = 0
  14963.             ,@existing_row_updateble = 1
  14964.             ,@this_row_updateable = 1
  14965.  
  14966.     if (@updateable_row = 0)
  14967.     begin
  14968.         select @this_row_updateable = 0
  14969.     end
  14970.  
  14971.     if sessionproperty('replication_agent') = 0
  14972.     begin
  14973.         -- Security Check
  14974.         exec @retcode = dbo.sp_MScheck_pull_access
  14975.             @agent_id = @agent_id,
  14976.             @agent_type = 1 -- merge agent
  14977.         if @@error <> 0 or @retcode <> 0
  14978.             return (1)
  14979.     end
  14980.  
  14981.     SELECT @current_time = GETDATE()
  14982.  
  14983.     -- Update Perfmon counter
  14984.     if @perfmon_increment = 1
  14985.     begin
  14986.         if @runstatus = @startup
  14987.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Merge", 1)
  14988.         else if (@runstatus = @succeed or @runstatus = @retry or @runstatus = @failure)
  14989.             dbcc incrementinstance ("SQL Replication Agents", "Running", "Merge", -1)
  14990.     end
  14991.  
  14992.     SELECT @agent_name = name, @publisher_id = publisher_id, @publisher_db = publisher_db, 
  14993.         @publication = publication from MSmerge_agents where id = @agent_id
  14994.     SELECT @publisher = srvname from master..sysservers where srvid = @publisher_id
  14995.  
  14996.     IF @runstatus = @inprogress or @runstatus = @idle
  14997.         BEGIN
  14998.             SELECT TOP 1 @start_time = start_time, 
  14999.                     @lastrow_timestamp = timestamp,
  15000.                     @publisher_insertcount_old = publisher_insertcount ,
  15001.                     @publisher_updatecount_old = publisher_updatecount, 
  15002.                     @publisher_deletecount_old = publisher_deletecount,
  15003.                     @publisher_conflictcount_old = publisher_conflictcount,
  15004.                     @subscriber_insertcount_old = subscriber_insertcount, 
  15005.                     @subscriber_updatecount_old = subscriber_updatecount,
  15006.                     @subscriber_deletecount_old = subscriber_deletecount,
  15007.                     @subscriber_conflictcount_old = subscriber_conflictcount,
  15008.                     @delivery_time_old = delivery_time,
  15009.                     @existing_row_updateble = updateable_row
  15010.             FROM MSmerge_history (rowlock)
  15011.             WHERE  agent_id = @agent_id ORDER BY timestamp DESC
  15012.         
  15013.             select @delivered_rows_old = @publisher_insertcount_old + 
  15014.                              @publisher_updatecount_old +
  15015.                              @publisher_deletecount_old +
  15016.                              @subscriber_updatecount_old +
  15017.                              @subscriber_insertcount_old +
  15018.                              @subscriber_deletecount_old 
  15019.         END
  15020.     ELSE IF @runstatus <> 1 --1 is the Start status
  15021.         BEGIN
  15022.             SELECT TOP 1 @start_time = start_time, 
  15023.                         @lastrow_timestamp = timestamp
  15024.             FROM MSmerge_history (rowlock)
  15025.             WHERE  agent_id = @agent_id ORDER BY timestamp DESC
  15026.         END
  15027.     ELSE
  15028.         BEGIN
  15029.             SELECT @start_time = @current_time
  15030.         END
  15031.  
  15032.     /* Use the current time if no corresponding start_up message logged */
  15033.     IF @start_time IS NULL
  15034.        SELECT @start_time = @current_time
  15035.  
  15036.     /* Calculate agent run duration */
  15037.     SELECT @duration = DATEDIFF(second, @start_time, @current_time) 
  15038.                              
  15039.     select @delivered_rows = @publisher_insertcount + 
  15040.                              @publisher_updatecount +
  15041.                              @publisher_deletecount +
  15042.                              @subscriber_updatecount +
  15043.                              @subscriber_insertcount +
  15044.                              @subscriber_deletecount 
  15045.  
  15046.     -- Set Perfmon counters
  15047.     if @runstatus = @idle or @runstatus = @inprogress
  15048.     begin
  15049.         dbcc addinstance ("SQL Replication Merge", @agent_name)
  15050.  
  15051.         set @changes = @publisher_insertcount + @publisher_updatecount + @publisher_deletecount                             
  15052.         dbcc incrementinstance ("SQL Replication Merge", "Downloaded Changes/sec", @agent_name, @changes)
  15053.  
  15054.         set @changes = @subscriber_updatecount + @subscriber_insertcount + @subscriber_deletecount 
  15055.         dbcc incrementinstance ("SQL Replication Merge", "Uploaded Changes/sec", @agent_name, @changes)
  15056.  
  15057.         set @perfmon_conflict_count = @publisher_conflictcount + @subscriber_conflictcount
  15058.         dbcc incrementinstance ("SQL Replication Merge", "Conflicts/sec", @agent_name, @perfmon_conflict_count)
  15059.     end
  15060.  
  15061.     if @runstatus = @inprogress  or @runstatus = @idle            -- if it is in progress, then do incremental change
  15062.     begin
  15063.         select @publisher_insertcount = @publisher_insertcount_old + @publisher_insertcount
  15064.         select      @publisher_updatecount = @publisher_updatecount_old + @publisher_updatecount
  15065.         select      @publisher_deletecount = @publisher_deletecount_old + @publisher_deletecount
  15066.         select      @publisher_conflictcount = @publisher_conflictcount_old + @publisher_conflictcount
  15067.         select      @subscriber_insertcount = @subscriber_insertcount_old + @subscriber_insertcount
  15068.         select     @subscriber_updatecount = @subscriber_updatecount_old + @subscriber_updatecount
  15069.         select     @subscriber_deletecount = @subscriber_deletecount_old + @subscriber_deletecount
  15070.         select     @subscriber_conflictcount = @subscriber_conflictcount_old + @subscriber_conflictcount
  15071.  
  15072.         select  @delivery_time = @delivery_time_old + @delivery_time
  15073.         select @delivered_rows = @delivered_rows + @delivered_rows_old
  15074.     end
  15075.     
  15076.     IF @duration <> 0 
  15077.        SELECT @delivery_rate = (@delivered_rows * 1.0) / @duration
  15078.     ELSE
  15079.        SELECT @delivery_rate = 0
  15080.  
  15081.     /* 
  15082.     ** Set error id to 0 unless the user want to log errors associate with this 
  15083.     ** history message.
  15084.     */
  15085.     SELECT @error_id = 0
  15086.     IF @log_error = 1
  15087.     BEGIN
  15088.         -- Ignore errors here. @error_id will be set to 0 in case of errors  
  15089.         EXEC dbo.sp_MSget_new_errorid @error_id OUTPUT
  15090.     END
  15091.  
  15092.     -- Insert idle record or update if history record is already 'idle'
  15093.     IF (@existing_row_updateble = 1) and (@runstatus = @idle or @update_existing_row = 1)
  15094.     begin
  15095.         -- Attempt to update the last row if it is IDLE
  15096.         UPDATE MSmerge_history SET runstatus = @runstatus, time = @current_time, duration = @duration,
  15097.             comments = @comments,
  15098.             delivery_time = @delivery_time, 
  15099.             delivery_rate = @delivery_rate, 
  15100.             publisher_insertcount = @publisher_insertcount,
  15101.             publisher_updatecount = @publisher_updatecount,
  15102.             publisher_deletecount = @publisher_deletecount,
  15103.             publisher_conflictcount = @publisher_conflictcount,
  15104.             subscriber_insertcount = @subscriber_insertcount,
  15105.             subscriber_updatecount = @subscriber_updatecount,
  15106.             subscriber_deletecount = @subscriber_deletecount,
  15107.             subscriber_conflictcount = @subscriber_conflictcount,
  15108.             updateable_row = @this_row_updateable,
  15109.             error_id = case @error_id when 0 then error_id else @error_id end    
  15110.             WHERE
  15111.             agent_id = @agent_id and
  15112.             timestamp = @lastrow_timestamp and
  15113.             (runstatus = @runstatus or 
  15114.             (@update_existing_row = 1 and runstatus in (@idle, @inprogress) and @runstatus in (@idle, @inprogress)))
  15115.  
  15116.         -- Insert idle record if there is not one
  15117.         if @@ROWCOUNT = 0
  15118.             INSERT INTO MSmerge_history
  15119.             (
  15120.             agent_id, runstatus, start_time, time, duration, comments, delivery_time, delivery_rate, publisher_insertcount,
  15121.             publisher_updatecount, publisher_deletecount, publisher_conflictcount, subscriber_insertcount, subscriber_updatecount,
  15122.             subscriber_deletecount, subscriber_conflictcount, error_id, timestamp, updateable_row
  15123.             )
  15124.             VALUES 
  15125.             (
  15126.             @agent_id, @runstatus, @start_time, @current_time, 
  15127.             @duration, @comments,  @delivery_time, @delivery_rate, 
  15128.             @publisher_insertcount, @publisher_updatecount, @publisher_deletecount, @publisher_conflictcount, 
  15129.             @subscriber_insertcount, @subscriber_updatecount, @subscriber_deletecount, @subscriber_conflictcount, 
  15130.             @error_id, NULL, @this_row_updateable
  15131.             )
  15132.     end
  15133.     else
  15134.     begin
  15135.         INSERT INTO MSmerge_history 
  15136.         (
  15137.             agent_id, runstatus, start_time, time, duration, comments, delivery_time, delivery_rate, publisher_insertcount,
  15138.             publisher_updatecount, publisher_deletecount, publisher_conflictcount, subscriber_insertcount, subscriber_updatecount,
  15139.             subscriber_deletecount, subscriber_conflictcount, error_id, timestamp, updateable_row
  15140.         )
  15141.         VALUES 
  15142.         (
  15143.         @agent_id, @runstatus, @start_time, @current_time, 
  15144.         @duration, @comments, @delivery_time, @delivery_rate, 
  15145.         @publisher_insertcount, @publisher_updatecount, @publisher_deletecount, @publisher_conflictcount, 
  15146.         @subscriber_insertcount, @subscriber_updatecount, @subscriber_deletecount, @subscriber_conflictcount, 
  15147.         @error_id, NULL, @this_row_updateable
  15148.         )
  15149.     end
  15150.  
  15151.     -- Refresh repl monitor
  15152.     declare @agent_type int
  15153.     set @agent_type = dbo.fn_MSmask_agent_type (@agent_id, 4)
  15154.  
  15155.     -- Update global replication agent status table
  15156.     exec dbo.sp_MSupdate_replication_status 
  15157.         @publisher, 
  15158.         @publisher_db,
  15159.         @publication,
  15160.         @publication_type = 2,
  15161.         @agent_type = @agent_type,
  15162.         @agent_name = @agent_name,
  15163.         @status = @runstatus
  15164.  
  15165.     -- Raise the appropriate error
  15166.     if @do_raiserror = 1
  15167.     begin
  15168.         select @agentclassname = formatmessage(14554)
  15169.         exec dbo.sp_MSrepl_raiserror agentclassname, @agent_name, @runstatus, @comments
  15170.     end
  15171.  
  15172.     IF @@ERROR <> 0
  15173.         RETURN (1)
  15174.  
  15175.     RETURN (0)
  15176. END
  15177. GO   
  15178.  
  15179. raiserror(15339,-1,-1,'sp_MSenum_merge')
  15180. go
  15181. create procedure sp_MSenum_merge
  15182. @name nvarchar(100) = '%',
  15183. @show_distdb bit = 0,
  15184. @exclude_anonymous bit = 0
  15185. as
  15186.     set nocount on
  15187.  
  15188.     declare @publisher sysname
  15189.     declare @publisher_id smallint
  15190.     declare @publisher_db sysname
  15191.     declare @subscriber sysname
  15192.     declare @subscriber_id smallint
  15193.     declare @subscriber_db sysname
  15194.     declare @subscriber_name sysname
  15195.     declare @subscription_type int
  15196.     declare @publication sysname
  15197.     declare @status int
  15198.     declare @start_time nvarchar(24)
  15199.     declare @time nvarchar(24)
  15200.     declare @duration int
  15201.     declare @comments nvarchar(255)
  15202.     declare @publisher_insertcount int
  15203.     declare @publisher_updatecount int
  15204.     declare @publisher_deletecount int
  15205.     declare @publisher_conflictcount int
  15206.     declare @subscriber_insertcount int
  15207.     declare @subscriber_updatecount int
  15208.     declare @subscriber_deletecount int
  15209.     declare @subscriber_conflictcount int
  15210.     declare @delivery_rate int
  15211.     declare @agent_name nvarchar(100)
  15212.     declare @error_id int
  15213.     declare @job_id binary(16)
  15214.     declare @local_job bit
  15215.     declare @profile_id int
  15216.     declare @agent_id int
  15217.     declare @last_timestamp binary(8)
  15218.     declare @offload_enabled bit
  15219.     declare @offload_server  sysname
  15220.         ,@subscriber_type tinyint
  15221.  
  15222.  
  15223.     create table #merge_agent (name nvarchar(100) NOT NULL, status int NOT NULL,
  15224.         publisher sysname NOT NULL, publisher_db sysname NOT NULL, publication sysname NULL,
  15225.         subscriber sysname NOT NULL, subscriber_db sysname NOT NULL, subscription_type int NULL,
  15226.         start_time nvarchar(24) NULL, time nvarchar(24) NULL, duration int NULL, 
  15227.         comments nvarchar(255) NULL, delivery_rate int NULL,
  15228.         publisher_insertcount int NULL, publisher_updatecount int NULL, publisher_deletecount int NULL,
  15229.         publisher_conficts int NULL, 
  15230.         subscriber_insertcount int NULL, subscriber_updatecount int NULL, subscriber_deletecount int NULL,
  15231.         subscriber_conficts int NULL, error_id int NULL, job_id binary(16) NULL,
  15232.         local_job bit NULL, profile_id int NOT NULL, agent_id int NOT NULL, last_timestamp binary(8) NOT NULL,
  15233.         offload_enabled bit NOT NULL, offload_server sysname NULL,
  15234.         subscriber_type tinyint NULL)
  15235.  
  15236.     declare hC CURSOR LOCAL FAST_FORWARD FOR
  15237.         select p.publisher_id, a.subscriber_id, a.publisher_db, a.subscriber_db, 
  15238.             p.publication, a.name, a.local_job, a.job_id, a.profile_id, a.id, a.subscriber_name, 
  15239.             offload_enabled, offload_server
  15240.             from MSmerge_agents a, MSpublications p
  15241.             where 
  15242.             a.name LIKE @name and
  15243.             a.publisher_id = p.publisher_id and
  15244.             a.publisher_db = p.publisher_db and
  15245.             a.publication = p.publication and
  15246.             (@exclude_anonymous = 0 or a.subscriber_name is null)
  15247.  
  15248.         for read only
  15249.  
  15250.  
  15251.     OPEN hC
  15252.     FETCH hC INTO @publisher_id, @subscriber_id, @publisher_db, @subscriber_db,
  15253.         @publication, @agent_name, @local_job, @job_id, @profile_id, @agent_id, @subscriber_name, 
  15254.         @offload_enabled, @offload_server
  15255.  
  15256.     WHILE (@@fetch_status <> -1)
  15257.     begin
  15258.  
  15259.         /* Initialize the values for no history case */
  15260.         select @status = 0,
  15261.             @start_time = NULL,
  15262.             @time = NULL, 
  15263.             @duration = NULL, 
  15264.             @comments = NULL,
  15265.             @publisher_insertcount = 0,
  15266.             @publisher_deletecount = 0,
  15267.             @publisher_updatecount = 0,
  15268.             @publisher_conflictcount = 0,
  15269.             @subscriber_insertcount = 0,
  15270.             @subscriber_deletecount = 0,
  15271.             @subscriber_updatecount = 0,
  15272.             @subscriber_conflictcount = 0,
  15273.             @delivery_rate = 0,
  15274.             @error_id = NULL, 
  15275.             @last_timestamp = 0x00000000
  15276.  
  15277.         select @status = isnull(runstatus,0),
  15278.             @start_time = convert(nvarchar(12), start_time, 112) +
  15279.                           substring(convert(nvarchar(24), start_time, 121), 11, 13),
  15280.             @time = convert(nvarchar(12), time, 112) +
  15281.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  15282.             @duration = duration, 
  15283.             @comments = comments,
  15284.             @publisher_insertcount = publisher_insertcount,
  15285.             @publisher_deletecount = publisher_deletecount,
  15286.             @publisher_updatecount =  publisher_updatecount,
  15287.             @publisher_conflictcount =  publisher_conflictcount,
  15288.             @subscriber_insertcount = subscriber_insertcount,
  15289.             @subscriber_deletecount = subscriber_deletecount,
  15290.             @subscriber_updatecount =  subscriber_updatecount,
  15291.             @subscriber_conflictcount =  subscriber_conflictcount,
  15292.             -- Note: return average rate here !!! delivery_rate column is current rate
  15293.             @delivery_rate = 
  15294.                 case    when duration <> 0 then 
  15295.                             (publisher_insertcount + publisher_updatecount +
  15296.                             publisher_deletecount + subscriber_insertcount + 
  15297.                             subscriber_updatecount + subscriber_deletecount)/duration
  15298.                         when duration = 0 then 0
  15299.                 end, 
  15300.             @error_id = error_id, @last_timestamp = timestamp
  15301.             from MSmerge_history
  15302.             where
  15303.                 agent_id = @agent_id and
  15304.                 timestamp = (select max(timestamp) from MSmerge_history mh2
  15305.                     where mh2.agent_id = @agent_id)
  15306.  
  15307.         select @publisher = srvname from master..sysservers where srvid = @publisher_id
  15308.  
  15309.         -- For non anonymous agents, @subscriber_name is null 
  15310.         if @subscriber_name is NULL
  15311.             begin
  15312.                 select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  15313.                 if @local_job = 1 select @subscription_type = 0
  15314.                     else select @subscription_type = 1
  15315.                 select @subscriber_type = type from MSsubscriber_info where
  15316.                     UPPER(publisher) = UPPER(@publisher) and
  15317.                     UPPER(subscriber) = UPPER(@subscriber)
  15318.             end
  15319.         else 
  15320.             begin
  15321.                 select @subscriber = @subscriber_name
  15322.                 select @subscriber_db = @subscriber_db + '-' +  convert(nvarchar(4), @agent_id)
  15323.                 select @subscription_type = 2   -- anonymous type
  15324.             end
  15325.         
  15326.         insert into #merge_agent values (@agent_name, @status, @publisher,
  15327.             @publisher_db, @publication, @subscriber, @subscriber_db, @subscription_type,
  15328.             @start_time, @time, @duration, @comments, @delivery_rate,
  15329.             @publisher_insertcount, @publisher_updatecount, @publisher_deletecount, 
  15330.             @publisher_conflictcount,
  15331.             @subscriber_insertcount, @subscriber_updatecount, @subscriber_deletecount, 
  15332.             @subscriber_conflictcount,
  15333.             @error_id, @job_id, @local_job, @profile_id, @agent_id, @last_timestamp,
  15334.             @offload_enabled, @offload_server, @subscriber_type)
  15335.  
  15336.         FETCH hC INTO @publisher_id, @subscriber_id, @publisher_db, @subscriber_db,
  15337.             @publication, @agent_name, @local_job, @job_id, @profile_id,
  15338.             @agent_id, @subscriber_name, @offload_enabled, @offload_server
  15339.         end
  15340.  
  15341.     if @show_distdb = 0
  15342.         select * from #merge_agent 
  15343.     else 
  15344.         select 'dbname' = DB_NAME(), * from #merge_agent
  15345.  
  15346.     drop table #merge_agent
  15347.     close hC
  15348.     deallocate hC
  15349.  
  15350. GO
  15351.  
  15352.  
  15353. raiserror(15339,-1,-1,'sp_MSenum_merge_s')
  15354. go
  15355.  
  15356. create procedure sp_MSenum_merge_s
  15357. @name nvarchar(100), 
  15358. @hours int = 0, /* @hours < 0 will return TOP 100 */
  15359. @session_type int = 1 /* Return all sessions */
  15360. as
  15361.     set nocount on
  15362.  
  15363.     declare @succeed int
  15364.     declare @agent_id int
  15365.     declare @retry int
  15366.     declare @failure int
  15367.     declare @min_time datetime
  15368.  
  15369.     /* 
  15370.     ** Status const defined in sqlrepl.h 
  15371.     */
  15372.     select @succeed = 2
  15373.     select @retry = 5
  15374.     select @failure = 6
  15375.  
  15376.     select @agent_id = id from MSmerge_agents where name = @name
  15377.  
  15378.     /* Get date starting point */
  15379.     IF @hours < 0
  15380.     BEGIN
  15381.         select top 100 runstatus, 
  15382.             'start_time' = convert(nvarchar(12), start_time, 112) +
  15383.                            substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  15384.             'time' = convert(nvarchar(12), time, 112) +
  15385.                      substring(convert(nvarchar(24), time, 121), 11, 13), 
  15386.             comments, duration, 
  15387.             -- Note: return average rate here !!! delivery_rate column is current rate
  15388.             case    when duration <> 0 then 
  15389.                             (publisher_insertcount + publisher_updatecount +
  15390.                             publisher_deletecount + subscriber_insertcount + 
  15391.                             subscriber_updatecount + subscriber_deletecount)/duration
  15392.                     when duration = 0 then 0
  15393.             end, 
  15394.             publisher_insertcount, publisher_updatecount, publisher_deletecount, publisher_conflictcount,
  15395.             subscriber_insertcount, subscriber_updatecount, subscriber_deletecount, subscriber_conflictcount,
  15396.             'action_count' = (select count(*) from MSmerge_history where
  15397.                 start_time = rh.start_time and agent_id = @agent_id),
  15398.             error_id
  15399.             from MSmerge_history rh
  15400.             where
  15401.             agent_id = @agent_id and
  15402.             ((@session_type = 1 and
  15403.             (runstatus = @succeed or
  15404.             runstatus = @retry or
  15405.             timestamp = (select max(timestamp) from MSmerge_history rh2 where
  15406.                 rh2.agent_id = @agent_id))) or 
  15407.             runstatus = @failure)
  15408.             order by timestamp desc
  15409.     END
  15410.     ELSE
  15411.     BEGIN
  15412.         IF @hours = 0
  15413.         BEGIN
  15414.             select @min_time = NULL
  15415.         END
  15416.         ELSE
  15417.         BEGIN
  15418.             select @min_time = dateadd(hour, -@hours, getdate())
  15419.         END
  15420.         select  runstatus, 
  15421.             'start_time' = convert(nvarchar(12), start_time, 112) +
  15422.                            substring(convert(nvarchar(24), start_time, 121), 11, 13), 
  15423.             'time' = convert(nvarchar(12), time, 112) +
  15424.                      substring(convert(nvarchar(24), time, 121), 11, 13), 
  15425.             comments, duration, 
  15426.             -- Note: return average rate here !!! delivery_rate column is current rate
  15427.             case    when duration <> 0 then 
  15428.                             (publisher_insertcount + publisher_updatecount +
  15429.                             publisher_deletecount + subscriber_insertcount + 
  15430.                             subscriber_updatecount + subscriber_deletecount)/duration
  15431.                     when duration = 0 then 0
  15432.             end, 
  15433.             publisher_insertcount, publisher_updatecount, publisher_deletecount, publisher_conflictcount,
  15434.             subscriber_insertcount, subscriber_updatecount, subscriber_deletecount, subscriber_conflictcount,
  15435.             'action_count' = (select count(*) from MSmerge_history where
  15436.                 start_time = rh.start_time and agent_id = @agent_id),
  15437.             error_id
  15438.             from MSmerge_history rh
  15439.             where
  15440.             agent_id = @agent_id and
  15441.             ((@session_type = 1 and
  15442.             (runstatus = @succeed or
  15443.             runstatus = @retry or
  15444.             timestamp = (select max(timestamp) from MSmerge_history rh2 where
  15445.                 rh2.agent_id = @agent_id))) or 
  15446.             runstatus = @failure) and
  15447.             (time >= @min_time or @min_time IS NULL)
  15448.             order by timestamp desc
  15449.     END
  15450.  
  15451. GO
  15452.  
  15453. raiserror(15339,-1,-1,'sp_MSenum_merge_sd')
  15454. go
  15455.  
  15456. create procedure sp_MSenum_merge_sd
  15457. @name nvarchar(100),
  15458. @time datetime = NULL
  15459. as
  15460.     set nocount on
  15461.  
  15462.     declare @start_time datetime
  15463.     declare @agent_id int
  15464.     declare @time_up datetime
  15465.  
  15466.     select @agent_id = id from MSmerge_agents where name=@name
  15467.     
  15468.     IF @time IS NULL
  15469.         select @time = GETDATE()
  15470.  
  15471.     /*
  15472.     ** Minute-approximate @time can be used.
  15473.     ** Note: The select only return datetime data with minute precision
  15474.     */
  15475.     IF  DATEPART(second, @time) = 0 AND
  15476.         DATEPART(millisecond, @time) = 0
  15477.     BEGIN
  15478.         SELECT @time_up = DATEADD(second, +59, @time)
  15479.         SELECT @time_up = DATEADD(millisecond, +999, @time)
  15480.     END
  15481.     ELSE
  15482.         SELECT @time_up = @time
  15483.         
  15484.  
  15485.     select top 1 @start_time = start_time           
  15486.          from MSmerge_history rh
  15487.         where
  15488.         rh.agent_id = @agent_id and
  15489.         time <= @time_up
  15490.         order by timestamp DESC
  15491.  
  15492.     select  runstatus, 
  15493.             'time' = convert(nvarchar(12), time, 112) + 
  15494.                      substring(convert(nvarchar(24), time, 121), 11, 13),
  15495.             comments, duration, 
  15496.         -- Note: return average rate here !!! delivery_rate column is current rate
  15497.         case    when duration <> 0 then 
  15498.                         (publisher_insertcount + publisher_updatecount +
  15499.                         publisher_deletecount + subscriber_insertcount + 
  15500.                         subscriber_updatecount + subscriber_deletecount)/duration
  15501.                 when duration = 0 then 0
  15502.         end, 
  15503.         publisher_insertcount, publisher_updatecount, publisher_deletecount, publisher_conflictcount,
  15504.         subscriber_insertcount, subscriber_updatecount, subscriber_deletecount, subscriber_conflictcount,
  15505.         error_id            
  15506.         from MSmerge_history rh
  15507.         where
  15508.         rh.agent_id = @agent_id and
  15509.         start_time = @start_time
  15510.         order by timestamp desc
  15511. GO
  15512.  
  15513. raiserror(15339,-1,-1,'sp_MSenableagentoffload')
  15514. GO
  15515. CREATE PROCEDURE sp_MSenableagentoffload (
  15516.     @job_id             VARBINARY(16),
  15517.     @offloadserver      sysname = NULL
  15518.     ) AS
  15519.  
  15520.     SET NOCOUNT ON
  15521.  
  15522.     /*
  15523.     **  Declarations
  15524.     */
  15525.  
  15526.     DECLARE @agent_id          INT
  15527.     DECLARE @subscription_type INT
  15528.     DECLARE @agenttype         NVARCHAR(20)
  15529.     DECLARE @agent_table       sysname 
  15530.     DECLARE @offloadserverwasnull INT
  15531.     DECLARE @retcode           INT
  15532.     
  15533.     SELECT @agent_id = NULL
  15534.     SELECT @subscription_type = 0
  15535.     SELECT @agenttype = NULL    
  15536.     SELECT @agent_table = RTRIM(@@SERVERNAME) + '.' + db_name() + N'.dbo.'
  15537.  
  15538.     -- get the agent type from sysjobsteps table (subsystem) 
  15539.     SELECT @agenttype = LOWER(subsystem) 
  15540.       FROM msdb..sysjobsteps 
  15541.      WHERE job_id = @job_id
  15542.        AND LOWER(subsystem) IN (N'distribution', N'merge') 
  15543.     
  15544.     -- validate the agent type, it has to be non null
  15545.     IF @agenttype IS NULL
  15546.     BEGIN
  15547.         RAISERROR(21134, 16, -1)
  15548.         RETURN 1
  15549.     END
  15550.  
  15551.     -- Make sure that the given offload server does not contain
  15552.     -- invalid characters
  15553.     EXEC @retcode = sp_MSreplcheckoffloadserver @offloadserver
  15554.     IF @retcode <> 0 OR @@error <> 0
  15555.     BEGIN
  15556.         RETURN (1)
  15557.     END
  15558.  
  15559.     -- validate the existence of the job_id in the agent table and get 
  15560.     -- the value of the subscription type and agentid at the same time
  15561.     IF @agenttype = N'distribution'
  15562.     BEGIN
  15563.         SELECT @subscription_type = subscription_type,
  15564.                @agent_id = id  
  15565.           FROM dbo.MSdistribution_agents
  15566.          WHERE job_id = @job_id
  15567.         SELECT @agent_table = @agent_table + 'MSdistribution_agents'
  15568.     END
  15569.     ELSE 
  15570.     BEGIN
  15571.         SELECT @subscription_type = ms.subscription_type,
  15572.                @agent_id = ma.id
  15573.           FROM dbo.MSmerge_agents ma 
  15574.     INNER JOIN dbo.MSpublications mp 
  15575.             ON (ma.publisher_id = mp.publisher_id) 
  15576.            AND (ma.publisher_db = mp.publisher_db) 
  15577.            AND (ma.publication = mp.publication)
  15578.     INNER JOIN dbo.MSmerge_subscriptions ms
  15579.             ON (ma.publisher_id = ms.publisher_id)
  15580.            AND (ma.publisher_db = ms.publisher_db)
  15581.            AND (mp.publication_id = ms.publication_id)
  15582.            AND (ma.subscriber_id = ms.subscriber_id)
  15583.            AND (ma.subscriber_db = ms.subscriber_db)
  15584.      WHERE @job_id = ma.job_id
  15585.         SELECT @agent_table = @agent_table + 'MSmerge_agents'
  15586.     END
  15587.  
  15588.     IF @agent_id IS NULL
  15589.     BEGIN
  15590.         RAISERROR(21135, 16, -1, @agent_table)
  15591.         RETURN 1
  15592.     END 
  15593.     ELSE IF @@ROWCOUNT > 1
  15594.     BEGIN
  15595.         RAISERROR(21136, 16, -1, @agent_table)
  15596.         RETURN 1
  15597.     END
  15598.  
  15599.     -- raise error if subscription type is not push
  15600.     IF @subscription_type <> 0
  15601.     BEGIN
  15602.         RAISERROR(21137, 16, -1)
  15603.         RETURN 1
  15604.     END
  15605.  
  15606.     -- raise error if offload server name is the same as the
  15607.     -- distributor's name
  15608.     IF LOWER(@@SERVERNAME) = LOWER(@offloadserver)
  15609.     BEGIN
  15610.         RAISERROR(21138, 16, -1)
  15611.         RETURN 1
  15612.     END
  15613.  
  15614.     -- if the offload server name is NULL, try to obtain the offload server
  15615.     -- name from the agent table
  15616.     IF (@offloadserver IS NULL) OR (@offloadserver = N'')
  15617.     BEGIN
  15618.         SELECT @offloadserverwasnull = 1
  15619.         IF LOWER(@agenttype) = N'distribution'
  15620.         BEGIN
  15621.             SELECT @offloadserver = offload_server 
  15622.               FROM dbo.MSdistribution_agents
  15623.              WHERE id = @agent_id
  15624.         END
  15625.         ELSE
  15626.         BEGIN
  15627.             SELECT @offloadserver = offload_server
  15628.               FROM dbo.MSmerge_agents
  15629.              WHERE id = @agent_id
  15630.         END
  15631.     END 
  15632.     ELSE
  15633.     BEGIN
  15634.         SELECT @offloadserverwasnull = 0
  15635.     END
  15636.  
  15637.     -- if offload server name is still NULL, use the subscriber as the target 
  15638.     -- server
  15639.     IF (@offloadserver IS NULL) OR (@offloadserver = N'')
  15640.     BEGIN
  15641.         IF LOWER(@agenttype) = N'distribution'
  15642.         BEGIN
  15643.             SELECT @offloadserver = ss.srvname 
  15644.               FROM master.dbo.sysservers ss 
  15645.         INNER JOIN dbo.MSdistribution_agents da 
  15646.                 ON ss.srvid = da.subscriber_id
  15647.              WHERE @agent_id = da.id
  15648.         END
  15649.         ELSE
  15650.         BEGIN
  15651.             SELECT @offloadserver = ss.srvname
  15652.               FROM master.dbo.sysservers ss 
  15653.         INNER JOIN dbo.MSmerge_agents ma
  15654.                 ON ss.srvid = ma.subscriber_id
  15655.              WHERE @agent_id = ma.id
  15656.         END
  15657.     END
  15658.  
  15659.     IF (@offloadserver IS NULL) OR (@offloadserver = N'') 
  15660.     BEGIN
  15661.         RAISERROR(21139, 16, -1)
  15662.         RETURN 1
  15663.     END
  15664.     ELSE IF LOWER(@offloadserver) = LOWER(@@SERVERNAME) 
  15665.     BEGIN
  15666.         IF @offloadserverwasnull = 1
  15667.         BEGIN
  15668.             RAISERROR(21261, 16, -1)
  15669.         END
  15670.         ELSE
  15671.         BEGIN
  15672.             RAISERROR(21140, 16, -1)
  15673.         END
  15674.         RETURN 1
  15675.     END
  15676.  
  15677.     BEGIN TRANSACTION enable_offload
  15678.     
  15679.     -- Update the agent table with the new offload settings
  15680.     IF LOWER(@agenttype) = N'distribution'
  15681.     BEGIN
  15682.         UPDATE MSdistribution_agents
  15683.            SET offload_enabled = 1,
  15684.                offload_server = @offloadserver
  15685.          WHERE id = @agent_id
  15686.         IF @@ERROR <> 0
  15687.             GOTO Failure
  15688.     END
  15689.     ELSE
  15690.     BEGIN
  15691.         UPDATE MSmerge_agents
  15692.            SET offload_enabled = 1,
  15693.                offload_server = @offloadserver
  15694.          WHERE id = @agent_id
  15695.         IF @@ERROR <> 0
  15696.             GOTO Failure
  15697.     END    
  15698.  
  15699.     -- Add the offload parameter
  15700.     EXEC sp_MSaddoffloadparameter @offloadserver = @offloadserver,
  15701.                                   @job_id = @job_id,
  15702.                                   @agenttype = @agenttype
  15703.     
  15704.     IF @@ERROR <> 0
  15705.         GOTO Failure
  15706.     COMMIT TRANSACTION enable_offload
  15707.     RETURN 0
  15708. Failure:
  15709.     ROLLBACK TRANSACTION enable_offload
  15710.     RETURN 1
  15711. GO
  15712.  
  15713. raiserror(15339,-1,-1,'sp_MSdisableagentoffload')
  15714. GO
  15715. CREATE PROCEDURE sp_MSdisableagentoffload (
  15716.     @job_id         VARBINARY(16),
  15717.     @offloadserver  sysname = NULL
  15718.     ) AS
  15719.     
  15720.     SET NOCOUNT ON
  15721.     
  15722.     DECLARE @agent_id    INT
  15723.     DECLARE @agenttype   NVARCHAR(20)
  15724.  
  15725.     SELECT @agent_id = NULL
  15726.     SELECT @agenttype = NULL
  15727.  
  15728.     -- Obtain the agent type from the sysjobssteps table
  15729.     SELECT @agenttype = LOWER(subsystem) 
  15730.       FROM msdb..sysjobsteps
  15731.      WHERE job_id = @job_id
  15732.        AND LOWER(subsystem) IN (N'merge', N'distribution')
  15733.  
  15734.     -- validate the agent type, it has to be either 'merge' or 'distribution'
  15735.     IF @agenttype IS NULL
  15736.     BEGIN
  15737.         RAISERROR(21134, 16, -1)
  15738.         RETURN 1
  15739.     END
  15740.  
  15741.     -- don't check the subscription type 
  15742.     BEGIN TRANSACTION disable_offload
  15743.     
  15744.     -- Update the agent table with the new offload settings
  15745.     IF @agenttype = N'distribution'
  15746.     BEGIN
  15747.         IF @offloadserver IS NULL -- Leave the existing offload server alone
  15748.         BEGIN
  15749.             UPDATE MSdistribution_agents
  15750.                SET offload_enabled = 0
  15751.              WHERE job_id = @job_id
  15752.             IF @@ERROR <> 0
  15753.                 GOTO Failure
  15754.         END
  15755.         ELSE
  15756.         BEGIN
  15757.             UPDATE MSdistribution_agents
  15758.                SET offload_enabled = 0,
  15759.                    offload_server = @offloadserver
  15760.              WHERE job_id = @job_id            
  15761.             IF @@ERROR <> 0
  15762.                 GOTO Failure
  15763.         END    
  15764.  
  15765.  
  15766.     END
  15767.     ELSE
  15768.     BEGIN
  15769.         IF @offloadserver IS NULL -- Leave the existing offload server alone
  15770.         BEGIN
  15771.             UPDATE MSmerge_agents
  15772.                SET offload_enabled = 0
  15773.              WHERE job_id = @job_id
  15774.             IF @@ERROR <> 0
  15775.                 GOTO Failure
  15776.         END
  15777.         ELSE
  15778.         BEGIN
  15779.             UPDATE MSmerge_agents
  15780.                SET offload_enabled = 0,
  15781.                    offload_server = @offloadserver
  15782.              WHERE job_id = @job_id
  15783.             IF @@ERROR <> 0
  15784.                 GOTO Failure
  15785.         END
  15786.     END    
  15787.  
  15788.     -- Call stored procedure to remove -offload parameter from the 
  15789.     -- agent command line
  15790.  
  15791.     EXEC sp_MSremoveoffloadparameter @job_id = @job_id, 
  15792.                                      @agenttype = @agenttype
  15793.     IF @@ERROR <> 0
  15794.         GOTO Failure
  15795.     COMMIT TRANSACTION disable_offload
  15796.  
  15797.     RETURN 0
  15798. Failure:
  15799.  
  15800.     ROLLBACK TRANSACTION disable_offload
  15801.     RETURN (1)
  15802.  
  15803. GO
  15804.     
  15805. raiserror(15339,-1,-1,'sp_MSadd_repl_error')
  15806. GO
  15807.  
  15808. CREATE PROCEDURE sp_MSadd_repl_error (
  15809. @id                 int,
  15810. @error_type_id      int,
  15811. @source_type_id     int,
  15812. @source_name        sysname,
  15813. @error_code         sysname,
  15814. @error_text         ntext
  15815. )
  15816. AS
  15817.     declare @retcode int
  15818.     declare @xact_seqno varbinary(16)
  15819.     declare @command_id int
  15820.  
  15821.     -- Security Check
  15822.     -- require the login to be in cache regardless of the publication id and agent_id.
  15823.     -- This means that once a agent get into the distribution db, it
  15824.     -- can add any error.   
  15825.     exec @retcode = dbo.sp_MScheck_pull_access
  15826.     if @@error <> 0 or @retcode <> 0
  15827.         return (1)
  15828.  
  15829.     select @xact_seqno = xact_seqno, @command_id = command_id from MSrepl_errors where
  15830.         id = @id and xact_seqno is not null
  15831.     
  15832.     INSERT INTO MSrepl_errors VALUES (@id, getdate(), @error_type_id, @source_type_id,
  15833.         @source_name, @error_code, @error_text, @xact_seqno, @command_id)
  15834.  
  15835.     IF @@ERROR <> 0
  15836.     BEGIN
  15837.        RETURN (1)
  15838.     END
  15839.  
  15840.     return (0)
  15841. GO   
  15842.  
  15843.  
  15844. raiserror(15339,-1,-1,'sp_MSadd_repl_alert')
  15845. GO
  15846.  
  15847. CREATE PROCEDURE sp_MSadd_repl_alert (
  15848. @agent_type         int,
  15849. @agent_id           int,
  15850. @error_id           int,
  15851. @alert_error_code   int,
  15852. @xact_seqno         varbinary(16),      
  15853. @command_id         int,
  15854. @publisher          sysname,
  15855. @publisher_db       sysname,
  15856. @subscriber         sysname,
  15857. @subscriber_db      sysname,
  15858. @alert_error_text   ntext
  15859. )
  15860. AS
  15861.     SET NOCOUNT ON
  15862.  
  15863.     declare @retcode int
  15864.     declare @article sysname
  15865.     declare @article_id int
  15866.     declare @destination_object sysname
  15867.     declare @source_object sysname
  15868.     declare @publisher_id int
  15869.     declare @publication sysname
  15870.     declare @publication_id int
  15871.     declare @publication_type int
  15872.     declare @subscriber_id int
  15873.     declare @publisher_database_id int
  15874.     declare @agent_type2 int
  15875.  
  15876.     -- Security Check
  15877.     if @agent_type = 3
  15878.         select @agent_type2 = 0 -- distribution
  15879.     else if @agent_type = 4
  15880.         select @agent_type2 = 1 -- merge
  15881.  
  15882.     if @agent_type2 is not null 
  15883.     begin
  15884.         exec @retcode = dbo.sp_MScheck_pull_access
  15885.                 @agent_id = @agent_id,
  15886.                 @agent_type = @agent_type2
  15887.         if @@error <> 0 or @retcode <> 0
  15888.             return (1)
  15889.     end
  15890.     else
  15891.     begin
  15892.         if is_member('db_owner') = 0
  15893.         begin
  15894.             RAISERROR (14126, 16, -1)
  15895.             return(1)
  15896.         end
  15897.     end
  15898.  
  15899.     select @publisher_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  15900.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  15901.     
  15902.     select @publisher_database_id = id from MSpublisher_databases 
  15903.     where publisher_id = @publisher_id and publisher_db = @publisher_db
  15904.  
  15905.     select @article_id = article_id from MSrepl_commands
  15906.     where publisher_database_id = @publisher_database_id
  15907.     and xact_seqno = @xact_seqno
  15908.     and command_id = @command_id
  15909.  
  15910.     select @publication = mp.publication, @publication_id = mp.publication_id, @publication_type = mp.publication_type
  15911.     from MSpublications as mp, MSsubscriptions as ms
  15912.     where mp.publisher_id = ms.publisher_id
  15913.     and mp.publisher_db = ms.publisher_db
  15914.     and mp.publication_id = ms.publication_id
  15915.     and ms.publisher_id = @publisher_id
  15916.     and ms.publisher_db = @publisher_db
  15917.     and ms.subscriber_id = @subscriber_id
  15918.     and ms.subscriber_db = @subscriber_db
  15919.     and ms.article_id = @article_id
  15920.  
  15921.     select @article = article, @destination_object = destination_object, @source_object = source_object 
  15922.     from MSarticles
  15923.     where article_id = @article_id
  15924.         and publisher_id = @publisher_id
  15925.         and publisher_db = @publisher_db
  15926.         and publication_id = @publication_id
  15927.  
  15928.      INSERT INTO msdb.dbo.sysreplicationalerts (status, agent_type , agent_id, error_id, alert_error_code, time, publisher,
  15929.                                 publisher_db, publication, publication_type, subscriber, subscriber_db,
  15930.                                 article, destination_object, source_object, alert_error_text)
  15931.                 VALUES (0, @agent_type, @agent_id, @error_id, @alert_error_code, getdate(), @publisher, 
  15932.                         @publisher_db, @publication, @publication_type, @subscriber, @subscriber_db, 
  15933.                         @article, @destination_object, @source_object, @alert_error_text)
  15934.     
  15935.     IF @@ERROR <> 0
  15936.     BEGIN
  15937.        RETURN (1)
  15938.     END
  15939.  
  15940.     return (0)
  15941. GO   
  15942.  
  15943. raiserror(15339,-1,-1,'sp_MSadd_replmergealert')
  15944. GO
  15945.  
  15946. CREATE PROCEDURE sp_MSadd_replmergealert (
  15947. @agent_type         int,
  15948. @agent_id           int,
  15949. @error_id           int,
  15950. @alert_error_code   int,
  15951. @publisher          sysname,
  15952. @publisher_db       sysname,
  15953. @publication        sysname,
  15954. @publication_type   int,
  15955. @subscriber         sysname,
  15956. @subscriber_db      sysname,
  15957. @article            sysname,
  15958. @destination_object sysname,
  15959. @source_object      sysname,
  15960. @alert_error_text   ntext
  15961. )
  15962. AS
  15963.     SET NOCOUNT ON
  15964.  
  15965.     INSERT INTO msdb.dbo.sysreplicationalerts (status, agent_type , agent_id, error_id, alert_error_code, time, publisher,
  15966.                                 publisher_db, publication, publication_type, subscriber, subscriber_db,
  15967.                                 article, destination_object, source_object, alert_error_text)
  15968.                 VALUES (0, @agent_type, @agent_id, @error_id, @alert_error_code, getdate(), @publisher, 
  15969.                         @publisher_db, @publication, @publication_type, @subscriber, @subscriber_db, 
  15970.                         @article, @destination_object, @source_object, @alert_error_text)
  15971.     
  15972.     IF @@ERROR <> 0
  15973.     BEGIN
  15974.        RETURN (1)
  15975.     END
  15976.  
  15977.     return (0)
  15978. GO   
  15979.  
  15980.  
  15981. raiserror(15339,-1,-1,'sp_MSget_repl_error')
  15982. GO
  15983.  
  15984. create procedure sp_MSget_repl_error (
  15985. @id int
  15986. )
  15987. as
  15988.     set nocount on
  15989.     select  source_type_id, source_name, error_code, error_text, 
  15990.             convert(nvarchar(12), time, 112) + 
  15991.             substring(convert(nvarchar(24), time, 121), 11, 13),
  15992.             error_type_id, 
  15993.             'has_xact_seqno' = case when xact_seqno is null or xact_seqno = 0x0
  15994.                 then convert(bit, 0) else convert(bit, 1) end,
  15995.             xact_seqno, command_id
  15996.         from MSrepl_errors
  15997.         where
  15998.             id = @id and
  15999.             -- rows with error_type_id are placeholders
  16000.             error_type_id IS NOT NULL
  16001.         order by time ASC
  16002. GO
  16003.  
  16004.  
  16005. raiserror(15339,-1,-1,'sp_MSdist_activate_auto_sub')
  16006. go
  16007. CREATE PROCEDURE sp_MSdist_activate_auto_sub
  16008. @publisher_id int,
  16009. @publisher_db sysname,
  16010. @article_id int
  16011.  
  16012. as
  16013.     
  16014.   declare @automatic tinyint
  16015.   declare @active tinyint
  16016.   declare @subscribed tinyint
  16017.  
  16018.    set nocount on
  16019.  
  16020.     select @automatic = 1
  16021.  
  16022.     select @subscribed = 1
  16023.     select @active = 2
  16024.  
  16025.     begin transaction MSdist_activate_auto_sub
  16026.  
  16027.        update MSsubscriptions set status = @active,
  16028.             subscription_time = getdate()
  16029.            where
  16030.               publisher_id = @publisher_id and
  16031.               publisher_db = @publisher_db and
  16032.               article_id = @article_id and
  16033.               sync_type = @automatic and
  16034.               status in( @subscribed )
  16035.  
  16036.        if @@ERROR <> 0
  16037.           begin
  16038.           if @@trancount > 0
  16039.             rollback transaction MSdist_activate_auto_sub
  16040.           return (1)
  16041.           end
  16042.  
  16043.    commit transaction
  16044.  
  16045. GO
  16046.  
  16047. raiserror(15339,-1,-1,'sp_MSlock_auto_sub')
  16048. go
  16049. CREATE PROCEDURE sp_MSlock_auto_sub
  16050. @publisher_id int,
  16051. @publisher_db sysname,
  16052. @publication sysname,
  16053. @reset bit = 0  /* @reset = 1 is used for Scheduled Snapshot publications by snapshot */
  16054.  
  16055. as
  16056.     
  16057.   /* This sp only work for 7.0 publisher since it use the publication name */  
  16058.    set nocount on
  16059.  
  16060.     DECLARE @virtual smallint     /* const: virtual subscriber id */
  16061.     DECLARE @virtual_anonymous smallint /* const: virtual anonymous subscriber id */
  16062.     DECLARE @subscribed tinyint
  16063.     DECLARE @automatic tinyint
  16064.     DECLARE @publication_id int
  16065.     DECLARE @counter int
  16066.     DECLARE @independent_agent bit
  16067.     DECLARE @active tinyint
  16068.  
  16069.     SELECT @virtual = -1
  16070.     SELECT @virtual_anonymous = -2
  16071.     SELECT @subscribed = 1
  16072.     SELECT @active = 2
  16073.     SELECT @automatic = 1
  16074.  
  16075.     select @publication_id = publication_id , @independent_agent = independent_agent
  16076.         from MSpublications 
  16077.         where 
  16078.         publisher_id = @publisher_id and
  16079.         publisher_db = @publisher_db and
  16080.         publication = @publication 
  16081.  
  16082.  
  16083.     /* 
  16084.     ** Set exclusive lock on the rows that will be updated to prevent deadlock 
  16085.     **      in snapshot agent.
  16086.     ** Note: using UPDATE lock may cause deadlock with sp_MSget_repl_commands as following
  16087.     ** 1. The distribution agent gets shared lock on MSsubscriptions.
  16088.     ** 2. The snapshot agent gets update lock on MSsubscriptions.
  16089.     ** 3. The snapshot agent gets exclusive lock on MSrepl_commands (inserting into the table)
  16090.     ** 4. The distribution agent waits to get shared lock on MSrepl_commands
  16091.     ** 5. The snapshot agent waits to convert update lock to exclusive lock on MSrepl_subscriptions (updating the table).
  16092.     */
  16093.     --SELECT @counter = COUNT(*) FROM MSsubscriptions (ROWLOCK UPDLOCK)
  16094.     -- 1. Avoid defered updates: Don't update fields in the clusted index
  16095.     -- 2. Avoid updating fields in the where clause 
  16096.     UPDATE MSsubscriptions SET update_mode = update_mode 
  16097.       WHERE 
  16098.          publisher_id = @publisher_id and
  16099.          publisher_db = @publisher_db and
  16100.          publication_id = @publication_id and 
  16101.          /* virtual subscriptions are automatic sync type */
  16102.          sync_type = @automatic and 
  16103.          (status = @subscribed or 
  16104.          subscriber_id = @virtual or
  16105.          subscriber_id = @virtual_anonymous or
  16106.          @reset = 1) 
  16107. GO
  16108.  
  16109. raiserror(15339,-1,-1,'sp_MSget_new_xact_seqno')
  16110. go
  16111. CREATE PROCEDURE sp_MSget_new_xact_seqno
  16112. @publisher_id int,
  16113. @publisher_db sysname,
  16114. @len    tinyint
  16115.  
  16116. AS
  16117.    declare @new_xact_seqno varbinary(16)
  16118.    declare @old_xact_seqno varbinary(16)
  16119.    declare @tag int
  16120.    declare @datalen tinyint
  16121.    declare @publisher_database_id int
  16122.  
  16123.    set nocount on 
  16124.    select @old_xact_seqno = NULL
  16125.  
  16126.     -- Get publisher database id.
  16127.     SELECT @publisher_database_id = id from MSpublisher_databases where publisher_id = @publisher_id and 
  16128.         publisher_db = @publisher_db
  16129.  
  16130.    set rowcount 1
  16131.    select @old_xact_seqno = rt.xact_seqno
  16132.       from
  16133.       -- Prevent inserts
  16134.       MSrepl_transactions rt (HOLDLOCK PAGLOCK UPDLOCK)
  16135.       where 
  16136.          rt.publisher_database_id = @publisher_database_id 
  16137.          order by xact_seqno desc
  16138.    set rowcount 0
  16139.  
  16140.    
  16141.    if @old_xact_seqno IS NULL
  16142.    begin
  16143.         /* if nothing got selected, lock the entire table 
  16144.         ** Don't return meta data !!
  16145.         */
  16146.        select @old_xact_seqno = rt.xact_seqno
  16147.           from
  16148.           MSrepl_transactions rt (HOLDLOCK TABLOCKX)
  16149.           where 0 = 1
  16150.  
  16151.         select @old_xact_seqno = subscription_seqno from MSsubscriptions 
  16152.         where
  16153.             publisher_database_id = @publisher_database_id and
  16154.             subscription_seqno = (select MAX(subscription_seqno) from MSsubscriptions rs2
  16155.             where
  16156.                 rs2.publisher_database_id = @publisher_database_id)
  16157.    end
  16158.  
  16159.     select @datalen = datalength(@old_xact_seqno) 
  16160.     /* Plus one to the tag */
  16161.     if @datalen = @len
  16162.     begin
  16163.         select @tag = convert( int, convert( binary(4), substring( convert( nvarchar, @old_xact_seqno ), @datalen/2 - 2 + 1,2 ) ) )
  16164.         
  16165.         if @tag = 0xffffffff
  16166.         begin
  16167.             raiserror(21018, 16, -1)
  16168.             return(1)
  16169.         end
  16170.         /* avoid arithmatic overflow */
  16171.         if @tag = 0x7fffffff
  16172.             select @tag = 0x80000000
  16173.         else 
  16174.             select @tag = @tag + 1
  16175.  
  16176.         select @new_xact_seqno = 
  16177.         convert( varbinary, substring( convert(nvarchar, @old_xact_seqno), 1, @datalen/2-2)) +
  16178.         convert( VARBINARY(4), @tag )
  16179.  
  16180.     end
  16181.     /* Add a tag */
  16182.     else
  16183.     begin
  16184.         if @datalen + 4 <> @len
  16185.         begin
  16186.             -- We are in trouble if we reach here.
  16187.             return(1)
  16188.         end
  16189.         select @tag = 1
  16190.         select @new_xact_seqno = 
  16191.             @old_xact_seqno + CONVERT(VARBINARY(4), @tag) 
  16192.     end
  16193.  
  16194.    select @new_xact_seqno
  16195. GO
  16196.  
  16197.  
  16198.  
  16199. raiserror(15339,-1,-1,'sp_MSchange_publication')
  16200. go
  16201.  CREATE PROCEDURE sp_MSchange_publication (
  16202.      @publisher sysname,
  16203.      @publisher_db sysname,
  16204.      @publication sysname,
  16205.      @property sysname,
  16206.      @value nvarchar(255)
  16207.      )
  16208. as
  16209. BEGIN
  16210.     set nocount on
  16211.     
  16212.      declare @publisher_id smallint
  16213.              ,@publication_type int
  16214.              ,@retcode int
  16215.              ,@max_distretention int
  16216.              ,@retention_value int
  16217.              ,@cmd    nvarchar(255)
  16218.              ,@cmd2   nvarchar(255)
  16219.              ,@cmd3   nvarchar(255)
  16220.  
  16221.     -- Check if publisher is a defined as a distribution publisher in the current database
  16222.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  16223.     if @retcode <> 0
  16224.     begin
  16225.         return(1)
  16226.     end
  16227.  
  16228.     /* Charater properties  */
  16229.  
  16230.     begin tran
  16231.  
  16232.     IF LOWER(@property) ='description'
  16233.     BEGIN
  16234.         UPDATE MSpublications SET description = @value
  16235.             WHERE   publisher_id = @publisher_id AND
  16236.                     publisher_db = @publisher_db AND
  16237.                     publication = @publication
  16238.         IF @@ERROR <> 0 
  16239.             goto UNDO
  16240.     END
  16241.     ELSE IF LOWER(@property) IN ('snapshot_agent')
  16242.     BEGIN
  16243.         -- local job name is internal and should not be changed
  16244.         if exists (select * from MSsnapshot_agents where
  16245.             publisher_id = @publisher_id and
  16246.             publication = @publication and
  16247.             publisher_db = @publisher_db and
  16248.             local_job = 1)
  16249.         begin
  16250.             raiserror(21030, 16, -1)
  16251.             goto UNDO
  16252.         end
  16253.  
  16254.         -- Drop and recreate
  16255.         exec @retcode = dbo.sp_MSdrop_snapshot_agent
  16256.             @publisher = @publisher,
  16257.             @publisher_db = @publisher_db,
  16258.             @publication = @publication
  16259.  
  16260.         IF @@ERROR <> 0 or @retcode <> 0
  16261.             goto UNDO
  16262.  
  16263.         exec @retcode = dbo.sp_MSadd_snapshot_agent
  16264.             @name = @value,
  16265.             @publisher = @publisher,
  16266.             @publisher_db = @publisher_db,
  16267.             @publication = @publication,
  16268.             @local_job = 0
  16269.  
  16270.         IF @@ERROR <> 0 or @retcode <> 0
  16271.             goto UNDO
  16272.     END
  16273.     ELSE IF LOWER(@property) IN ('logreader_agent')
  16274.     BEGIN
  16275.         -- local job name is internal and should not be changed
  16276.         if exists (select * from MSlogreader_agents where
  16277.             publisher_id = @publisher_id and
  16278.             publication = @publication and
  16279.             publisher_db = @publisher_db and
  16280.             local_job = 1)
  16281.         begin
  16282.             raiserror(21030, 16, -1)
  16283.             goto UNDO
  16284.         end
  16285.  
  16286.         -- Drop and recreate
  16287.         exec @retcode = dbo.sp_MSdrop_logreader_agent
  16288.             @publisher = @publisher,
  16289.             @publisher_db = @publisher_db,
  16290.             @publication = @publication
  16291.  
  16292.         IF @@ERROR <> 0 or @retcode <> 0
  16293.             goto UNDO
  16294.  
  16295.         exec @retcode = dbo.sp_MSadd_logreader_agent
  16296.             @name = @value,
  16297.             @publisher = @publisher,
  16298.             @publisher_db = @publisher_db,
  16299.             @publication = @publication,
  16300.             @local_job = 0
  16301.  
  16302.         IF @@ERROR <> 0 or @retcode <> 0
  16303.             goto UNDO
  16304.     END
  16305.     ELSE if LOWER(@property) IN ('retention')
  16306.     BEGIN
  16307.         select @retention_value = convert(int, @value)
  16308.         select @publication_type = publication_type
  16309.             from MSpublications
  16310.             WHERE   publisher_id = @publisher_id AND
  16311.                     publisher_db = @publisher_db AND
  16312.                     publication = @publication
  16313.         UPDATE MSpublications set retention=@retention_value 
  16314.         WHERE   publisher_id = @publisher_id AND
  16315.                     publisher_db = @publisher_db AND
  16316.                     publication = @publication
  16317.         if @@ERROR<>0
  16318.                 goto UNDO
  16319.     END
  16320.      ELSE if LOWER(@property) = ('queue_type')
  16321.      BEGIN
  16322.          --
  16323.          -- If we have come here, it is for MSMQ queue type.
  16324.          -- Distributor needs to support MSMQ 2.0 - Just check that
  16325.          --
  16326.          if (convert(int, @value) = 1)
  16327.          begin
  16328.              --
  16329.              -- Now we use xp_MSver to detect NT OS version
  16330.              -- MSMQ subscription only allowed for platforms that support MSMQ 2.0
  16331.              -- version 5.0.2195 or higher
  16332.              --
  16333.              create table #tosversion ( propid int, propname sysname collate database_default, value int, charvalue nvarchar(255) collate database_default)
  16334.              insert into #tosversion (propid, propname, value, charvalue)
  16335.                  exec master.dbo.xp_msver N'WindowsVersion'
  16336.  
  16337.              declare @vervalue int
  16338.                  ,@lobyte tinyint
  16339.                  ,@hibyte tinyint
  16340.                  ,@loword smallint
  16341.                  ,@hiword smallint
  16342.  
  16343.              --
  16344.              -- low order byte of low order word = OSmajor, high order byte of low order word = OSminor
  16345.              -- high order word = OSbuild
  16346.              --
  16347.              select @vervalue = value from #tosversion where propname = N'WindowsVersion'
  16348.              select @loword = (@vervalue & 0xffff)
  16349.                      ,@hiword = (@vervalue / 0x10000) & 0xffff
  16350.              select @lobyte = @loword & 0xff
  16351.                      ,@hibyte = (@loword / 100) & 0xff
  16352.              drop table #tosversion
  16353.  
  16354.              --
  16355.              -- check for OS major version
  16356.              --
  16357.              if (@lobyte < 5)
  16358.              begin
  16359.                  raiserror(21334, 16, 6, '2.0')
  16360.                  goto UNDO
  16361.              end
  16362.  
  16363.              --
  16364.              -- check for OS build version
  16365.              --
  16366.              if (@lobyte = 5 and @hiword < 2195)
  16367.              begin
  16368.                  raiserror(21334, 16, 7, '2.0')
  16369.                  goto UNDO
  16370.              end
  16371.          end
  16372.      END
  16373.     ELSE
  16374.     BEGIN
  16375.         SELECT @cmd = ''
  16376.         SELECT @cmd = @cmd + 'UPDATE MSpublications '
  16377.         SELECT @cmd = @cmd + '   SET ' + LOWER(@property) + ' = '
  16378.         /* @value can be 255 nchars, so don't append it */
  16379.         SELECT @cmd2 = ' WHERE publisher_id = ' + STR(@publisher_id)
  16380.         SELECT @cmd2 =  @cmd2 + ' AND publisher_db = ' + quotename(@publisher_db,'''')
  16381.         SELECT @cmd2 =  @cmd2 + ' AND publication = '  + quotename(@publication, '''')
  16382.         EXECUTE (@cmd + @value + @cmd2)
  16383.         IF @@ERROR <> 0 
  16384.             goto UNDO
  16385.     END
  16386.  
  16387.     COMMIT TRAN
  16388.  
  16389.     RETURN(0)
  16390.  
  16391. UNDO:
  16392.     IF @@TRANCOUNT = 1
  16393.         ROLLBACK TRAN
  16394.     ELSE
  16395.         COMMIT TRAN   
  16396.     RETURN (1)
  16397. END
  16398. go
  16399.  
  16400.  
  16401. raiserror(15339,-1,-1,'sp_MSadd_article')
  16402. go
  16403. CREATE PROCEDURE sp_MSadd_article
  16404. @publisher sysname,
  16405. @publisher_db sysname,
  16406. @publication sysname,
  16407. @article sysname,
  16408. @article_id int = NULL,
  16409. @destination_object sysname = NULL,
  16410. @source_object sysname = NULL,
  16411. @description nvarchar(255) = NULL,
  16412. @source_owner   sysname = NULL
  16413. as
  16414.  
  16415.     set nocount on
  16416.  
  16417.     declare @publisher_id smallint
  16418.     declare @publication_id int
  16419.     declare @retcode int
  16420.     declare @thirdparty_flag bit
  16421.     declare @immediate_sync bit
  16422.     declare @allow_anonymous bit
  16423.     declare @subscription_seqno binary(16)
  16424.     declare @subscribed tinyint
  16425.     declare @active tinyint
  16426.  
  16427.     select @subscribed = 1  
  16428.     select @active = 2
  16429.         
  16430.     -- Check if publisher is a defined as a distribution publisher in the current database
  16431.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  16432.     if @retcode <> 0
  16433.     begin
  16434.         return(1)
  16435.     end
  16436.  
  16437.     -- Get publication id
  16438.     select @publication_id = publication_id,  
  16439.         @thirdparty_flag = thirdparty_flag,
  16440.         @immediate_sync = immediate_sync, @allow_anonymous = allow_anonymous 
  16441.         from MSpublications where
  16442.         publisher_id = @publisher_id and 
  16443.         publisher_db = @publisher_db and
  16444.         publication = @publication
  16445.     if @publication_id is NULL
  16446.     begin
  16447.         raiserror (20026, 11, -1, @publication)
  16448.         return (1)
  16449.     end
  16450.  
  16451.     -- Make sure article does not already exist
  16452.     if exists (select * from MSarticles where publication_id = @publication_id and
  16453.         publisher_id = @publisher_id and publisher_db = @publisher_db and article = @article)
  16454.     begin
  16455.         if @thirdparty_flag = 1
  16456.         begin
  16457.             raiserror (14030, 16, -1, @article, @publication)
  16458.             return (1)
  16459.         end
  16460.         else
  16461.         begin
  16462.             exec @retcode = dbo.sp_MSdrop_article
  16463.                 @publisher = @publisher,
  16464.                 @publisher_db = @publisher_db,
  16465.                 @publication = @publication,
  16466.                 @article = @article
  16467.             if @retcode <> 0 or @@error <> 0
  16468.             begin
  16469.                 return (1)
  16470.             end
  16471.         end
  16472.     end
  16473.  
  16474.     -- If it is a third party publication - check if a subscription exists
  16475.     -- for the publication already. If it does then we cannot add any
  16476.     -- articles - the existing subscriptions will have to dropped first and then
  16477.     -- resubscribed
  16478.     -- excluding virtual subscriptions.
  16479.     if (@thirdparty_flag = 1)
  16480.     begin
  16481.         if exists (select * from MSsubscriptions where 
  16482.                 publisher_id = @publisher_id and 
  16483.                 publisher_db = @publisher_db and 
  16484.                 publication_id = @publication_id and
  16485.                 subscriber_id >= 0)
  16486.         begin
  16487.             raiserror(21131, 16, -1, @publication)
  16488.             return (1)
  16489.         end
  16490.     end
  16491.  
  16492.     begin tran
  16493.     save tran MSadd_article
  16494.  
  16495.     -- Generate new article id when one is not provided by a 
  16496.     -- third party publisher or merge publication
  16497.     if @article_id is NULL
  16498.     begin
  16499.         if (@thirdparty_flag = 1)
  16500.         begin
  16501.             -- Generate unique id per publisher
  16502.             select @article_id = max(article_id) + 1 from MSarticles where 
  16503.                 publisher_id = @publisher_id
  16504.         end
  16505.         else
  16506.         begin
  16507.             -- 6.5 behavior : retain for compatibility
  16508.             -- NOTE: article_id is incremented per publisher/publisher_db/publication
  16509.             select @article_id = max(article_id) + 1 from MSarticles where 
  16510.                 publisher_id = @publisher_id and
  16511.                 publisher_db = @publisher_db and
  16512.                 publication_id = @publication_id
  16513.         end
  16514.  
  16515.         if @article_id is null
  16516.             select @article_id = 1
  16517.     end
  16518.     else
  16519.     begin
  16520.         --
  16521.         -- for third party publisher - validate the article id
  16522.         --
  16523.         if (@thirdparty_flag = 1)
  16524.         begin
  16525.             if exists (select * from MSarticles where
  16526.                     article_id = @article_id and
  16527.                     publisher_id = @publisher_id and
  16528.                     publisher_db = @publisher_db and
  16529.                     publication_id = @publication_id)
  16530.             begin
  16531.                 if @@trancount > 0
  16532.                 begin
  16533.                     rollback tran MSadd_article
  16534.                     commit tran
  16535.                 end
  16536.                 raiserror (14155, 16, 2)
  16537.                 return (1)
  16538.             end
  16539.         end
  16540.     end
  16541.  
  16542.     insert into MSarticles values (@publisher_id, @publisher_db, @publication_id,
  16543.         @article, @article_id, @destination_object, @source_owner, @source_object, @description)
  16544.     if @@error <> 0
  16545.     begin
  16546.         if @@trancount > 0
  16547.         begin
  16548.             rollback tran MSadd_article
  16549.             commit tran
  16550.         end
  16551.         return (1)
  16552.     end
  16553.  
  16554.     -- For third party publications create immediate sync and anonymous virtual subscription
  16555.     -- with 'subscribed' status and then change anonymous virtual to 'active' status
  16556.     -- SQL Server publications will do this via RPC calls to sp_MSadd_subscription
  16557.     if @thirdparty_flag = 1 
  16558.     begin
  16559.         select @subscription_seqno = 0x00  
  16560.         if @immediate_sync = 1
  16561.         begin
  16562.             -- @status passed to sp_MSadd_subscription should always be @subscribed.
  16563.             exec @retcode = dbo.sp_MSadd_subscription
  16564.                 @publisher = @publisher,
  16565.                 @publisher_db = @publisher_db,
  16566.                 @publication = @publication,
  16567.                 @article_id = @article_id,
  16568.                 @subscriber = NULL,                 -- virtual subscription
  16569.                 @status = @subscribed,              
  16570.                 @subscription_seqno = @subscription_seqno,
  16571.                 @sync_type = 1  -- virtual subscriptions are automatic sync type 
  16572.             if @retcode <> 0 or @@error <> 0
  16573.             begin
  16574.                 if @@trancount > 0
  16575.                 begin
  16576.                     rollback tran MSadd_article
  16577.                     commit tran
  16578.                 end
  16579.                 return (1)
  16580.             end
  16581.             -- For SQL publications, we have logic to immediately active the 
  16582.             -- virtual anonymous subscription to no_sync subscriptions. However, this
  16583.             -- feature is not exposed (You need to pass undocumented command line arg 
  16584.             -- '-NoInitialSync' to the distribution agent for the anonymous subscription).
  16585.             -- Do the same for 3rd party publications
  16586.  
  16587.             if @allow_anonymous = 1
  16588.             begin
  16589. /*
  16590. @publisher sysname,
  16591. @publisher_db sysname,
  16592. @subscriber sysname,
  16593. @article_id int,
  16594. @status int,
  16595. @subscription_seqno varbinary(16),
  16596. --post 6x
  16597. @destination_db sysname = '%'
  16598. */
  16599.                 exec @retcode = dbo.sp_MSupdate_subscription
  16600.                     @publisher = @publisher,
  16601.                     @publisher_db = @publisher_db,
  16602.                     @subscriber = NULL,                 -- virtual subscription
  16603.                     @article_id = @article_id,
  16604.                     @status = @active,              
  16605.                     @subscription_seqno = @subscription_seqno,
  16606.                     @destination_db = '%' -- For virtual sub, @destination_db is not used. Can pass in anything
  16607.                 if @retcode <> 0 or @@error <> 0
  16608.                 begin
  16609.                     if @@trancount > 0
  16610.                     begin
  16611.                         rollback tran MSadd_article
  16612.                         commit tran
  16613.                     end
  16614.                     return (1)
  16615.                 end
  16616.             end
  16617.         end
  16618.     end
  16619.  
  16620.     commit tran
  16621. go
  16622.  
  16623. raiserror(15339,-1,-1,'sp_MSchange_article')
  16624. go
  16625. CREATE PROCEDURE sp_MSchange_article
  16626. @publisher sysname,
  16627. @publisher_db sysname,
  16628. @publication sysname,
  16629. @article sysname,
  16630. @article_id int,
  16631. @property nvarchar(20) = NULL,
  16632. @value nvarchar(255) = NULL
  16633. AS
  16634.     DECLARE @retcode int
  16635.     DECLARE @publisher_id smallint
  16636.     DECLARE @publication_id int
  16637.     declare @tablename sysname
  16638.  
  16639.     -- Get publisher id
  16640.  
  16641.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  16642.     if @retcode <> 0
  16643.     begin
  16644.         return(1)
  16645.     end
  16646.  
  16647.     -- lower case property
  16648.     select @property = lower (@property)
  16649.     
  16650.     -- Get publication id
  16651.  
  16652.     select @publication_id = publication_id
  16653.         from MSpublications where
  16654.         publisher_id = @publisher_id and 
  16655.         publisher_db = @publisher_db and
  16656.         publication = @publication
  16657.     if @publication_id is NULL
  16658.     begin
  16659.         raiserror (20026, 11, -1, @publication)
  16660.         return (1)
  16661.     end
  16662.  
  16663.     if @property = N'description'     
  16664.     begin
  16665.         update MSarticles set description = @value
  16666.         where publisher_id = @publisher_id
  16667.         and publisher_db = @publisher_db
  16668.         and publication_id = @publication_id
  16669.         and article = @article
  16670.         and article_id = @article_id
  16671.         if @@error <> 0
  16672.         begin
  16673.             return 1
  16674.         end
  16675.     end
  16676.     else if @property in( N'dest_table', N'dest_object' )
  16677.     begin
  16678.         update MSarticles set destination_object = @value
  16679.         where publisher_id = @publisher_id
  16680.         and publisher_db = @publisher_db
  16681.         and publication_id = @publication_id
  16682.         and article = @article
  16683.         and article_id = @article_id
  16684.         if @@error <> 0
  16685.         begin
  16686.             return 1
  16687.         end
  16688.     end
  16689.     else if @property = 'identity_range'
  16690.     begin
  16691.         declare @range bigint
  16692.         select @range = convert(bigint, @value)
  16693.         select @tablename = source_object from MSarticles 
  16694.             where publisher_id = @publisher_id
  16695.             and publisher_db = @publisher_db
  16696.             and publication_id = @publication_id
  16697.             and article = @article
  16698.             and article_id = @article_id
  16699.  
  16700.         update MSrepl_identity_range set range = @range where
  16701.             publisher = @publisher and
  16702.             publisher_db = @publisher_db and
  16703.             tablename = @tablename
  16704.         if @@error <> 0
  16705.         begin
  16706.             return 1
  16707.         end
  16708.     end
  16709.     else if @property = 'threshold'
  16710.     begin
  16711.         declare @threshold int
  16712.         select @threshold = convert(int, @value)
  16713.         select @tablename = source_object from MSarticles 
  16714.             where publisher_id = @publisher_id
  16715.             and publisher_db = @publisher_db
  16716.             and publication_id = @publication_id
  16717.             and article = @article
  16718.             and article_id = @article_id
  16719.  
  16720.         update MSrepl_identity_range set threshold = @threshold where
  16721.             publisher = @publisher and
  16722.             publisher_db = @publisher_db and
  16723.             tablename = @tablename
  16724.         if @@error <> 0
  16725.         begin
  16726.             return 1
  16727.         end
  16728.     end
  16729.     else
  16730.     begin
  16731.         return 1
  16732.     end
  16733. go
  16734.  
  16735.  
  16736. raiserror(15339,-1,-1,'sp_MShelp_publication')
  16737. go   
  16738. CREATE PROCEDURE sp_MShelp_publication (
  16739. @publisher sysname,
  16740. @publisher_db sysname = '%',
  16741. @publication sysname = '%')
  16742. as
  16743. BEGIN
  16744.     set nocount on
  16745.     declare    @queued_agent sysname
  16746.  
  16747.     if @publisher_db != '%' and @publication != '%' and not exists (select * from MSpublications where
  16748.         publisher_id = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)) and
  16749.         ((@publisher_db = N'%') or (publisher_db = @publisher_db)) and
  16750.         publication like @publication)
  16751.     begin
  16752.         raiserror(20026, 16, -1, @publication)
  16753.         return(1)
  16754.     end
  16755.  
  16756.     select @queued_agent = name from MSqreader_agents 
  16757.     select p.publisher_db, p.publication, p.publication_id, p.publication_type, 
  16758.         --thirdparty_flag, 
  16759.         independent_agent,
  16760.         immediate_sync, allow_push, allow_pull, allow_anonymous, 'snapshot_agent' = s.name,
  16761.         'logreader_agent' = l.name, p.description, vendor_name 
  16762.         -- queue reader agent only if we have valid queued subscription
  16763.         ,'queuereader agent' = case 
  16764.             when (exists (select * from MSsubscriptions sub where sub.publisher_id = p.publisher_id and
  16765.                         sub.publisher_db = p.publisher_db and sub.publication_id = p.publication_id and
  16766.                         (sub.update_mode in (2,3,4,5)))) 
  16767.             then @queued_agent else NULL end
  16768.         ,'thirdparty_options' = thirdparty_options
  16769.         ,'snapshot_jobid' = j.job_id
  16770.         from MSpublications p  
  16771.         LEFT OUTER JOIN MSsnapshot_agents s
  16772.         ON
  16773.         s.publisher_id = p.publisher_id and
  16774.         s.publisher_db = p.publisher_db and
  16775.         s.publication = p.publication
  16776.         LEFT OUTER JOIN MSlogreader_agents l
  16777.         ON
  16778.         (l.publisher_id = p.publisher_id and
  16779.         l.publisher_db = p.publisher_db and
  16780.         p.publication_type = 0 and              -- Only Transactional Publication has a  Log Reader
  16781.         (l.publication = p.publication OR
  16782.          thirdparty_flag = 0))
  16783.         LEFT OUTER JOIN msdb..sysjobs_view j
  16784.         ON
  16785.         s.job_id = j.job_id
  16786.       where 
  16787.         p.publisher_id = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)) and
  16788.         ((@publisher_db = N'%') or (p.publisher_db = @publisher_db)) and
  16789.         p.publication like @publication
  16790. END
  16791. go
  16792.  
  16793. raiserror(15339,-1,-1,'sp_MShelp_article')
  16794. go
  16795. CREATE PROCEDURE sp_MShelp_article 
  16796. @publisher sysname,
  16797. @publisher_db sysname,
  16798. @publication sysname,        
  16799. @article sysname = '%'
  16800. as
  16801.  
  16802.     set nocount on
  16803.  
  16804.     select article, article_id, source_object, description, source_owner from MSarticles a where 
  16805.         a.publisher_id = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)) and 
  16806.         a.publisher_db = @publisher_db and
  16807.         a.publication_id = (select publication_id from MSpublications where 
  16808.             publisher_id = a.publisher_id and
  16809.             publisher_db = a.publisher_db and
  16810.             publication = @publication) and
  16811.         a.article like @article
  16812. go
  16813.  
  16814. raiserror(15339,-1,-1,'sp_MShelp_subscription')
  16815. go
  16816. CREATE PROCEDURE sp_MShelp_subscription 
  16817. @publisher sysname,
  16818. @publisher_db sysname,
  16819. @publication sysname,        
  16820. @subscriber sysname = '%',              
  16821. @subscriber_db sysname = '%'
  16822. as
  16823. set nocount on
  16824.  
  16825.     select distinct ss.srvname + ':' + s.subscriber_db, ss.srvname, s.subscriber_db, s.subscription_type, 
  16826.         sync_type, status, agent.name, agent.job_id from 
  16827.         MSsubscriptions s, master..sysservers ss, MSdistribution_agents agent where 
  16828.         s.publisher_id = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)) and 
  16829.         s.publisher_db = @publisher_db and
  16830.         s.publication_id = (select publication_id from MSpublications where 
  16831.             publisher_id = s.publisher_id and
  16832.             publisher_db = s.publisher_db and
  16833.             publication = @publication) and
  16834.         ((@subscriber_db = N'%') or (s.subscriber_db = @subscriber_db)) and
  16835.         s.subscriber_id = ss.srvid and
  16836.         ((@subscriber = N'%') or (UPPER(ss.srvname) = UPPER(@subscriber))) and
  16837.         s.subscriber_id >= 0 and                    -- ignore virtual subscriptions
  16838.         s.agent_id = agent.id
  16839. go
  16840.  
  16841. raiserror(15339,-1,-1,'sp_MSadd_subscription_3rd')
  16842. go
  16843. CREATE PROCEDURE sp_MSadd_subscription_3rd
  16844. @publisher sysname,
  16845. @publisher_db sysname,
  16846. @publication sysname,
  16847. @subscriber sysname,       
  16848. @subscriber_db sysname = NULL,
  16849. @status tinyint,                    -- 0 = inactive, 1 = subscribed, 2 = active 
  16850. @subscription_type tinyint = 0,     -- 0 = push, 1 = pull, 2 = anonymous 
  16851. @sync_type tinyint = 2,             -- 0 = none  1 = automatic snaphot  2 = no intial snapshot
  16852.  
  16853. @frequency_type int = NULL,
  16854. @frequency_interval int = NULL,
  16855. @frequency_relative_interval int = NULL,
  16856. @frequency_recurrence_factor int = NULL,
  16857. @frequency_subday int = NULL,
  16858. @frequency_subday_interval int = NULL,
  16859. @active_start_time_of_day int = NULL,
  16860. @active_end_time_of_day int = NULL,
  16861. @active_start_date int = NULL,
  16862. @active_end_date int = NULL,
  16863.  
  16864. @distribution_jobid binary(8) = NULL OUTPUT
  16865.  
  16866. as
  16867.     set nocount on
  16868.  
  16869.     declare @retcode int
  16870.     declare @publication_id int
  16871.     declare @article_id int
  16872.     declare @virtual_id smallint
  16873.     declare @publisher_id smallint
  16874.     declare @immediate_sync bit
  16875.     declare @allow_push bit
  16876.     declare @allow_pull bit
  16877.     declare @allow_anonymous bit
  16878.     declare @subscription_seqno binary(16)
  16879.  
  16880.     select @virtual_id = -1
  16881.  
  16882.     -- Check if publisher is a defined as a distribution publisher in the current database
  16883.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  16884.     if @retcode <> 0
  16885.     begin
  16886.         return(1)
  16887.     end
  16888.  
  16889.     -- Get publication information
  16890.     select @publication_id = publication_id, @immediate_sync = immediate_sync,
  16891.         @allow_push = allow_push, @allow_pull = allow_pull, @allow_anonymous = allow_anonymous
  16892.         from MSpublications where
  16893.         publisher_id = @publisher_id and
  16894.         publisher_db = @publisher_db and
  16895.         publication = @publication
  16896.     if @publication_id is null
  16897.     begin
  16898.         raiserror(14016, 16, -1, @publication)
  16899.         return (1)
  16900.     end
  16901.  
  16902.     -- Check if publication supports subscription type
  16903.     if @subscription_type = 0 and @allow_push != 1
  16904.     begin
  16905.         raiserror(20034, 16, -1, @publication, 'push')
  16906.         return (1)
  16907.     end
  16908.     else if @subscription_type = 1 and @allow_pull != 1
  16909.     begin
  16910.         raiserror(20034, 16, -1, @publication, 'pull')
  16911.         return (1)
  16912.     end
  16913.     else if @subscription_type = 2 and @allow_anonymous != 1
  16914.     begin
  16915.         raiserror(20034, 16, -1, @publication, 'anonymous')
  16916.         return (1)
  16917.     end
  16918.  
  16919.     begin tran
  16920.     save tran MSadd_subscription_3rd
  16921.  
  16922.     -- Add a subscription for each article in the publication
  16923.     declare hCMSadd_subscription_3rd CURSOR LOCAL FAST_FORWARD FOR 
  16924.         select article_id from MSarticles a where
  16925.             a.publisher_id = @publisher_id and
  16926.             a.publisher_db = @publisher_db and
  16927.             a.publication_id = @publication_id
  16928.         for read only
  16929.  
  16930.     open hCMSadd_subscription_3rd
  16931.     fetch hCMSadd_subscription_3rd into @article_id
  16932.         
  16933.     while (@@fetch_status <> -1)
  16934.     begin
  16935.         if @immediate_sync = 1
  16936.             select @subscription_seqno = subscription_seqno from MSsubscriptions where
  16937.                 publisher_id = @publisher_id and
  16938.                 publisher_db = @publisher_db and
  16939.                 article_id = @article_id and
  16940.                 subscriber_id = @virtual_id 
  16941.         else
  16942.             select @subscription_seqno = 0x00 
  16943.  
  16944.         exec @retcode = dbo.sp_MSadd_subscription
  16945.             @publisher = @publisher,
  16946.             @publisher_db = @publisher_db,
  16947.             @publication = @publication,        -- Must provide this
  16948.             @article_id = @article_id,
  16949.             @subscriber = @subscriber,       
  16950.             @subscriber_db = @subscriber_db,
  16951.             @status = @status,
  16952.             @subscription_seqno = @subscription_seqno,
  16953.             @subscription_type = @subscription_type,
  16954.             @sync_type = @sync_type,
  16955.  
  16956.             @frequency_type = @frequency_type,
  16957.             @frequency_interval = @frequency_interval,
  16958.             @frequency_relative_interval = @frequency_relative_interval,
  16959.             @frequency_recurrence_factor = @frequency_recurrence_factor,
  16960.             @frequency_subday = @frequency_subday,
  16961.             @frequency_subday_interval = @frequency_subday_interval,
  16962.             @active_start_time_of_day = @active_start_time_of_day,
  16963.             @active_end_time_of_day = @active_end_time_of_day,
  16964.             @active_start_date = @active_start_date,
  16965.             @active_end_date = @active_end_date,
  16966.  
  16967.             @distribution_jobid = @distribution_jobid output
  16968.         if @retcode != 0 or @@error != 0
  16969.         begin
  16970.             close hCMSadd_subscription_3rd
  16971.             deallocate hCMSadd_subscription_3rd
  16972.             if @@trancount > 0
  16973.             begin
  16974.                 rollback tran MSadd_subscription_3rd
  16975.                 commit tran
  16976.             end
  16977.             return(1)
  16978.         end
  16979.  
  16980.         fetch hCMSadd_subscription_3rd into @article_id
  16981.     end
  16982.  
  16983.     close hCMSadd_subscription_3rd
  16984.     deallocate hCMSadd_subscription_3rd
  16985.  
  16986.     -- If article_id is null, there were no articles defined for the publication
  16987.     if @article_id is NULL
  16988.     begin
  16989.         raiserror(14009, 16, -1, @publication)
  16990.         if @@trancount > 0
  16991.         begin
  16992.             rollback tran MSadd_subscription_3rd
  16993.             commit tran
  16994.         end
  16995.         return (1)
  16996.     end
  16997.  
  16998.     commit tran
  16999.  
  17000. go
  17001.  
  17002. raiserror(15339,-1,-1,'sp_MSdrop_subscription_3rd')
  17003. go
  17004. CREATE PROCEDURE sp_MSdrop_subscription_3rd
  17005. @publisher sysname,
  17006. @publisher_db sysname,
  17007. @publication sysname,
  17008. @subscriber sysname,       
  17009. @subscriber_db sysname = NULL
  17010.  
  17011. as
  17012.     set nocount on
  17013.  
  17014.     declare @retcode int
  17015.     declare @article_id int
  17016.     declare @publisher_id smallint
  17017.     declare @publication_id int
  17018.  
  17019.     -- Check if publisher is a defined as a distribution publisher in the current database
  17020.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  17021.     if @retcode <> 0
  17022.     begin
  17023.         return(1)
  17024.     end
  17025.  
  17026.     -- Get publication information
  17027.     select @publication_id = publication_id from MSpublications where
  17028.         publisher_id = @publisher_id and
  17029.         publisher_db = @publisher_db and
  17030.         publication = @publication
  17031.     if @publication_id is null
  17032.     begin
  17033.         raiserror(14016, 16, -1, @publication)
  17034.         return (1)
  17035.     end
  17036.  
  17037.     begin tran
  17038.     save tran MSdrop_subscription_3rd
  17039.  
  17040.     -- Drop the subscription for each article in the publication
  17041.     if lower(@subscriber) = 'all' and lower(@subscriber_db) = 'all'
  17042.     begin
  17043.         declare hCMSdrop_subscription_3rd CURSOR LOCAL FAST_FORWARD FOR 
  17044.             select a.article_id, srv.srvname, sub.subscriber_db 
  17045.                 from MSarticles a, MSsubscriptions sub, master..sysservers srv where
  17046.                 a.publisher_id = @publisher_id and
  17047.                 a.publisher_db = @publisher_db and
  17048.                 a.publication_id = @publication_id and
  17049.                 sub.article_id = a.article_id and
  17050.                 sub.publisher_id = @publisher_id and
  17051.                 sub.publisher_db = @publisher_db and
  17052.                 sub.publication_id = @publication_id and
  17053.                 srv.srvid = sub.subscriber_id and
  17054.                 sub.subscriber_id >= 0
  17055.             union
  17056.             -- For virtual subscriptions
  17057.             select a.article_id, convert(sysname, null), convert(sysname, null)
  17058.                 from MSarticles a where
  17059.                 a.publisher_id = @publisher_id and
  17060.                 a.publisher_db = @publisher_db and
  17061.                 a.publication_id = @publication_id and
  17062.                 exists (select * from MSsubscriptions sub where
  17063.                     sub.article_id = a.article_id and
  17064.                     sub.publisher_id = @publisher_id and
  17065.                     sub.publisher_db = @publisher_db and
  17066.                     sub.publication_id = @publication_id and
  17067.                     sub.subscriber_id <0 )
  17068.             for read only
  17069.     end
  17070.     else
  17071.         declare hCMSdrop_subscription_3rd CURSOR LOCAL FAST_FORWARD FOR 
  17072.             select article_id, @subscriber, @subscriber_db from MSarticles a where
  17073.                 a.publisher_id = @publisher_id and
  17074.                 a.publisher_db = @publisher_db and
  17075.                 a.publication_id = @publication_id
  17076.             for read only
  17077.  
  17078.     open hCMSdrop_subscription_3rd
  17079.     fetch hCMSdrop_subscription_3rd into @article_id, @subscriber, @subscriber_db
  17080.         
  17081.     while (@@fetch_status <> -1)
  17082.     begin
  17083.         exec @retcode = dbo.sp_MSdrop_subscription
  17084.             @publisher = @publisher,
  17085.             @publisher_db = @publisher_db,
  17086.             @publication = @publication,        -- Must provide this
  17087.             @article_id = @article_id,
  17088.             @subscriber = @subscriber,       
  17089.             @subscriber_db = @subscriber_db
  17090.         if @retcode != 0 or @@error != 0
  17091.         begin
  17092.             close hCMSdrop_subscription_3rd
  17093.             deallocate hCMSdrop_subscription_3rd
  17094.             if @@trancount > 0
  17095.             begin
  17096.                 rollback tran MSdrop_subscription_3rd
  17097.                 commit tran
  17098.             end
  17099.             return (1)
  17100.         end
  17101.  
  17102.        fetch hCMSdrop_subscription_3rd into @article_id, @subscriber, @subscriber_db
  17103.     end
  17104.  
  17105.     close hCMSdrop_subscription_3rd
  17106.     deallocate hCMSdrop_subscription_3rd
  17107.     commit tran
  17108. go
  17109.  
  17110. raiserror(15339,-1,-1,'sp_MSactivate_subscriptions')
  17111. go
  17112.  
  17113. CREATE PROCEDURE sp_MSactivate_subscriptions
  17114. @publisher_id int,
  17115. @publisher_db sysname,
  17116. @publication_id int, 
  17117. @xact_seqno varbinary(16),
  17118. @reset bit = 0      /* @reset = 1 is used for Scheduled Snapshot publications by snapshot */
  17119. AS
  17120.  
  17121.     declare @article_id int
  17122.     declare @retcode int
  17123.  
  17124.     declare hCseqno_3rd CURSOR LOCAL FAST_FORWARD FOR 
  17125.         select article_id from MSarticles a where
  17126.             a.publisher_id = @publisher_id and
  17127.             a.publisher_db = @publisher_db and
  17128.             a.publication_id = @publication_id
  17129.         for read only
  17130.  
  17131.     open hCseqno_3rd
  17132.     fetch hCseqno_3rd into @article_id
  17133.         
  17134.     while (@@fetch_status <> -1)
  17135.     begin
  17136.         select @article_id
  17137.         select @xact_seqno
  17138.         exec @retcode = dbo.sp_MSset_snapshot_xact_seqno
  17139.             @publisher_id = @publisher_id,
  17140.             @publisher_db = @publisher_db,
  17141.             @article_id = @article_id,
  17142.             @xact_seqno = @xact_seqno,
  17143.             @reset = @reset
  17144.         if @retcode != 0 or @@error != 0
  17145.         begin
  17146.             close hCseqno_3rd
  17147.             deallocate hCseqno_3rd
  17148.             return(1)
  17149.         end
  17150.  
  17151.         -- Activate the subscriptions
  17152.         exec @retcode = dbo.sp_MSdist_activate_auto_sub
  17153.             @publisher_id = @publisher_id,
  17154.             @publisher_db = @publisher_db,
  17155.             @article_id = @article_id
  17156.         if @retcode != 0 or @@error != 0
  17157.         begin
  17158.             close hCseqno_3rd
  17159.             deallocate hCseqno_3rd
  17160.             return(1)
  17161.         end
  17162.  
  17163.         fetch hCseqno_3rd into @article_id
  17164.     end
  17165.  
  17166.     close hCseqno_3rd
  17167.     deallocate hCseqno_3rd
  17168. GO
  17169. raiserror(15339,-1,-1,'sp_MSdrop_merge_subscription')
  17170. GO
  17171.  
  17172. CREATE PROCEDURE sp_MSdrop_merge_subscription
  17173. @publisher          sysname,
  17174. @publisher_db       sysname,
  17175. @publication        sysname,
  17176. @subscriber         sysname,
  17177. @subscriber_db      sysname,
  17178. @subscription_type  nvarchar(15) = 'push'           /* Subscription type - push, pull, both */ 
  17179.  
  17180. as
  17181.  
  17182.     set nocount on
  17183.  
  17184.     declare @publisher_id smallint
  17185.     declare @subscriber_id smallint
  17186.     declare @retcode int
  17187.     declare @publication_id int
  17188.     declare @job_id binary(16)
  17189.     declare @thirdparty_flag bit
  17190.     declare @id                 int
  17191.     declare @keep_for_last_run  bit
  17192.  
  17193.     -- Check if publisher is a defined as a distribution publisher in the current database
  17194.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  17195.     if @retcode <> 0
  17196.     begin
  17197.         return(1)
  17198.     end
  17199.  
  17200.     -- Check if subscriber exists
  17201.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber) 
  17202.     if @subscriber_id is NULL
  17203.     begin
  17204.         raiserror (20032, 16, -1, @subscriber, @publisher) 
  17205.         return (1)
  17206.     end
  17207.  
  17208.     -- Check if the publication exists
  17209.     select @publication_id = publication_id,
  17210.         @thirdparty_flag = thirdparty_flag
  17211.         from MSpublications where
  17212.         publisher_id = @publisher_id and
  17213.         publisher_db = @publisher_db and
  17214.         publication = @publication
  17215.     if @publication_id is NULL
  17216.     begin
  17217.         raiserror (20026, 16, -1, @publication) 
  17218.        return (1)
  17219.     end
  17220.  
  17221.     -- Check that subscription exists
  17222.     if not exists (select * from MSmerge_subscriptions where 
  17223.         publisher_id = @publisher_id and 
  17224.         publisher_db = @publisher_db and 
  17225.         publication_id = @publication_id and
  17226.         subscriber_id = @subscriber_id and
  17227.         subscriber_db = @subscriber_db)
  17228.     begin
  17229.         if @thirdparty_flag = 1
  17230.         begin
  17231.             --UNDONE : Add this back again when we add pull subscriptions metedata at the distributor
  17232.             --raiserror (14050, 10, -1)
  17233.             return(1)
  17234.         end
  17235.         else
  17236.             return (0)
  17237.     end
  17238.  
  17239.     begin tran
  17240.     save transaction MSdrop_merge_subscription
  17241.  
  17242.     -- Delete the subscription 
  17243.     -- For anonymous type, delete virtual anonymous subscription also
  17244.     -- if deleting the  virtual subscription 
  17245.     -- (since there can be only one subscriber_id per article, subscriber_db doesn't matter)
  17246.     delete from MSmerge_subscriptions where
  17247.         publisher_id = @publisher_id and
  17248.         publisher_db = @publisher_db and
  17249.         publication_id = @publication_id and
  17250.         subscriber_id = @subscriber_id and
  17251.         subscriber_db = @subscriber_db
  17252.     if @@error <> 0
  17253.     begin
  17254.         goto FAILURE
  17255.     end
  17256.  
  17257.     /*
  17258.     ** Get agentid to check history record
  17259.     */
  17260.     select @id=id from MSmerge_agents where 
  17261.         publisher_id = @publisher_id and
  17262.         publisher_db = @publisher_db and
  17263.         publication = @publication and
  17264.         subscriber_id = @subscriber_id and
  17265.         subscriber_db = @subscriber_db
  17266.  
  17267.     /*
  17268.     ** If the subscription has not yet been synced, there is no need for subscriber side cleanup 
  17269.     ** therefore no need for the last agent run.
  17270.     */
  17271.     if exists (select * from MSmerge_history where agent_id = @id) and @subscription_type='push'
  17272.         select @keep_for_last_run = 0 -- cleanup code is not activated.
  17273.     else 
  17274.         select @keep_for_last_run = 0
  17275.     
  17276.     /*
  17277.     ** Delete Merge agent and meta data, if it exists
  17278.     */
  17279.     EXECUTE @retcode = dbo.sp_MSdrop_merge_agent 
  17280.         @publisher = @publisher,
  17281.         @publisher_db = @publisher_db,
  17282.         @publication = @publication,
  17283.         @subscriber = @subscriber,
  17284.         @subscriber_db = @subscriber_db,
  17285.         @keep_for_last_run = @keep_for_last_run
  17286.     if @@error <> 0 or @retcode <> 0
  17287.     begin
  17288.         goto FAILURE
  17289.     end
  17290.  
  17291.     commit transaction
  17292.     return 0
  17293. FAILURE:
  17294.     if @@trancount > 0
  17295.     begin   
  17296.         ROLLBACK TRANSACTION MSdrop_merge_subscription
  17297.         COMMIT TRANSACTION
  17298.     end
  17299.     return 1
  17300.         
  17301. GO
  17302.  
  17303. raiserror(15339,-1,-1,'sp_MSadd_merge_subscription')
  17304. GO
  17305. CREATE PROCEDURE sp_MSadd_merge_subscription
  17306. @publisher sysname,
  17307. @publisher_db sysname,
  17308. @publication sysname,
  17309. @subscriber sysname,       
  17310. @subscriber_db sysname,
  17311. @subscription_type tinyint = 0,     -- 0 = push, 1 = pull
  17312. @sync_type tinyint = 1,             -- 0 = none  1 = automatic snaphot  2 = no intial snapshot
  17313. @status tinyint = 1,                -- 0 = inactive, 1 = subscribed, 2 = active 
  17314. @frequency_type int = NULL,
  17315. @frequency_interval int = NULL,
  17316. @frequency_relative_interval int = NULL,
  17317. @frequency_recurrence_factor int = NULL,
  17318. @frequency_subday int = NULL,
  17319. @frequency_subday_interval int = NULL,
  17320. @active_start_time_of_day int = NULL,
  17321. @active_end_time_of_day int = NULL,
  17322. @active_start_date int = NULL,
  17323. @active_end_date int = NULL,
  17324. @optional_command_line nvarchar(4000) = NULL,
  17325. -- Job name, used in scripting.
  17326. @agent_name sysname = NULL,
  17327. @merge_jobid binary(16) = NULL OUTPUT,
  17328. -- Agent offload
  17329. @offloadagent bit = 0,
  17330. @offloadserver sysname = NULL
  17331. as
  17332.  
  17333.     set nocount on
  17334.  
  17335.     declare @publisher_id smallint
  17336.     declare @subscriber_id smallint
  17337.     declare @publication_id int
  17338.     declare @retcode int
  17339.  
  17340.     -- default values 
  17341.     declare @flushfrequency int 
  17342.     declare @frequencytype int
  17343.     declare @frequencyinterval int 
  17344.     declare @frequencyrelativeinterval int
  17345.     declare @frequencyrecurrencefactor int 
  17346.     declare @frequencysubday int 
  17347.     declare @frequencysubdayinterval int
  17348.     declare @activestarttimeofday int
  17349.     declare @activeendtimeofday int
  17350.     declare @activestartdate int 
  17351.     declare @activeenddate int 
  17352.     declare @push int
  17353.     declare @local_job bit
  17354.     declare @thirdparty_flag bit
  17355.  
  17356.     select @push = 0
  17357.  
  17358.     -- Check if publisher is a defined as a distribution publisher in the current database
  17359.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  17360.     if @retcode <> 0
  17361.     begin
  17362.         return(1)
  17363.     end
  17364.  
  17365.     -- Get the publication information 
  17366.     select @publication_id = publication_id,
  17367.         @thirdparty_flag = thirdparty_flag from 
  17368.         MSpublications where 
  17369.         publisher_id = @publisher_id and
  17370.         publisher_db = @publisher_db and
  17371.         publication = @publication
  17372.     if @publication_id is NULL
  17373.     begin
  17374.         raiserror (20026, 11, -1, @publication)
  17375.         return (1)
  17376.     end
  17377.  
  17378.     -- Get subscriber info
  17379.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  17380.  
  17381.     -- Make sure subscription does not already exist
  17382.     if exists (select * from MSmerge_subscriptions where 
  17383.         publisher_id = @publisher_id and 
  17384.         publisher_db = @publisher_db and 
  17385.         publication_id = @publication_id and
  17386.         subscriber_id = @subscriber_id and
  17387.         subscriber_db = @subscriber_db)
  17388.     begin
  17389.         if @thirdparty_flag = 1
  17390.         begin
  17391.             raiserror (14058, 16, -1)
  17392.             return(1)
  17393.         end
  17394.         else
  17395.         begin
  17396.             exec @retcode = dbo.sp_MSdrop_merge_subscription 
  17397.                 @publisher = @publisher,
  17398.                 @publisher_db = @publisher_db,
  17399.                 @publication = @publication,
  17400.                 @subscriber = @subscriber,
  17401.                 @subscriber_db = @subscriber_db,
  17402.                 @subscription_type  = @subscription_type
  17403.             if @retcode <> 0 or @@error <> 0
  17404.             begin
  17405.                 return (1)
  17406.             end
  17407.         end
  17408.     end
  17409.  
  17410.     --Get default task parameter values from MSsubscriber_info 
  17411.     
  17412.     select @frequencytype = frequency_type,
  17413.         @frequencyinterval = frequency_interval,
  17414.         @frequencyrelativeinterval = frequency_relative_interval,
  17415.         @frequencyrecurrencefactor = frequency_recurrence_factor,
  17416.         @frequencysubday = frequency_subday,
  17417.         @frequencysubdayinterval = frequency_subday_interval,
  17418.         @activestarttimeofday = active_start_time_of_day,
  17419.         @activeendtimeofday = active_end_time_of_day,
  17420.         @activestartdate = active_start_date,
  17421.         @activeenddate = active_end_date
  17422.     from MSsubscriber_schedule 
  17423.     where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber) and agent_type = 1
  17424.  
  17425.     if @frequency_type is null
  17426.         select @frequency_type = @frequencytype
  17427.  
  17428.     if @frequency_interval  is null
  17429.         select  @frequency_interval = @frequencyinterval
  17430.  
  17431.     if @frequency_relative_interval is null
  17432.         select  @frequency_relative_interval = @frequencyrelativeinterval
  17433.  
  17434.     if @frequency_recurrence_factor is null
  17435.         select  @frequency_recurrence_factor = @frequencyrecurrencefactor
  17436.  
  17437.     if @frequency_subday is null
  17438.         select  @frequency_subday = @frequencysubday
  17439.  
  17440.     if @frequency_subday_interval is null
  17441.         select  @frequency_subday_interval = @frequencysubdayinterval
  17442.  
  17443.     if @active_start_time_of_day is null
  17444.         select  @active_start_time_of_day = @activestarttimeofday
  17445.  
  17446.     if @active_end_time_of_day is null
  17447.         select  @active_end_time_of_day = @activeendtimeofday
  17448.  
  17449.     if @active_start_date is null
  17450.         select  @active_start_date = @activestartdate
  17451.  
  17452.     if @active_end_date is null
  17453.         select  @active_end_date = @activeenddate
  17454.  
  17455.     begin transaction 
  17456.  
  17457.     -- If push and agent name is not passed in, create local job.
  17458.     if @subscription_type = @push
  17459.         select @local_job = 1
  17460.     else
  17461.         select @local_job = 0
  17462.  
  17463.     insert into MSmerge_subscriptions values (@publisher_id, @publisher_db, @publication_id,
  17464.         @subscriber_id, @subscriber_db, @subscription_type, @sync_type, @status, 
  17465.         getdate())  -- need to store GUID?
  17466.     if @@error <> 0
  17467.     begin
  17468.         goto FAILURE
  17469.     end
  17470.  
  17471.     -- Create Merge Agent
  17472.     exec @retcode = dbo.sp_MSadd_merge_agent
  17473.         @name = @agent_name, 
  17474.         @publisher = @publisher,
  17475.         @publisher_db = @publisher_db,
  17476.         @publication = @publication,
  17477.         @subscriber = @subscriber,
  17478.         @subscriber_db = @subscriber_db,
  17479.         @local_job = @local_job,
  17480.         @frequency_type  = @frequency_type,                         
  17481.         @frequency_interval = @frequency_interval, 
  17482.         @frequency_relative_interval = @frequency_relative_interval, 
  17483.         @frequency_recurrence_factor = @frequency_recurrence_factor, 
  17484.         @frequency_subday = @frequency_subday, 
  17485.         @frequency_subday_interval = @frequency_subday_interval,
  17486.         @active_start_time_of_day = @active_start_time_of_day, 
  17487.         @active_end_time_of_day = @active_end_time_of_day,         
  17488.         @active_start_date = @active_start_date, 
  17489.         @active_end_date = @active_end_date,
  17490.         @optional_command_line = @optional_command_line,
  17491.         @merge_jobid = @merge_jobid OUTPUT,
  17492.         @offloadagent = @offloadagent,
  17493.         @offloadserver = @offloadserver,
  17494.         @subscription_type = @subscription_type
  17495.  
  17496.     if @retcode <> 0 or @@error <> 0
  17497.     begin
  17498.         goto FAILURE
  17499.     end
  17500.     
  17501.     commit transaction
  17502.     return (0)
  17503.  
  17504. FAILURE:
  17505.     /* UNDONE : This code is specific to 6.X nested transaction semantics */
  17506.     if @@TRANCOUNT = 1 
  17507.         ROLLBACK TRANSACTION 
  17508.     else
  17509.         COMMIT TRANSACTION 
  17510.     RETURN (1)
  17511.     
  17512. GO
  17513.  
  17514. raiserror(15339,-1,-1,'sp_MSenum_merge_subscriptions')
  17515. GO
  17516. create procedure sp_MSenum_merge_subscriptions
  17517. @publisher sysname,
  17518. @publisher_db sysname,
  17519. @publication sysname,
  17520. @exclude_anonymous bit = 0
  17521.  
  17522. as
  17523.  
  17524.     declare @subscriber sysname
  17525.     declare @subscriber_db sysname
  17526.     declare @subscriber_name sysname
  17527.     declare @type int
  17528.     declare @status int
  17529.     declare @agent_name nvarchar(100)
  17530.     declare @subscriber_id smallint
  17531.     declare @publisher_id smallint
  17532.     declare @start_time nvarchar(24)
  17533.     declare @time nvarchar(24)
  17534.     declare @duration int
  17535.     declare @comments nvarchar(255)
  17536.     declare @delivery_rate float
  17537.     declare @error_id int
  17538.     declare @publication_id int
  17539.     declare @publisher_insertcount int
  17540.     declare @publisher_updatecount int
  17541.     declare @publisher_deletecount int
  17542.     declare @publisher_conflictcount int
  17543.     declare @subscriber_insertcount int
  17544.     declare @subscriber_updatecount int
  17545.     declare @subscriber_deletecount int
  17546.     declare @subscriber_conflictcount int
  17547.     declare @job_id binary(16)
  17548.     declare @local_job bit
  17549.     declare @profile_id int
  17550.     declare @agent_id int
  17551.     declare @last_timestamp binary(8)
  17552.     declare @offload_enabled bit
  17553.     declare @offload_server sysname
  17554.         ,@subscriber_type tinyint
  17555.  
  17556.     set nocount on
  17557.  
  17558.  
  17559.     select @publisher_id = srvid from master..sysservers where
  17560.        UPPER(srvname) = UPPER(@publisher)
  17561.  
  17562.     select @publication_id = publication_id from MSpublications  where 
  17563.             publisher_id = @publisher_id and
  17564.             publisher_db = @publisher_db and
  17565.             publication = @publication and
  17566.             publication_type = 2 -- Merge 
  17567.  
  17568.     create table #merge_subscriptions (subscriber sysname NOT NULL,  status int NOT NULL, 
  17569.         subscriber_db sysname NOT NULL, type int NOT NULL, agent_name nvarchar(100) NOT NULL, last_action nvarchar(255) NULL, 
  17570.         action_time nvarchar(24) NULL, start_time nvarchar(24) NULL, duration int NULL, 
  17571.         delivery_rate float NULL,
  17572.         publisher_insertcount int NULL, publisher_updatecount int NULL, publisher_deletecount int NULL,
  17573.         publisher_conficts int NULL, 
  17574.         subscriber_insertcount int NULL, subscriber_updatecount int NULL, subscriber_deletecount int NULL,
  17575.         subscriber_conficts int NULL, error_id int NULL, job_id binary(16) NULL,
  17576.         local_job bit NULL, profile_id int NOT NULL, 
  17577.         agent_id int NOT NULL, last_timestamp binary(8) NOT NULL, offload_enabled bit NOT NULL, 
  17578.         offload_server sysname NULL, subscriber_type tinyint NULL)
  17579.     
  17580.     -- This is to force all queries to return rows ordered by job_id
  17581.     create unique clustered index ucmerge_subscriptions ON #merge_subscriptions (agent_id)
  17582.  
  17583.     declare hC CURSOR LOCAL FAST_FORWARD FOR select subscriber_id, subscriber_db, name, job_id, local_job, profile_id, id, subscriber_name,
  17584.                                                     offload_enabled, offload_server
  17585.                                 from MSmerge_agents 
  17586.                                  where publisher_id = @publisher_id and publisher_db = @publisher_db and publication = @publication  and 
  17587.                                     (@exclude_anonymous = 0 or subscriber_name is null)
  17588.                             for read only
  17589.     open hC
  17590.     fetch hC into  @subscriber_id, @subscriber_db, @agent_name, @job_id, @local_job, @profile_id, @agent_id, @subscriber_name, @offload_enabled,
  17591.                    @offload_server
  17592.     while (@@fetch_status <> -1)
  17593.     begin
  17594.  
  17595.         if @subscriber_name is not NULL 
  17596.             begin
  17597.                 select @subscriber = @subscriber_name
  17598.                 select @subscriber_db = @subscriber_db + '-' + convert(nvarchar(4), @agent_id)
  17599.                 select @type = 2   --anonymous subscription
  17600.             end
  17601.         else
  17602.             begin
  17603.                 select @subscriber = srvname from master..sysservers where srvid=@subscriber_id
  17604.                 select @type = subscription_type from MSmerge_subscriptions 
  17605.                     where publisher_id = @publisher_id and
  17606.                         publisher_db = @publisher_db and
  17607.                         publication_id = @publication_id and
  17608.                         subscriber_id = @subscriber_id and
  17609.                         subscriber_db = @subscriber_db
  17610.                 select @subscriber_type = type from MSsubscriber_info where
  17611.                     UPPER(publisher) = UPPER(@publisher) and
  17612.                     UPPER(subscriber) = UPPER(@subscriber)
  17613.             end
  17614.             
  17615.         -- Get the status of the agent
  17616.         select @status = 0 
  17617.         select  @start_time = NULL,
  17618.             @time = NULL, 
  17619.             @duration = NULL, 
  17620.             @comments = NULL,
  17621.             @publisher_insertcount = NULL,
  17622.             @publisher_deletecount = NULL,
  17623.             @publisher_updatecount =  NULL,
  17624.             @publisher_conflictcount =  NULL,
  17625.             @subscriber_insertcount = NULL,
  17626.             @subscriber_deletecount = NULL,
  17627.             @subscriber_updatecount =  NULL,
  17628.             @subscriber_conflictcount =  NULL,
  17629.             @delivery_rate = NULL, 
  17630.             @error_id = NULL,
  17631.             @last_timestamp = 0x00000000
  17632.                 
  17633.         select @status = isnull(runstatus,0),
  17634.             @start_time = convert(nvarchar(12), start_time, 112) +
  17635.                           substring(convert(nvarchar(24), start_time, 121), 11, 13),
  17636.             @time = convert(nvarchar(12), time, 112) +
  17637.                     substring(convert(nvarchar(24), time, 121), 11, 13), 
  17638.             @duration = duration, 
  17639.             @comments = comments,
  17640.             @publisher_insertcount = publisher_insertcount,
  17641.             @publisher_deletecount = publisher_deletecount,
  17642.             @publisher_updatecount =  publisher_updatecount,
  17643.             @publisher_conflictcount =  publisher_conflictcount,
  17644.             @subscriber_insertcount = subscriber_insertcount,
  17645.             @subscriber_deletecount = subscriber_deletecount,
  17646.             @subscriber_updatecount =  subscriber_updatecount,
  17647.             @subscriber_conflictcount =  subscriber_conflictcount,
  17648.             -- Note: return average rate here !!! delivery_rate column is current rate
  17649.             @delivery_rate = 
  17650.                 case    when duration <> 0 then 
  17651.                             (publisher_insertcount + publisher_updatecount +
  17652.                             publisher_deletecount + subscriber_insertcount + 
  17653.                             subscriber_updatecount + subscriber_deletecount)/duration
  17654.                         when duration = 0 then 0
  17655.                 end, 
  17656.             @error_id = error_id, @last_timestamp = timestamp
  17657.             from MSmerge_history
  17658.             where
  17659.                 agent_id = @agent_id and
  17660.                 timestamp = (select max(timestamp) from MSmerge_history 
  17661.                     where agent_id = @agent_id)
  17662. /* Not currently working Build 351
  17663.                 timestamp = (select top 1 timestamp from MSmerge_history 
  17664.                     where agent_id = @agent_id
  17665.                     order by timestamp DESC) 
  17666. */
  17667.         
  17668.             insert into #merge_subscriptions values ( @subscriber, @status, @subscriber_db,
  17669.                 @type, @agent_name, @comments, @time, @start_time, @duration,
  17670.                 @delivery_rate, 
  17671.                 @publisher_insertcount, @publisher_updatecount, @publisher_deletecount, 
  17672.                 @publisher_conflictcount,
  17673.                 @subscriber_insertcount, @subscriber_updatecount, @subscriber_deletecount, 
  17674.                 @subscriber_conflictcount,
  17675.                 @error_id, @job_id, @local_job, @profile_id, @agent_id, @last_timestamp,
  17676.                 @offload_enabled, @offload_server, @subscriber_type)
  17677.         
  17678.  
  17679.         fetch hC into  @subscriber_id, @subscriber_db, @agent_name, @job_id, @local_job, @profile_id, @agent_id, @subscriber_name,
  17680.                        @offload_enabled, @offload_server
  17681.       end
  17682.  
  17683.     select * from #merge_subscriptions order by job_id asc
  17684.  
  17685.     drop table #merge_subscriptions
  17686.     close hC
  17687.     deallocate hC
  17688.  
  17689. go
  17690.  
  17691. raiserror(15339,-1,-1,'sp_update_agent_profile')
  17692. GO
  17693.  
  17694. -- Update the profile for an agent
  17695. CREATE PROCEDURE sp_update_agent_profile (
  17696.     @agent_type     int,
  17697.     @agent_id       int,
  17698.     @profile_id int
  17699. )
  17700. AS
  17701.     SET NOCOUNT ON
  17702.  
  17703.     DECLARE @proc               nvarchar(255)
  17704.  
  17705.     DECLARE @snapshot_type          int
  17706.     DECLARE @logreader_type         int
  17707.     DECLARE @distribution_type      int
  17708.     DECLARE @merge_type         int
  17709.     DECLARE    @qreader_type            int
  17710.  
  17711.     SELECT @snapshot_type = 1
  17712.     SELECT @logreader_type = 2
  17713.     SELECT @distribution_type = 3
  17714.     SELECT @merge_type = 4
  17715.     SELECT @qreader_type = 9
  17716.  
  17717.     IF @agent_type NOT IN (@snapshot_type, @logreader_type, @distribution_type, @merge_type, @qreader_type)
  17718.         RETURN (1) 
  17719.  
  17720.     /* The profile must be defined for the agent type in MSagent_profiles table */
  17721.     IF NOT EXISTS ( select * from msdb..MSagent_profiles
  17722.             where profile_id = @profile_id
  17723.             and agent_type = @agent_type )
  17724.         RETURN (1)
  17725.     
  17726.     -- The system 'SkipErrors' profile is for sql subscribers only.
  17727.     if @distribution_type = @agent_type and @profile_id = 14
  17728.     begin
  17729.         declare @subscriber_id int, @publisher_id int
  17730.         select top 1 @publisher_id = publisher_id, @subscriber_id = subscriber_id from
  17731.             MSsubscriptions where agent_id = @agent_id
  17732.         declare @subscriber sysname, @publisher sysname
  17733.         select @publisher = srvname from master..sysservers where srvid = @publisher_id
  17734.         select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  17735.  
  17736.         -- Use 'exists' not 'not exists' to take care null @publisher or @subscriber
  17737.         if exists (select * from MSsubscriber_info where
  17738.             upper(publisher) = upper(@publisher) and
  17739.             upper(subscriber) = upper(@subscriber) and
  17740.             type <> 0)
  17741.         begin
  17742.             raiserror(20603, 16, -1)
  17743.             return 1
  17744.         end
  17745.     end
  17746.     
  17747.     SELECT @proc = 'UPDATE ' +
  17748.         CASE @agent_type
  17749.            WHEN @snapshot_type THEN 'MSsnapshot_agents'
  17750.            WHEN @logreader_type THEN 'MSlogreader_agents'
  17751.            WHEN @distribution_type THEN 'MSdistribution_agents'
  17752.            WHEN @merge_type THEN 'MSmerge_agents'
  17753.            WHEN @qreader_type THEN 'MSqreader_agents'
  17754.         END
  17755.         + ' SET profile_id = ' + convert(nvarchar(10), @profile_id)
  17756.         + ' WHERE id = ' + convert(nvarchar(10), @agent_id)
  17757.  
  17758.     EXECUTE (@proc)
  17759.  
  17760.     IF @@ERROR <> 0 
  17761.         RETURN (1)
  17762. GO
  17763.  
  17764.  
  17765. raiserror(15339,-1,-1,'sp_MSprofile_in_use')
  17766. GO
  17767.  
  17768. CREATE PROCEDURE sp_MSprofile_in_use (
  17769.     @tablename          nvarchar(255),
  17770.     @profile_id int
  17771. )
  17772. AS
  17773.     DECLARE @usage_count int
  17774.  
  17775.     IF @tablename IS NULL OR @profile_id IS NULL
  17776.         return 1 ;
  17777.  
  17778.     IF @tablename = 'MSsnapshot_agents'
  17779.         SELECT @usage_count = count(*) FROM MSsnapshot_agents
  17780.         WHERE profile_id = @profile_id
  17781.     ELSE IF @tablename = 'MSlogreader_agents'
  17782.             SELECT @usage_count = count(*) FROM MSlogreader_agents
  17783.             WHERE profile_id = @profile_id
  17784.         ELSE IF @tablename = 'MSdistribution_agents'
  17785.                 SELECT @usage_count = count(*) FROM MSdistribution_agents
  17786.                 WHERE profile_id = @profile_id
  17787.             ELSE IF @tablename = 'MSmerge_agents'
  17788.                     SELECT @usage_count = count(*) FROM MSmerge_agents 
  17789.                     WHERE profile_id = @profile_id
  17790.                 ELSE 
  17791.                     SELECT @usage_count = 0
  17792.  
  17793.     IF @usage_count = 0
  17794.         RETURN -1
  17795.     ELSE
  17796.         RETURN 0
  17797. GO
  17798.  
  17799.  
  17800. raiserror(15339,-1,-1,'sp_MSreset_subscription')
  17801. GO
  17802. CREATE PROCEDURE sp_MSreset_subscription (
  17803.     @publisher sysname,
  17804.     @publisher_db sysname,
  17805.     @publication sysname,  
  17806.     @subscriber sysname,
  17807.     @subscriber_db sysname,
  17808.     @subscription_type int  -- have to have it to identify a distribution agent.
  17809. ) AS
  17810.  
  17811.  
  17812.     SET NOCOUNT ON
  17813.  
  17814.     /*
  17815.     ** Declarations.
  17816.     */
  17817.     DECLARE @retcode            int
  17818.     DECLARE @publisher_id       smallint
  17819.     DECLARE @subscriber_id      smallint
  17820.     DECLARE @virtual            smallint
  17821.     declare @publication_id        int
  17822.     declare @immediate_sync        bit
  17823.  
  17824.  
  17825.     /*
  17826.     ** Initializations
  17827.     */
  17828.     select @virtual = -1
  17829.  
  17830.     select @publisher_id = srvid from master..sysservers where 
  17831.         UPPER(srvname) = UPPER(@publisher)
  17832.  
  17833.     select @subscriber_id = srvid from master..sysservers where 
  17834.         UPPER(srvname) = UPPER(@subscriber) 
  17835.  
  17836.     select @publication_id = publication_id, @immediate_sync = immediate_sync
  17837.         from MSpublications where
  17838.         publisher_id = @publisher_id AND
  17839.         publisher_db = @publisher_db AND
  17840.         publication = @publication
  17841.  
  17842.     if @subscriber is NULL
  17843.         select @subscriber_id = @virtual
  17844.  
  17845.     -- No need to have 2 updates in one transaction.
  17846.     if @immediate_sync = 1
  17847.     begin
  17848.         UPDATE MSdistribution_agents SET subscription_guid = newid()
  17849.             WHERE
  17850.             publisher_id = @publisher_id AND
  17851.             publisher_db = @publisher_db AND
  17852.             publication = @publication and
  17853.             subscriber_id = @subscriber_id and
  17854.             subscriber_db = @subscriber_db and
  17855.             subscription_type = @subscription_type
  17856.  
  17857.         IF @@ERROR <> 0
  17858.             GOTO UNDO
  17859.     end
  17860.  
  17861.     UPDATE MSsubscriptions set subscription_time = getdate() 
  17862.         WHERE
  17863.         publisher_id = @publisher_id AND
  17864.         publisher_db = @publisher_db AND
  17865.         publication_id = @publication_id and
  17866.         subscriber_id = @subscriber_id and
  17867.         subscriber_db = @subscriber_db and
  17868.         subscription_type = @subscription_type
  17869.  
  17870.     IF @@ERROR <> 0
  17871.         GOTO UNDO
  17872.  
  17873.     RETURN(0)
  17874.  
  17875. UNDO:
  17876.     return(1)
  17877. GO
  17878.  
  17879. raiserror(15339,-1,-1,'sp_MSget_subscription_guid')
  17880. GO
  17881. CREATE PROCEDURE sp_MSget_subscription_guid (
  17882. @agent_id int )
  17883. as
  17884. begin
  17885.     set nocount on
  17886.  
  17887.     -- You need to make change to sp_MShelp_distribution_agentid when changing
  17888.     -- this.    
  17889.     -- Get subscription_guid
  17890.     select a1.subscription_guid
  17891.     from MSdistribution_agents a1
  17892.     where
  17893.     -- for non anonymous agents
  17894.     ((a1.virtual_agent_id is null and a1.id = @agent_id) or
  17895.     (   -- for anonymous agents
  17896.         a1.id = (select virtual_agent_id from MSdistribution_agents a2 where
  17897.             a2.id = @agent_id)) -- virtual account
  17898.     ) 
  17899. end            
  17900. GO
  17901.  
  17902.  
  17903. raiserror(15339,-1,-1,'sp_MSreset_subscription_seqno')
  17904. GO
  17905. CREATE PROCEDURE sp_MSreset_subscription_seqno (
  17906. @agent_id int,
  17907. @get_snapshot bit )
  17908. as
  17909.     set nocount on
  17910.  
  17911.     declare @publication_id int
  17912.     declare @sub_agent_id int
  17913.     declare @virtual_anonymous smallint
  17914.     declare @virtual smallint
  17915.     declare @retcode int
  17916.     declare @automatic tinyint
  17917.  
  17918.     select @automatic = 1
  17919.     select @virtual = -1
  17920.     select @virtual_anonymous = -2
  17921.  
  17922.     -- Security Check
  17923.     exec @retcode = dbo.sp_MScheck_pull_access
  17924.         @agent_id = @agent_id,
  17925.         @agent_type = 0 -- distribution agent
  17926.     if @@error <> 0 or @retcode <> 0
  17927.         return (1)
  17928.  
  17929.     -- Get version agent_id
  17930.     select top 1 @sub_agent_id = s2.agent_id from MSsubscriptions s1,
  17931.         MSsubscriptions s2 where
  17932.         s1.publisher_id = s2.publisher_id and
  17933.         s1.publisher_db = s2.publisher_db and
  17934.         s1.publication_id = s2.publication_id and
  17935.         s1.agent_id = @agent_id and
  17936.         s2.subscriber_id = 
  17937.             case @get_snapshot when 0 
  17938.                 then @virtual_anonymous
  17939.                 else @virtual
  17940.             end 
  17941.     
  17942.     -- If there are no virtual subscriptions defined. Don't reset.
  17943.     -- This might happen when the distribution agent tries to 
  17944.     -- reset an subscription on a non immediate_sync publication 
  17945.     -- (this can
  17946.     -- only happen when the publication is changed from immediate_sync to non
  17947.     -- immdiate_sync after the distribution agent has queried the immediate_sync
  17948.     -- property)
  17949.     if @sub_agent_id = 0
  17950.         return 0
  17951.  
  17952.     -- 'no_sync' subscriptions are handled differently
  17953.     if exists (select * from MSsubscriptions where agent_id = @agent_id and 
  17954.         sync_type <> @automatic)
  17955.     begin
  17956.         -- If @get_snapshot = 0, the distribution agent is process the attached
  17957.         -- subscription for the first time. Set subscription_seqno to zero so that
  17958.         -- all changes that are not in the subscription copy will be picked up.
  17959.         -- Otherwise, do noting.
  17960.         if @get_snapshot = 0
  17961.         begin
  17962.             update MSsubscriptions  set 
  17963.                 -- Use current date rather than virtual sub date for the
  17964.                 -- calculation in cleanup 
  17965.                 subscription_time = getdate(),
  17966.                 -- lsn should be ten bytes long. We will not be here
  17967.                 -- if the publisher is 6.x since 6x publisher does not
  17968.                 -- support immediate_sync (thus does not support subscription copy as well)
  17969.                 subscription_seqno = 0x00000000000000000000,
  17970.                 publisher_seqno = 0x00000000000000000000,
  17971.                 ss_cplt_seqno = 0x00000000000000000000
  17972.                 from MSsubscriptions rs1 where
  17973.                     agent_id = @agent_id 
  17974.         end        
  17975.         return 0
  17976.     end
  17977.  
  17978.     -- Reset the subscription statue to be that of the virtual_anonymous subscription.
  17979.     -- Thus, only the snapshot transactions that are later than the subscriber transaction
  17980.     -- timestamp will be picked up (i.e., new article or schema change article.)
  17981.     update MSsubscriptions  set 
  17982.         snapshot_seqno_flag =  
  17983.             (select subscription_seqno from MSsubscriptions rs2
  17984.                 where
  17985.                 rs2.agent_id = @sub_agent_id and
  17986.                 rs2.article_id = rs1.article_id),
  17987.         status =    
  17988.             (select status from MSsubscriptions rs2
  17989.                 where
  17990.                 rs2.agent_id = @sub_agent_id and
  17991.                 rs2.article_id = rs1.article_id),
  17992.         -- Use current date rather than virtual sub date for the
  17993.         -- calculation in cleanup 
  17994.         subscription_time = getdate(),
  17995.         subscription_seqno = 
  17996.             (select subscription_seqno from MSsubscriptions rs2
  17997.                 where
  17998.                 rs2.agent_id = @sub_agent_id and
  17999.                 rs2.article_id = rs1.article_id),
  18000.         publisher_seqno = 
  18001.             (select publisher_seqno from MSsubscriptions rs2
  18002.                 where
  18003.                 rs2.agent_id = @sub_agent_id and
  18004.                 rs2.article_id = rs1.article_id),
  18005.         ss_cplt_seqno = 
  18006.             (select ss_cplt_seqno from MSsubscriptions rs2
  18007.                 where
  18008.                 rs2.agent_id = @sub_agent_id and
  18009.                 rs2.article_id = rs1.article_id)
  18010.         from MSsubscriptions rs1 where
  18011.             agent_id = @agent_id
  18012.         
  18013.     if @@ERROR <> 0
  18014.         return 1
  18015. GO
  18016.  
  18017.  
  18018. raiserror(15339,-1,-1,'sp_MShelp_profile')
  18019. GO
  18020.  
  18021. CREATE PROCEDURE sp_MShelp_profile (        
  18022.     @agent_id   int,
  18023.     @agent_type int,
  18024.     @profile_name sysname = NULL
  18025. )
  18026. as
  18027.     declare @profile_id int
  18028.     declare @snapshot_type int
  18029.     declare @logreader_type int
  18030.     declare @distribution_type int
  18031.     declare @merge_type int
  18032.     declare @qreader_type int
  18033.  
  18034.     select @snapshot_type = 1
  18035.     select @logreader_type = 2
  18036.     select @distribution_type = 3
  18037.     select @merge_type = 4
  18038.     select @qreader_type = 9
  18039.  
  18040.     select @profile_id = NULL
  18041.  
  18042.     if (@profile_name is not null) and (rtrim(ltrim(@profile_name)) <> '')
  18043.     begin
  18044.         select @profile_id = profile_id from msdb..MSagent_profiles where
  18045.             agent_type = @agent_type and profile_name = @profile_name
  18046.  
  18047.         /* raise error if profile not found */
  18048.         if (@profile_id is null)
  18049.         begin
  18050.             raiserror(21123, 16, -1, @profile_name)
  18051.             return (1)
  18052.         end
  18053.     end
  18054.     
  18055.     -- if profile name not specified, use default.
  18056.     if (@profile_id is null)
  18057.     begin
  18058.         if @agent_type = @snapshot_type 
  18059.         begin
  18060.             if @agent_id = 0
  18061.                 select @profile_id = profile_id from msdb..MSagent_profiles where
  18062.                     agent_type = @agent_type and def_profile = 1
  18063.             else
  18064.                 select @profile_id = profile_id from MSsnapshot_agents
  18065.                     where id = @agent_id
  18066.         end
  18067.         else if @agent_type = @logreader_type
  18068.         begin
  18069.             if @agent_id = 0
  18070.                 select @profile_id = profile_id from msdb..MSagent_profiles where
  18071.                     agent_type = @agent_type and def_profile = 1
  18072.             else
  18073.                 select @profile_id = profile_id from MSlogreader_agents
  18074.                     where id = @agent_id
  18075.         end
  18076.         else if @agent_type = @distribution_type
  18077.         begin
  18078.             if @agent_id = 0
  18079.                 select @profile_id = profile_id from msdb..MSagent_profiles where
  18080.                     agent_type = @agent_type and def_profile = 1
  18081.             else
  18082.                 select @profile_id = profile_id from MSdistribution_agents
  18083.                     where id = @agent_id
  18084.         end
  18085.         else if @agent_type = @merge_type
  18086.         begin
  18087.             if @agent_id = 0
  18088.                 select @profile_id = profile_id from msdb..MSagent_profiles where
  18089.                     agent_type = @agent_type and def_profile = 1
  18090.             else
  18091.                 select @profile_id = profile_id from MSmerge_agents
  18092.                     where id = @agent_id
  18093.         end
  18094.         else if @agent_type = @qreader_type
  18095.         begin
  18096.             if @agent_id = 0
  18097.                 select @profile_id = profile_id from msdb..MSagent_profiles where
  18098.                     agent_type = @agent_type and def_profile = 1
  18099.             else
  18100.                 select @profile_id = profile_id from MSqreader_agents
  18101.                     where id = @agent_id
  18102.         end
  18103.     end
  18104.     
  18105.     select profile_id, parameter_name, value 
  18106.         from msdb..MSagent_parameters
  18107.         where profile_id = @profile_id
  18108. GO
  18109.  
  18110. raiserror(15339,-1,-1,'sp_MShelp_snapshot_agentid')
  18111. GO
  18112.  
  18113. CREATE PROCEDURE sp_MShelp_snapshot_agentid (
  18114.     @publisher_id       smallint,
  18115.     @publisher_db       sysname,
  18116.     @publication        sysname,
  18117.     @job_id             binary(16) = NULL
  18118. )
  18119. AS
  18120.     set nocount on
  18121.     declare @retcode int
  18122.     declare @publisher sysname
  18123.     declare @description nvarchar(255)
  18124.  
  18125.     -- Check if agent exists, if not and there is an 6.x tasks then create one
  18126.     if @publication is not null and @publication <> '' and not exists (select * from MSsnapshot_agents where
  18127.             publisher_id = @publisher_id and
  18128.             publisher_db = @publisher_db and
  18129.             publication = @publication)
  18130.     begin
  18131.         -- Do it only if the agent name is valid. It will be the case if
  18132.         -- the agent is launched by SQL Server Agent
  18133.         if exists (select * from msdb..sysjobs_view where
  18134.             job_id = @job_id)
  18135.         begin
  18136.             select @publisher = srvname from master..sysservers where srvid = @publisher_id
  18137.             begin tran
  18138.             exec @retcode = dbo.sp_MSadd_snapshot_agent
  18139.                 @publisher = @publisher, 
  18140.                 @publisher_db = @publisher_db,
  18141.                 @publication = @publication,
  18142.                 @local_job = 1,
  18143.                 @job_existing = 1,
  18144.                 @snapshot_jobid = @job_id
  18145.             if @@ERROR<> 0 or @retcode <> 0
  18146.                 goto UNDO
  18147.  
  18148.             -- Add a publication definition so it shows up in monitoring procs
  18149.             set @description = formatmessage(20555)
  18150.             exec @retcode = dbo.sp_MSadd_publication
  18151.                 @publisher = @publisher,
  18152.                 @publisher_db = @publisher_db,
  18153.                 @publication = @publication,
  18154.                 @publication_type = 1,              -- Make all 6.x pubs transactional
  18155.                 @description = @description     -- 6.x publication description
  18156.  
  18157.             if @@ERROR<> 0 or @retcode <> 0
  18158.                 goto UNDO
  18159.             commit tran
  18160.         end
  18161.     end
  18162.  
  18163.     select id, name from MSsnapshot_agents  where 
  18164.         publisher_id = @publisher_id and
  18165.         publisher_db = @publisher_db and
  18166.         publication = @publication
  18167.  
  18168.     return(0)
  18169.  
  18170. UNDO:
  18171.     if @@TRANCOUNT = 1
  18172.         ROLLBACK TRAN
  18173.     else
  18174.         COMMIT TRAN
  18175.     return(1)
  18176. GO
  18177.  
  18178. raiserror(15339,-1,-1,'sp_MShelp_logreader_agentid')
  18179. GO
  18180.  
  18181. CREATE PROCEDURE sp_MShelp_logreader_agentid (
  18182.     @publisher_id       smallint,
  18183.     @publisher_db       sysname
  18184. )
  18185. AS
  18186.     set nocount on
  18187.     declare @retcode int
  18188.     declare @publisher sysname
  18189.     declare @job_id binary(16)
  18190.     declare @qv_package    varchar(20)
  18191.     declare @desk_top        int
  18192.     declare @license_value int
  18193.     declare @qv_value_package int
  18194.  
  18195.     select @qv_package = '845129433'
  18196.     select @license_value = 0 
  18197.     select @desk_top = 3
  18198.             
  18199.     exec @qv_value_package = master..xp_qv @qv_package
  18200.     if @@ERROR<>0 
  18201.         begin
  18202.             raiserror(20089, 16, -1)
  18203.             return (1)
  18204.         end
  18205.     if @qv_value_package = 1         --- 1 means desktop
  18206.         select @license_value = @desk_top   -- to be consistent with all other compenents.
  18207.     
  18208.     -- Check if agent exists, if not and there is an 6.x tasks then create one
  18209.     if not exists (select * from MSlogreader_agents where
  18210.             publisher_id = @publisher_id and
  18211.             publisher_db = @publisher_db)
  18212.     begin
  18213.         select @publisher = srvname from master..sysservers where srvid = @publisher_id
  18214.  
  18215.         -- Do it only if the agent name is valid. It will be the case if
  18216.         -- the agent is launched by SQL Server Agent
  18217.         select @job_id = id.job_id from msdb..systasks_view v,
  18218.             msdb..systaskids id
  18219.             where 
  18220.             v.server = @publisher and           
  18221.             v.databasename = @publisher_db and
  18222.             v.subsystem = 'LogReader' and
  18223.             v.id = id.task_id
  18224.  
  18225.         if @job_id is not NULL
  18226.         begin
  18227.             exec @retcode = dbo.sp_MSadd_logreader_agent
  18228.                 @publisher = @publisher, 
  18229.                 @publisher_db = @publisher_db,
  18230.                 -- 'ALL' is Used in sp_addpublication as well
  18231.                 @publication = 'ALL',
  18232.                 @local_job = 1,
  18233.                 @job_existing = 1,
  18234.                 @job_id = @job_id
  18235.             if @@ERROR<> 0 or @retcode <> 0
  18236.                 return(1)
  18237.         end
  18238.     end
  18239.   
  18240.     select id, name, @license_value from MSlogreader_agents where 
  18241.         publisher_id = @publisher_id and 
  18242.         publisher_db = @publisher_db
  18243.  
  18244.     return(0)
  18245.  
  18246. GO
  18247.  
  18248. /*
  18249. ** This procedure is to add an agent row in MSmerge_agents for an anonymous subscription,
  18250. ** if it is not already there. If it is, return the agentid and agent name for monitoring
  18251. ** purpose.
  18252. */
  18253. raiserror(15339,-1,-1,'sp_MSadd_merge_anonymous_agent')
  18254. GO
  18255.  
  18256. CREATE PROCEDURE sp_MSadd_merge_anonymous_agent (
  18257.     @publisher_id       smallint,
  18258.     @publisher_db       sysname,
  18259.     @publication        sysname,
  18260.     @subscriber_db      sysname,
  18261.     @subscriber_name    sysname,
  18262.     @subid              uniqueidentifier, 
  18263.     @first_anonymous    int        -- 0 means this is the first time for this anonymous agent being ran.
  18264. )
  18265. AS
  18266.     declare @min_valid_day  datetime
  18267.     declare @merge_type     int
  18268.     declare @profile_id     int
  18269.     declare @subscriber_id  smallint
  18270.     declare @agent_name     sysname
  18271.     declare @agent_id       int
  18272.     declare @retcode        int
  18273.     declare @publication_id int
  18274.     declare @not_exist      bit
  18275.     declare @last_status    int
  18276.     declare @last_history    datetime
  18277.     declare @merge_jobid    uniqueidentifier
  18278.     declare @by_pass        bit
  18279.     declare @retention        int
  18280.     declare @success        int
  18281.     declare @expired        int
  18282.     declare @dropped        int
  18283.     declare @allow_anonymous bit
  18284.  
  18285.     select @dropped = 0
  18286.     select @expired = 0
  18287.     select @success = 2
  18288.     select @by_pass = 0
  18289.  
  18290. /*
  18291. ** This stored procedure does not really add a job at distribution database;
  18292. ** if add a row in MSmerge_agent table for anonymous subscription for the 
  18293. ** purpose of history logging
  18294. */
  18295.  
  18296.     -- Check to see if the publication is valid and allow anonymous
  18297.     select @publication_id = publication_id, @allow_anonymous = allow_anonymous, @retention = retention from MSpublications where
  18298.         publisher_id = @publisher_id and
  18299.         publisher_db = @publisher_db and
  18300.         publication = @publication
  18301.  
  18302.     if @publication_id is null
  18303.     begin
  18304.         RAISERROR (21040, 16, -1, @publication)
  18305.         return 1
  18306.     end
  18307.  
  18308.     if @allow_anonymous = 0
  18309.     begin
  18310.         RAISERROR (21084, 16, -1, @publication)
  18311.         return 1
  18312.     end
  18313.  
  18314.     if @subscriber_name is null
  18315.         select @subscriber_name = N''
  18316.  
  18317.     if @retention is NULL or @retention =0
  18318.         select @by_pass = 1
  18319.  
  18320.     -- Security check
  18321.     exec @retcode = dbo.sp_MScheck_pull_access
  18322.         @publication_id = @publication_id, @agent_type = 1
  18323.     if @retcode <> 0 or @@error <> 0
  18324.         return (1)
  18325.  
  18326.     select @not_exist = 0
  18327.     SELECT @merge_type = 4
  18328.     select @subscriber_id = 0  -- For anonymous subscribers, ID is always 0 
  18329.  
  18330.     SELECT @profile_id = profile_id
  18331.     FROM msdb..MSagent_profiles
  18332.     WHERE agent_type = @merge_type
  18333.         AND def_profile = 1
  18334.  
  18335.     IF @profile_id IS NULL
  18336.         RETURN (1)
  18337.  
  18338.     /*
  18339.     ** This is to handle Jet only
  18340.     */
  18341.     IF @subid = '00000000-0000-0000-0000-000000000000'
  18342.     begin
  18343.         select @subid = anonymous_subid from MSmerge_agents 
  18344.                 where publisher_id=@publisher_id and 
  18345.                       publisher_db = @publisher_db and 
  18346.                       publication = @publication and 
  18347.                       subscriber_name = @subscriber_name 
  18348.                       and subscriber_db = @subscriber_db
  18349.         if @subid = '00000000-0000-0000-0000-000000000000'
  18350.             select @subid = newid()
  18351.         else
  18352.             select @first_anonymous = 1   -- for Jet, schemaversion should not be 0 in this path.
  18353.     end
  18354.          
  18355.     IF NOT EXISTS (select * from MSmerge_agents where anonymous_subid=@subid)
  18356.     begin
  18357.  
  18358.         if @first_anonymous <= 0   --only add agent entry for initial subscription only. 
  18359.         begin
  18360.             select @not_exist = 1
  18361.  
  18362.             -- Generate a job GUID for remote agents. This will be used by the UI to uniquely
  18363.             -- identify rows returned by the enums
  18364.             set @merge_jobid = newid();
  18365.  
  18366.             insert into MSmerge_agents (name, publisher_id, publisher_db, publication, 
  18367.                         subscriber_id, subscriber_db, anonymous_subid, job_id, profile_id, subscriber_name)
  18368.                     VALUES (convert(nvarchar(40), @subid), @publisher_id, @publisher_db, @publication, 
  18369.                             @subscriber_id, @subscriber_db, @subid, @merge_jobid, @profile_id, @subscriber_name)
  18370.         end
  18371.         else
  18372.             select @dropped  =1
  18373.     end
  18374.     
  18375.     select @agent_id = id, @agent_name = name from MSmerge_agents 
  18376.         where anonymous_subid=@subid  -- subid guarantees uniqueness
  18377.     
  18378.     if @by_pass = 0 --by pass the checking if retention is NULL or 0
  18379.     begin
  18380.         select @min_valid_day = dateadd(day, -@retention, getdate())
  18381.         
  18382.         select Top 1 @last_status = runstatus, @last_history = time from MSmerge_history where agent_id = @agent_id
  18383.                     order by time DESC
  18384.         if @last_status = 6 and EXISTS (select * from MSmerge_history where agent_id = @agent_id and runstatus = 2) 
  18385.                 select Top 1 @last_history = time from MSmerge_history where agent_id = @agent_id and runstatus = 2
  18386.                         order by time DESC    
  18387.         /*
  18388.         ** This anonymous subscription is gone for too long to be efficiently reconciled. Either reinitialization or
  18389.         ** re-deployment of this subscription is needed. Merge agent will fail.
  18390.         */
  18391.         if @last_history < @min_valid_day and @first_anonymous <> 0    --do not check for re-initialized replicas.
  18392.                     select @expired = 1
  18393.    end
  18394.  
  18395.     select @agent_id, @agent_name, @expired where @dropped = 0 --return empty result set 
  18396.         
  18397. GO
  18398.  
  18399.  
  18400. raiserror(15339,-1,-1,'sp_MShelp_merge_agentid')
  18401. GO
  18402.  
  18403. CREATE PROCEDURE sp_MShelp_merge_agentid (
  18404.     @publisher_id       smallint,
  18405.     @publisher_db       sysname,
  18406.     @publication        sysname,
  18407.     @subscriber_id      smallint,
  18408.     @subscriber_db      sysname
  18409. )
  18410. AS
  18411.     declare @publisher        sysname
  18412.     declare @subscriber        sysname
  18413.     declare @expired        int
  18414.     declare @agent_id         int
  18415.     declare @name             sysname
  18416.     declare @retention         int
  18417.     declare @last_status    int
  18418.     declare @last_history    datetime
  18419.     declare @min_valid_day     datetime
  18420.     declare @reinited         int
  18421.     declare @status         int
  18422.     declare @success        int
  18423.     declare @publication_id    int
  18424.     declare @subscriber_datasource_type int
  18425.     declare @sql_subscriber    int
  18426.     
  18427.     select @expired = 0
  18428.     select @reinited = 4
  18429.     select @success = 2
  18430.  
  18431.     select @subscriber_datasource_type = 0
  18432.     select @sql_subscriber = 0
  18433.  
  18434.     if not EXISTS (select * from MSpublications 
  18435.         where publisher_id=@publisher_id 
  18436.         and publisher_db = @publisher_db
  18437.         and publication = @publication
  18438.         and publication_type = 2) -- merge publication is gone
  18439.     begin
  18440.         select 1, @publication, 1, 0 --third column = 1 means publication is gone, making the other values meanningless.
  18441.         return (1)
  18442.     end
  18443.  
  18444.        select @publication_id = publication_id 
  18445.         from MSpublications
  18446.         where publisher_id = @publisher_id and
  18447.               publisher_db = @publisher_db and
  18448.               publication = @publication
  18449.  
  18450.     -- Get subscriber info
  18451.     select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  18452.     select @publisher = srvname from master..sysservers where srvid = @publisher_id
  18453.  
  18454.     select @subscriber_datasource_type = type
  18455.         from MSsubscriber_info 
  18456.         where UPPER(publisher) = UPPER(@publisher) and UPPER(subscriber) = UPPER(@subscriber)
  18457.  
  18458.     if (@subscriber_datasource_type = @sql_subscriber)
  18459.     begin
  18460.         select @status = status from MSmerge_subscriptions where
  18461.             publisher_id = @publisher_id and 
  18462.             publisher_db = @publisher_db and 
  18463.             publication_id = @publication_id and
  18464.             subscriber_id = @subscriber_id and
  18465.             subscriber_db = @subscriber_db
  18466.  
  18467.         select @agent_id = id, @name = name from MSmerge_agents 
  18468.             where publisher_id = @publisher_id 
  18469.             and publisher_db = @publisher_db
  18470.             and publication = @publication
  18471.             and subscriber_id = @subscriber_id
  18472.             and subscriber_db = @subscriber_db
  18473.     end
  18474.     else
  18475.     begin
  18476.         select @status = status from MSmerge_subscriptions where
  18477.             publisher_id = @publisher_id and 
  18478.             publisher_db = @publisher_db and 
  18479.             publication_id = @publication_id and
  18480.             subscriber_id = @subscriber_id
  18481.  
  18482.         select @agent_id = id, @name = name from MSmerge_agents 
  18483.             where publisher_id = @publisher_id 
  18484.             and publisher_db = @publisher_db
  18485.             and publication = @publication
  18486.             and subscriber_id = @subscriber_id
  18487.     end
  18488.  
  18489.     -- Security check. Do it here to let the agent fail at the beginning
  18490.     if @agent_id is not null
  18491.     begin
  18492.         exec dbo.sp_MScheck_pull_access @agent_id = @agent_id, @agent_type = 1 -- merge agent
  18493.         select @retention = retention 
  18494.             from MSpublications 
  18495.             where publisher_id=@publisher_id and publisher_db=@publisher_db and publication=@publication 
  18496.  
  18497.         if @retention is not NULL and @retention > 0
  18498.         begin
  18499.             select @min_valid_day = dateadd(day, @retention * (-1), getdate()) 
  18500.             select Top 1 @last_status = runstatus, @last_history = time 
  18501.                     from MSmerge_history where agent_id = @agent_id
  18502.                         order by time DESC
  18503.             if @last_status = 6 and EXISTS (select * from MSmerge_history where  agent_id = @agent_id and runstatus = 2) 
  18504.                 select Top 1 @last_history = time from MSmerge_history where agent_id = @agent_id and runstatus = 2
  18505.                                 order by time DESC    
  18506.             if @last_history < @min_valid_day and @status <> @reinited
  18507.                 select @expired = 1
  18508.         end
  18509.     end
  18510.  
  18511. select @agent_id, @name, 0, @expired where @agent_id is not NULL
  18512. GO
  18513.  
  18514. raiserror(15339,-1,-1,'sp_MSdistpublisher_cleanup')
  18515. GO
  18516.  
  18517. CREATE PROCEDURE sp_MSdistpublisher_cleanup 
  18518. @publisher sysname
  18519. as
  18520.  
  18521.     set nocount on
  18522.     declare @publisher_id smallint
  18523.     declare @job_id binary(16)
  18524.     declare @retcode int
  18525.     
  18526.     -- Delete agents
  18527.     -- Get the publisher id
  18528.     -- Check if publisher is a defined as a distribution publisher in the current database
  18529.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  18530.     if @retcode <> 0
  18531.     begin
  18532.         return(1)
  18533.     end
  18534.     
  18535.     -- Dropping local jobs
  18536.     -- Use union in 'select'. Insensitive cursor will be used automatically.
  18537.     DECLARE hCagents CURSOR LOCAL FAST_FORWARD FOR
  18538.             SELECT job_id 
  18539.                 FROM MSsnapshot_agents
  18540.                 WHERE publisher_id = @publisher_id and local_job = 1
  18541.         UNION
  18542.             SELECT job_id
  18543.                 FROM MSlogreader_agents
  18544.                 WHERE publisher_id = @publisher_id and local_job = 1
  18545.         UNION
  18546.             SELECT job_id 
  18547.                 FROM MSdistribution_agents
  18548.                 WHERE publisher_id = @publisher_id and local_job = 1
  18549.         UNION
  18550.             SELECT job_id
  18551.                 FROM MSmerge_agents
  18552.                 WHERE publisher_id = @publisher_id  and local_job = 1
  18553.         FOR READ ONLY
  18554.  
  18555.     OPEN hCagents
  18556.     FETCH hCagents INTO @job_id
  18557.    
  18558.     WHILE (@@fetch_status <> -1)
  18559.     BEGIN
  18560.         IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @job_id)
  18561.         BEGIN
  18562.             exec @retcode = msdb.dbo.sp_delete_job @job_id = @job_id
  18563.             if @retcode <> 0 or @@error <> 0
  18564.                 return(1)
  18565.         END
  18566.         FETCH hCagents INTO @job_id 
  18567.     end
  18568.  
  18569.     -- Clean up the tables, including
  18570.     --  4 Agent tables
  18571.     --  2 subscription tables
  18572.     --  article table
  18573.     --  publication table
  18574.     --  2 subscriber table
  18575.     -- The order is to avoid breaking monitoring
  18576.  
  18577.  
  18578.     delete MSpublisher_databases where publisher_id = @publisher_id
  18579.     if @@error <> 0 
  18580.         return (1) 
  18581.  
  18582.     delete MSpublications where publisher_id = @publisher_id
  18583.     if @@error <> 0 
  18584.         return (1) 
  18585.  
  18586.     delete MSarticles where publisher_id = @publisher_id
  18587.     if @@error <> 0 
  18588.         return (1) 
  18589.  
  18590.     delete MSsubscriptions where publisher_id = @publisher_id
  18591.     if @@error <> 0 
  18592.         return (1) 
  18593.  
  18594.     delete MSmerge_subscriptions where publisher_id = @publisher_id
  18595.     if @@error <> 0 
  18596.         return (1) 
  18597.  
  18598.     delete MSsnapshot_agents where publisher_id = @publisher_id
  18599.     if @@error <> 0 
  18600.         return (1) 
  18601.     
  18602.     delete MSlogreader_agents where publisher_id = @publisher_id
  18603.     if @@error <> 0 
  18604.         return (1) 
  18605.  
  18606.     delete MSdistribution_agents where publisher_id = @publisher_id
  18607.     if @@error <> 0 
  18608.         return (1) 
  18609.  
  18610.     delete MSmerge_agents where publisher_id = @publisher_id
  18611.     if @@error <> 0 
  18612.         return (1) 
  18613.  
  18614.     delete MSsubscriber_info where UPPER(publisher) = UPPER(@publisher)
  18615.     if @@error <> 0 
  18616.         return (1) 
  18617.  
  18618.     delete MSsubscriber_schedule where UPPER(publisher) = UPPER(@publisher)
  18619.     if @@error <> 0 
  18620.         return (1) 
  18621.  
  18622.     delete MSpublication_access where not exists (select * from MSpublications p where
  18623.         p.publication_id = MSpublication_access.publication_id)
  18624.     if @@error <> 0 
  18625.         return (1) 
  18626.  
  18627.     delete MSrepl_originators where 
  18628.         not exists (select * from MSpublisher_databases p
  18629.             where p.id = MSrepl_originators.publisher_database_id )
  18630.     if @@error <> 0 
  18631.         return (1) 
  18632.  
  18633.     -- Force a refresh of the replication status temp table.
  18634.     if (select object_id('tempdb.dbo.MSreplication_agent_status')) is not NULL
  18635.         delete tempdb.dbo.MSreplication_agent_status
  18636. GO
  18637.  
  18638. raiserror(15339,-1,-1,'sp_MSenum_replication_status')
  18639. GO
  18640.  
  18641. create procedure sp_MSenum_replication_status
  18642. as
  18643.     declare @anonymous_mask int
  18644.     select @anonymous_mask = 0x80000000
  18645.  
  18646.     select 'publisher' = srvname, 'publisher_db' = sa.publisher_db, 
  18647.         'publication' = sa.publication, 'publication_type' = sa.publication_type,
  18648.         'agent_type' = 1, 'status' = runstatus, 'agent_name' = sa.name from 
  18649.         MSsnapshot_history sh1, master..sysservers, MSsnapshot_agents sa
  18650.         where 
  18651.         sh1.timestamp = (select max(timestamp) from MSsnapshot_history sh2 where
  18652.             sh2.agent_id = sa.id) and
  18653.         srvid = sa.publisher_id 
  18654.     UNION
  18655.     select srvname, sa.publisher_db, sa.publication, sa.publication_type, 
  18656.         1, 0, sa.name from 
  18657.         master..sysservers, MSsnapshot_agents sa
  18658.         where 
  18659.         srvid = sa.publisher_id and
  18660.         not exists (select * from MSsnapshot_history sh where sh.agent_id = sa.id)
  18661.     UNION
  18662.     select srvname, la.publisher_db, 'ALL', 0, 2, runstatus, la.name from
  18663.         MSlogreader_history lh1, MSlogreader_agents la, master..sysservers
  18664.         where timestamp = (select max(timestamp) from 
  18665.             MSlogreader_history lh2 where
  18666.             lh2.agent_id = la.id) and
  18667.             srvid = la.publisher_id
  18668.     UNION
  18669.     select srvname, la.publisher_db, 'ALL', 0, 2, 0, la.name from
  18670.         MSlogreader_agents la, master..sysservers
  18671.         where
  18672.             srvid = la.publisher_id and
  18673.             not exists (select * from MSlogreader_history lh where lh.agent_id = la.id)
  18674.     UNION
  18675.     select srvname, da.publisher_db, da.publication, p.publication_type, 3, runstatus, da.name from 
  18676.             MSdistribution_history dh1, master..sysservers, 
  18677.             MSdistribution_agents da, MSpublications p, MSsubscriptions s
  18678.             where timestamp = (select max(timestamp) from 
  18679.                 MSdistribution_history dh2 where
  18680.                 dh2.agent_id = da.id) and
  18681.                 srvid = da.publisher_id and
  18682.                 s.agent_id = da.id and
  18683.                 p.publication_id = s.publication_id
  18684.     UNION
  18685.     select srvname, da.publisher_db, da.publication, p.publication_type, 3, 0, da.name from 
  18686.             master..sysservers, 
  18687.             MSdistribution_agents da,
  18688.             MSpublications p,
  18689.             MSsubscriptions s
  18690.             where 
  18691.                 srvid = da.publisher_id and
  18692.                 not exists (select * from MSdistribution_history dh where dh.agent_id = da.id) and
  18693.                 s.agent_id = da.id and
  18694.                 p.publication_id = s.publication_id
  18695.     UNION    -- Load distribution dummy rows
  18696.     -- The select below will return dumplicates but it will be eliminated by union operator.
  18697.     select srvname, da.publisher_db, p.publication, p.publication_type, 
  18698.             case    when da.anonymous_agent_id is not null then 3 | @anonymous_mask
  18699.                     else 3
  18700.             end,
  18701.             runstatus, da.name from 
  18702.             MSdistribution_history dh1, master..sysservers, 
  18703.             MSdistribution_agents da, MSpublications p, MSsubscriptions s
  18704.             where timestamp = (select max(timestamp) from 
  18705.                 MSdistribution_history dh2 where
  18706.                 dh2.agent_id = da.id) and
  18707.                 srvid = da.publisher_id and
  18708.                 s.agent_id = da.id and
  18709.                 p.publication_id = s.publication_id
  18710.     UNION -- Load distrbution dummy_rows
  18711.     select srvname, da.publisher_db, p.publication, p.publication_type, 3, 0, da.name from 
  18712.             master..sysservers, 
  18713.             MSdistribution_agents da,
  18714.             MSpublications p,
  18715.             MSsubscriptions s
  18716.             where 
  18717.                 srvid = da.publisher_id and
  18718.                 not exists (select * from MSdistribution_history dh where dh.agent_id = da.id) and
  18719.                 s.agent_id = da.id and
  18720.                 p.publication_id = s.publication_id
  18721.     UNION
  18722.     select srvname, ma.publisher_db, ma.publication, 2,
  18723.         case    when ma.subscriber_name is not null then 4 | @anonymous_mask
  18724.                 else 4
  18725.         end,
  18726.         runstatus, ma.name from 
  18727.         MSmerge_history mh1, master..sysservers, MSmerge_agents ma
  18728.         where timestamp = (select max(timestamp) from
  18729.             MSmerge_history mh2 where
  18730.             mh2.agent_id = ma.id) and
  18731.             srvid = ma.publisher_id 
  18732.  
  18733.     UNION
  18734.     select srvname, ma.publisher_db, ma.publication, 2, 4, 0, ma.name from 
  18735.         master..sysservers, MSmerge_agents ma
  18736.         where 
  18737.             srvid = ma.publisher_id and
  18738.             not exists (select * from MSmerge_history mh where mh.agent_id = ma.id)
  18739.  
  18740.     UNION -- queue reader        
  18741.     select 'publisher'= @@servername, 'publisher_db' = db_name(), 'publication' = 'ALL', 
  18742.             'publication_type' = 0, 'agent_type' = 9, 'status' = runstatus, 'agent_name' = la.name 
  18743.     from MSqreader_history lh1, MSqreader_agents la
  18744.     where lh1.timestamp = 
  18745.             (select max(timestamp) from MSqreader_history lh2 
  18746.             where lh2.agent_id = la.id) 
  18747.  
  18748.     order by publisher, publisher_db, publication
  18749.  
  18750. go
  18751.  
  18752. raiserror(15339,-1,-1,'sp_MSagent_stethoscope')
  18753. GO
  18754. CREATE PROCEDURE sp_MSagent_stethoscope (
  18755.     @heartbeat_interval int = 10  --minutes
  18756. )
  18757. as
  18758. BEGIN
  18759.     declare @current_time datetime
  18760.             ,@agent_name nvarchar(100)
  18761.             ,@agent_id int
  18762.             ,@job_id binary(16)
  18763.             ,@start_time datetime
  18764.             ,@duration int
  18765.             ,@comments nvarchar(255)
  18766.             ,@publisher_id smallint
  18767.             ,@publisher sysname
  18768.             ,@publisher_db sysname
  18769.             ,@heartbeat_failure bit
  18770.             ,@snapshot_type int
  18771.             ,@logreader_type int
  18772.             ,@distribution_type int
  18773.             ,@merge_type int
  18774.             ,@qreader_type int
  18775.             ,@histverboselevel tinyint
  18776.  
  18777.     --
  18778.     -- initialize
  18779.     --
  18780.     set nocount on
  18781.     select @snapshot_type = 1
  18782.             ,@logreader_type = 2
  18783.             ,@distribution_type = 3
  18784.             ,@merge_type = 4
  18785.             ,@qreader_type = 9
  18786.             ,@heartbeat_failure = 0
  18787.             ,@current_time = getdate()
  18788.             ,@comments = formatmessage(20554, @heartbeat_interval)
  18789.  
  18790.     -- If a running snapshot agent has not logged a history message within the specified
  18791.     -- heartbeat_interval then raise a agent suspect error
  18792.     declare hC_snapshot_suspect CURSOR LOCAL FAST_FORWARD for 
  18793.         select sh1.agent_id, sh1.start_time from MSsnapshot_history sh1 where
  18794.             (sh1.runstatus = 1 or sh1.runstatus = 3 or sh1.runstatus = 4) and
  18795.             dateadd(minute, @heartbeat_interval, sh1.time) < @current_time and
  18796.             sh1.timestamp = (select max(timestamp) from MSsnapshot_history where
  18797.                 agent_id= sh1.agent_id)
  18798.         for read only
  18799.  
  18800.     open hC_snapshot_suspect
  18801.     fetch hC_snapshot_suspect into @agent_id, @start_time
  18802.     while (@@fetch_status <> -1)
  18803.     begin
  18804.  
  18805.         set @heartbeat_failure = 1
  18806.  
  18807.         -- Get the agent name
  18808.         select @agent_name = name, @job_id = job_id from MSsnapshot_agents where id = @agent_id
  18809.  
  18810.         -- Log a "No action" message on behalf of the agent
  18811.         exec dbo.sp_MSadd_snapshot_history
  18812.             @agent_id = @agent_id,
  18813.             @runstatus = 6,     -- Failure status
  18814.             @comments = @comments,
  18815.             @do_raiserror = 0
  18816.  
  18817.         fetch hC_snapshot_suspect into @agent_id, @start_time
  18818.     end
  18819.     close hC_snapshot_suspect
  18820.     deallocate hC_snapshot_suspect
  18821.  
  18822.  
  18823.     -- If a running logreader agent has not logged a history message within the specified
  18824.     -- heartbeat_interval then raise a agent suspect error
  18825.     declare hC_logreader_suspect CURSOR LOCAL FAST_FORWARD for 
  18826.         select la.id, sh1.start_time from MSlogreader_agents la, MSlogreader_history sh1 where
  18827.             (sh1.runstatus = 1 or sh1.runstatus = 3 or sh1.runstatus = 4) and
  18828.             dateadd(minute, @heartbeat_interval, sh1.time) < @current_time and
  18829.             sh1.timestamp = (select max(timestamp) from MSlogreader_history where
  18830.                 agent_id= sh1.agent_id) and
  18831.             la.id = sh1.agent_id
  18832.         for read only
  18833.  
  18834.     open hC_logreader_suspect
  18835.     fetch hC_logreader_suspect into @agent_id, @start_time
  18836.     while (@@fetch_status <> -1)
  18837.     begin
  18838.         set @heartbeat_failure = 1
  18839.  
  18840.         -- Get the agent name
  18841.         select @agent_name = name, @job_id = job_id from MSlogreader_agents where id = @agent_id
  18842.  
  18843.         -- Log a "No action" message on behalf of the agent
  18844.         select @publisher_id = publisher_id, @publisher_db = publisher_db from MSlogreader_agents where id = @agent_id
  18845.         select @publisher = srvname from master..sysservers where srvid = @publisher_id
  18846.         exec dbo.sp_MSadd_logreader_history
  18847.             @agent_id = @agent_id,
  18848.             @runstatus = 6,     -- Failure status
  18849.             @comments = @comments,
  18850.             @do_raiserror = 0
  18851.  
  18852.         fetch hC_logreader_suspect into @agent_id, @start_time
  18853.     end
  18854.     close hC_logreader_suspect
  18855.     deallocate hC_logreader_suspect
  18856.  
  18857.     -- If a running distribution agent has not logged a history message within the specified
  18858.     -- heartbeat_interval then raise a agent suspect error
  18859.     declare hC_distribution_suspect CURSOR LOCAL FAST_FORWARD for 
  18860.         select sh1.agent_id, sh1.start_time from MSdistribution_history sh1 where
  18861.             (sh1.runstatus = 1 or sh1.runstatus = 3 or sh1.runstatus = 4) and
  18862.             dateadd(minute, @heartbeat_interval, sh1.time) < @current_time and
  18863.             sh1.timestamp = (select max(timestamp) from MSdistribution_history where
  18864.                 agent_id= sh1.agent_id)
  18865.         for read only
  18866.  
  18867.     open hC_distribution_suspect
  18868.     fetch hC_distribution_suspect into @agent_id, @start_time
  18869.     while (@@fetch_status <> -1)
  18870.     begin
  18871.         -- Get the agent name
  18872.         select @heartbeat_failure = 1
  18873.         select @agent_name = name, @job_id = job_id from MSdistribution_agents where id = @agent_id
  18874.  
  18875.         -- Log a "No action" message on behalf of the agent
  18876.         exec dbo.sp_MSadd_distribution_history
  18877.             @agent_id = @agent_id,
  18878.             @runstatus = 6,     -- Failure status
  18879.             @comments = @comments,
  18880.             @do_raiserror = 0
  18881.         fetch hC_distribution_suspect into @agent_id, @start_time
  18882.     end
  18883.     close hC_distribution_suspect
  18884.     deallocate hC_distribution_suspect
  18885.  
  18886.     -- If a running merge agent has not logged a history message within the specified
  18887.     -- heartbeat_interval then raise a agent suspect error
  18888.     declare hC_merge_suspect CURSOR LOCAL FAST_FORWARD for 
  18889.         select sh1.agent_id, sh1.start_time from MSmerge_history sh1 where
  18890.             (sh1.runstatus = 1 or sh1.runstatus = 3 or sh1.runstatus = 4) and
  18891.             dateadd(minute, @heartbeat_interval, sh1.time) < @current_time and
  18892.             sh1.timestamp = (select max(timestamp) from MSmerge_history where
  18893.                 agent_id= sh1.agent_id)
  18894.         for read only
  18895.  
  18896.     open hC_merge_suspect
  18897.     fetch hC_merge_suspect into @agent_id, @start_time
  18898.     while (@@fetch_status <> -1)
  18899.     begin
  18900.         set @heartbeat_failure = 1
  18901.  
  18902.         -- Get the agent name
  18903.         select @agent_name = name, @job_id = job_id from MSmerge_agents where id = @agent_id
  18904.  
  18905.         -- Log a "No action" message on behalf of the agent
  18906.         exec dbo.sp_MSadd_merge_history
  18907.             @agent_id = @agent_id,
  18908.             @runstatus = 6,     -- Failure status
  18909.             @comments = @comments,
  18910.             @do_raiserror = 0
  18911.  
  18912.         fetch hC_merge_suspect into @agent_id, @start_time
  18913.     end
  18914.     close hC_merge_suspect
  18915.     deallocate hC_merge_suspect
  18916.  
  18917.     -- If a running queuereader agent has not logged a history message within the specified
  18918.     -- heartbeat_interval then raise a agent suspect error
  18919.     declare hC_qrdr_suspect CURSOR LOCAL FAST_FORWARD for 
  18920.         select sh1.agent_id, sh1.start_time from MSqreader_history sh1 where
  18921.             (sh1.runstatus = 1 or sh1.runstatus = 3 or sh1.runstatus = 4) and
  18922.             dateadd(minute, @heartbeat_interval, sh1.time) < @current_time and
  18923.             sh1.timestamp = (select max(timestamp) from MSqreader_history where
  18924.                 agent_id= sh1.agent_id)
  18925.         for read only
  18926.  
  18927.     open hC_qrdr_suspect
  18928.     fetch hC_qrdr_suspect into @agent_id, @start_time
  18929.     while (@@fetch_status <> -1)
  18930.     begin
  18931.         set @heartbeat_failure = 1
  18932.  
  18933.         -- Get the agent name
  18934.         select @agent_name = name, @job_id = job_id from MSqreader_agents where id = @agent_id
  18935.  
  18936.         -- Log a "No action" message on behalf of the agent
  18937.         exec dbo.sp_MSadd_qreader_history
  18938.             @agent_id = @agent_id,
  18939.             @runstatus = 6,     -- Failure status
  18940.             @comments = @comments,
  18941.             @do_raiserror = 0
  18942.  
  18943.         fetch hC_qrdr_suspect into @agent_id, @start_time
  18944.     end
  18945.     close hC_qrdr_suspect
  18946.     deallocate hC_qrdr_suspect
  18947.  
  18948.     -- Log all is fine message
  18949.     if @heartbeat_failure = 0
  18950.         -- "Detected heartbeat for all running Replication Agents"
  18951.         set @comments = formatmessage(20556)    
  18952.     else
  18953.         -- "Could not detected heartbeat for all running Replication Agents"
  18954.         set @comments = formatmessage(20580)    
  18955.  
  18956.     raiserror (20554, 10, -1, @heartbeat_interval)
  18957. END
  18958. GO
  18959.  
  18960. raiserror(15339,-1,-1,'sp_MSlock_distribution_agent')
  18961. GO
  18962.  
  18963. CREATE PROCEDURE sp_MSlock_distribution_agent (
  18964.     @id int,
  18965.     @mode int = 1 -- 0: shared  1: exclusive
  18966. ) AS
  18967.  
  18968.  
  18969.     SET         NOCOUNT ON
  18970.     DECLARE     @active tinyint
  18971.     declare     @count  int
  18972.     select @active = 2
  18973.     if @mode = 0
  18974.         select @count = count(*) from MSsubscriptions (ROWLOCK REPEATABLEREAD) where agent_id = @id and status = @active
  18975.     else
  18976.         select @count = count(*) from MSsubscriptions (ROWLOCK UPDLOCK) where agent_id = @id and status = @active
  18977. GO
  18978.  
  18979. raiserror(15339,-1,-1,'sp_MSdetect_nonlogged_shutdown')
  18980. GO
  18981. create procedure sp_MSdetect_nonlogged_shutdown
  18982. @subsystem nvarchar(60),
  18983. @agent_id int
  18984. as
  18985.     declare @job_id binary(16)
  18986.     declare @agent_name nvarchar(100)
  18987.     declare @message nvarchar(1024)
  18988.     declare @retcode int
  18989.     declare @runstatus int
  18990.  
  18991.     -- Detect if the agent was shutdown without a logged reason
  18992.     if UPPER(@subsystem) = 'SNAPSHOT'
  18993.     begin
  18994.         if exists (select runstatus from MSsnapshot_history where 
  18995.             agent_id = @agent_id and
  18996.             runstatus <> 2 and 
  18997. --CAC       runstatus <> 5 and 
  18998.             runstatus <> 6 and
  18999.             timestamp = (select max(timestamp) from MSsnapshot_history where agent_id = @agent_id))
  19000.             begin
  19001.                 select @job_id = job_id, @agent_name = name from MSsnapshot_agents where id = @agent_id
  19002.             end
  19003.     end
  19004.     else if UPPER(@subsystem) = 'LOGREADER'
  19005.     begin
  19006.         if exists (select runstatus from MSlogreader_history where 
  19007.             agent_id = @agent_id and
  19008.             runstatus <> 2 and 
  19009. --CAC           runstatus <> 5 and 
  19010.             runstatus <> 6 and
  19011.             timestamp = (select max(timestamp) from MSlogreader_history where agent_id = @agent_id))
  19012.             begin
  19013.                 select @job_id = job_id, @agent_name = name from MSlogreader_agents where id = @agent_id
  19014.             end
  19015.     end
  19016.     else if UPPER(@subsystem) = 'DISTRIBUTION'
  19017.     begin
  19018.         if exists (select runstatus from MSdistribution_history where 
  19019.             agent_id = @agent_id and
  19020.             runstatus <> 2 and 
  19021. --CAC           runstatus <> 5 and 
  19022.             runstatus <> 6 and
  19023.             timestamp = (select max(timestamp) from MSdistribution_history where agent_id = @agent_id))
  19024.             begin
  19025.                 select @job_id = job_id, @agent_name = name from MSdistribution_agents where id = @agent_id
  19026.             end
  19027.     end
  19028.     else if UPPER(@subsystem) = 'MERGE'
  19029.     begin
  19030.         if exists (select runstatus from MSmerge_history where 
  19031.             agent_id = @agent_id and
  19032.             runstatus <> 2 and 
  19033. --CAC           runstatus <> 5 and 
  19034.             runstatus <> 6 and
  19035.             timestamp = (select max(timestamp) from MSmerge_history where agent_id = @agent_id))
  19036.             begin
  19037.                 select @job_id = job_id, @agent_name = name from MSmerge_agents where id = @agent_id
  19038.             end
  19039.     end
  19040.     else if UPPER(@subsystem) = 'QUEUEREADER'
  19041.     begin
  19042.         if exists (select runstatus from MSqreader_history where 
  19043.             agent_id = @agent_id and
  19044.             runstatus <> 2 and 
  19045. --CAC       runstatus <> 5 and 
  19046.             runstatus <> 6 and
  19047.             timestamp = (select max(timestamp) from MSqreader_history where agent_id = @agent_id))
  19048.             begin
  19049.                 select @job_id = job_id, @agent_name = name from MSqreader_agents where id = @agent_id
  19050.             end
  19051.     end
  19052.  
  19053.     -- If no job_id assume shutdown was logged properly
  19054.     if @job_id is null
  19055.         return 0
  19056.  
  19057.     -- Get last message from SQL Agent History table
  19058.     create table #JobHistory (
  19059.         instance_id int NOT NULL, 
  19060.         job_id uniqueidentifier NOT NULL,
  19061.         job_name nvarchar(100) NOT NULL,
  19062.         step_id int NOT NULL,
  19063.         step_name nvarchar(100) NOT NULL, 
  19064.         sql_message_id int NOT NULL,
  19065.         sql_severity int NOT NULL,
  19066.         message nvarchar(1024) NOT NULL,
  19067.         run_status int NOT NULL,
  19068.         run_date int NOT NULL,
  19069.         run_time int NOT NULL,
  19070.         run_duration int NOT NULL,
  19071.         operator_emailed sysname NULL,
  19072.         operator_netsent sysname NULL,
  19073.         operator_paged sysname NULL,
  19074.         retries_attempted int NOT NULL,
  19075.         server sysname NOT NULL
  19076.     )
  19077.     if @@error <> 0
  19078.         return 1
  19079.  
  19080.     -- Insert last history for step_id 2 (Agent running)
  19081.     set rowcount 1
  19082.     insert into #JobHistory exec msdb.dbo.sp_help_jobhistory @job_id = @job_id, @step_id = 2, 
  19083.         @mode = 'FULL'          
  19084.  
  19085.     -- Get the last history
  19086.     select @message = message, @runstatus = run_status from #JobHistory
  19087.  
  19088.     -- Reset rowcount
  19089.     set rowcount 0
  19090.  
  19091.     -- Map SQL Agent runstatus to Replication runstatus
  19092.     set @runstatus = 
  19093.     case @runstatus
  19094.         when 0 then 6   -- Fail mapping
  19095.         when 1 then 2   -- Success mapping
  19096.         when 2 then 5   -- Retry mapping
  19097.         when 3 then 2   -- Shutdown mapping
  19098.         when 4 then 3   -- Inprogress mapping
  19099.         when 5 then 0   -- Unknown is mapped to never run
  19100.     end
  19101.  
  19102.     -- If no message, provide a default message
  19103.     -- Also overwrite all inprogress messages to be "See SQL Agent history log".
  19104.     -- This is to prevent "Agent running. See monitor" to be logged into repl monitor.
  19105.     -- In this case (the last job history message is InProgress), we know that
  19106.     -- there have been failures of SQL Server Agent history logging.
  19107.     -- In fact, the only possible "in progress" msg in SQL Agent job step
  19108.     -- history for push jobs is "Agent running. See monitor". It is confusing that those
  19109.     -- messages showed up in repl monitor.
  19110.     if @message is null or @runstatus = 3
  19111.         select @message = formatmessage(20557, @agent_name)
  19112.  
  19113.     if UPPER(@subsystem) = 'SNAPSHOT'
  19114.         exec @retcode = dbo.sp_MSadd_snapshot_history @agent_id = @agent_id, @runstatus = @runstatus,
  19115.                 @comments = @message
  19116.     else if UPPER(@subsystem) = 'LOGREADER'
  19117.         exec @retcode = dbo.sp_MSadd_logreader_history @agent_id = @agent_id, @runstatus = @runstatus,
  19118.                 @comments = @message
  19119.     else if UPPER(@subsystem) = 'DISTRIBUTION'
  19120.         exec @retcode = dbo.sp_MSadd_distribution_history @agent_id = @agent_id, @runstatus = @runstatus,
  19121.                 @comments = @message
  19122.     else if UPPER(@subsystem) = 'MERGE'
  19123.         exec @retcode = dbo.sp_MSadd_merge_history @agent_id = @agent_id, @runstatus = @runstatus,
  19124.                 @comments = @message
  19125.     else if UPPER(@subsystem) = 'QUEUEREADER'
  19126.         exec @retcode = dbo.sp_MSadd_qreader_history @agent_id = @agent_id, @runstatus = @runstatus,
  19127.                 @comments = @message
  19128.  
  19129.     if @@error <> 0 or @retcode <> 0
  19130.         return 1
  19131.  
  19132.     drop table #JobHistory
  19133.  
  19134. GO
  19135.  
  19136. raiserror(15339,-1,-1,'sp_MSpublication_access')
  19137. GO
  19138.  
  19139. CREATE PROCEDURE sp_MSpublication_access (
  19140.     @publisher sysname,
  19141.     @publisher_db sysname = NULL,
  19142.     @publication sysname = NULL,
  19143.     @login sysname = NULL,
  19144.     @operation nvarchar(20), -- Can be add/drop/check/help/get_publications/get_logins
  19145.     @has_access bit = 0 output, -- Used only in check
  19146.     @skip bit = 0
  19147.         ) AS
  19148. -- This sp can be called repeatedly.
  19149.     
  19150.     declare @publisher_id smallint
  19151.     declare @retcode int
  19152.     declare @publication_id int
  19153.     declare @isntname bit
  19154.     declare @server_access bit
  19155.     declare @privilege nchar(21)
  19156.  
  19157.     -- Check if publisher is a defined as a distribution publisher in the current database
  19158.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  19159.     if @retcode <> 0
  19160.     begin
  19161.         return(1)
  19162.     end
  19163.  
  19164.     -- Check to see if the login exists and if the login is NT login
  19165.     select @isntname = isntname from master..syslogins where
  19166.         sid = suser_sid(@login) and
  19167.         hasaccess = 1
  19168.  
  19169.     -- Get the publication id 
  19170.     select @publication_id = publication_id from MSpublications where 
  19171.         publisher_id = @publisher_id and
  19172.         publisher_db = @publisher_db and
  19173.         publication = @publication
  19174.  
  19175.     -- Publication does not exist
  19176.     if @publication_id is null and
  19177.         @operation in ('add','drop','check','help')
  19178.     begin
  19179.         raiserror (20026, 16, -1, @publication)
  19180.         return (1)
  19181.     end
  19182.  
  19183.     if @operation = 'add'
  19184.     begin
  19185.         -- Login does not have access
  19186.         if @isntname is null
  19187.         begin
  19188.             if @skip = 0
  19189.             begin
  19190.                 raiserror(21048, 16, -1, @login, @@servername) 
  19191.                 return (1)
  19192.             end
  19193.             else
  19194.                 return (0)
  19195.         end
  19196.  
  19197.         -- Add login to the access list if it does not exist
  19198.         if not exists (select * from MSpublication_access where
  19199.             publication_id = @publication_id and
  19200.             login = @login)
  19201.         begin
  19202.             insert MSpublication_access (publication_id, login)
  19203.                 values (@publication_id,@login)
  19204.             if  @@error <> 0
  19205.                 return(1)
  19206.         end
  19207.     end
  19208.     else if @operation = 'drop'
  19209.     begin
  19210.         if @isntname is null and not exists (select * from MSpublication_access where
  19211.                 publication_id = @publication_id and
  19212.                 login = @login) 
  19213.         begin
  19214.             raiserror(15007,10,-1,@login)
  19215.             return 1
  19216.         end
  19217.         -- Do check existense when dropping since the login might be dropped
  19218.         -- outside replication already.
  19219.         delete MSpublication_access where
  19220.                 publication_id = @publication_id and
  19221.                 login = @login
  19222.         if  @@error <> 0
  19223.             return(1)
  19224.     end
  19225.     else if @operation = 'check'
  19226.     begin
  19227.         -- Cover the case when
  19228.         -- the NT user is not in syslogins
  19229.         if @isntname is null and suser_sid(@login) is not null
  19230.             select @isntname = 1
  19231.  
  19232.         -- If the login is valid NT login, call set user
  19233.         if @isntname = 1
  19234.         begin
  19235.             setuser @login
  19236.             if @@error <> 0
  19237.             begin
  19238.                 raiserror (21142, 16, -1, @@servername, @login)
  19239.                 return(1)
  19240.             end
  19241.         end
  19242.         if exists (select * from MSpublication_access l where
  19243.             publication_id = @publication_id and
  19244.             (l.login = @login or (@isntname = 1 and exists (select * from master..syslogins
  19245.                 where sid = suser_sid(l.login) and isntgroup = 1 and is_member(l.login) = 1))))
  19246.             set @has_access = 1
  19247.         else
  19248.             set @has_access = 0
  19249.         if @isntname = 1
  19250.         begin
  19251.             setuser
  19252.             if @@error <> 0
  19253.                 return(1)
  19254.         end        
  19255.     end
  19256.     else if @operation = 'help'
  19257.     begin
  19258.         select login from MSpublication_access where
  19259.                     publication_id = @publication_id and
  19260.                     login like @login
  19261.     end
  19262.     else if @operation = 'get_publications'
  19263.     begin
  19264.         -- Avoid setuser failure and cover the case of that 
  19265.         -- the NT user is not in syslogins
  19266.         if @isntname is null and suser_sid(@login) is not null
  19267.         begin
  19268.             exec @retcode = master.dbo.xp_logininfo
  19269.                 @login, N'all', @privilege output
  19270.             if @privilege is not null
  19271.                 select @isntname = 1
  19272.         end
  19273.  
  19274.         -- If the login is valid NT login, call set user
  19275.         if @isntname = 1
  19276.         begin
  19277.             setuser @login
  19278.             -- If the login is invalid, don't return any result.
  19279.             if @@error <> 0
  19280.             begin
  19281.                 raiserror (21142, 16, -1, @@servername, @login)
  19282.                 return(0)
  19283.             end
  19284.         end
  19285.         select p.publisher_db, p.publication from MSpublication_access l,
  19286.             MSpublications p where
  19287.             -- Get all the non default publications that have the login in the access list
  19288.             (
  19289.             -- If login match or there is an NT group in the access list and @login is integrated
  19290.             (l.login = @login or ( @isntname = 1 and exists (select * from master..syslogins
  19291.                 where sid = suser_sid(l.login) and isntgroup = 1 and is_member(l.login) = 1))) and
  19292.             l.publication_id = p.publication_id and
  19293.             p.publisher_id = @publisher_id
  19294.             ) 
  19295.         if @isntname = 1
  19296.         begin
  19297.             setuser
  19298.             if @@error <> 0
  19299.                 return(1)
  19300.         end        
  19301.     end
  19302.     else if @operation = 'get_logins'
  19303.     begin
  19304.         select loginname from master..syslogins where
  19305.             hasaccess = 1
  19306.     end
  19307. GO
  19308.  
  19309.  
  19310. raiserror(15339,-1,-1,'sp_MSdrop_6x_publication')
  19311. GO
  19312.  
  19313. -- This stored procedure is called by sp_droptask when 6.x publications are dropped.
  19314. create procedure sp_MSdrop_6x_publication
  19315. @job_id UNIQUEIDENTIFIER
  19316. as
  19317.     declare @publisher sysname
  19318.     declare @publisher_db sysname
  19319.     declare @publication sysname
  19320.     declare @retcode int
  19321.  
  19322.     -- Get publication information
  19323.     select @publisher = srvname, @publisher_db = publisher_db, @publication = publication from 
  19324.         MSsnapshot_agents, master..sysservers where
  19325.         job_id = @job_id and
  19326.         srvid = publisher_id
  19327.  
  19328.     -- Remove the publication and snapshot agent
  19329.     exec @retcode = dbo.sp_MSdrop_publication
  19330.         @publisher = @publisher,
  19331.         @publisher_db = @publisher_db,
  19332.         @publication = @publication 
  19333.     if @@ERROR <> 0 or @retcode <> 0
  19334.         return 1
  19335. GO
  19336.  
  19337. raiserror(15339,-1,-1,'sp_MShelp_distribution_agentid')
  19338. GO
  19339.  
  19340. CREATE PROCEDURE sp_MShelp_distribution_agentid
  19341. @publisher_id smallint,
  19342. @publisher_db sysname,
  19343. @publication sysname = NULL,
  19344. @subscriber_id smallint,
  19345. @subscriber_db sysname,
  19346. @subscription_type int, /* 0 = push 1 = pull 2=anonymous, */
  19347. -- For anonymous only
  19348. @subscriber_name    sysname = NULL,
  19349. @anonymous_subid    uniqueidentifier = NULL,
  19350. @reinitanon         bit = 0
  19351.  
  19352. as
  19353.  
  19354.     set nocount on
  19355.  
  19356.     declare @independent_agent bit
  19357.     declare @xact_seqno_length int
  19358.     declare @agent_id int
  19359.     declare @third_party_flag bit
  19360.     declare @retcode int
  19361.     declare @anonymous int
  19362.     declare @sub_agent_id int
  19363.     declare @allow_subscription_copy bit
  19364.     declare @immediate_sync bit
  19365.  
  19366.     select @anonymous = 2
  19367.     
  19368.     if @publication is null
  19369.         select @independent_agent = 0
  19370.     else
  19371.         select @independent_agent = 1
  19372.  
  19373.     select  top 1
  19374.         @third_party_flag = thirdparty_flag,
  19375.         @allow_subscription_copy = allow_subscription_copy,
  19376.         @immediate_sync = immediate_sync
  19377.         from MSpublications where
  19378.         publisher_id = @publisher_id and
  19379.         publisher_db = @publisher_db and
  19380.         publication = @publication or 
  19381.         (@publication is null and independent_agent = 0)
  19382.  
  19383.     -- Get agent id
  19384.     if @subscription_type = @anonymous
  19385.     begin
  19386.         exec @retcode = dbo.sp_MSadd_anonymous_agent
  19387.             @publisher_id   = @publisher_id,
  19388.             @publisher_db   = @publisher_db,
  19389.             @publication    = @publication,
  19390.             @subscriber_db  = @subscriber_db,
  19391.             @subscriber_name = @subscriber_name,
  19392.             @anonymous_subid =  @anonymous_subid output,
  19393.             @agent_id = @agent_id output,
  19394.             @reinitanon = @reinitanon
  19395.         if @@error <> 0 or @retcode <> 0
  19396.             return (1)
  19397.  
  19398.         -- Refer to sp_MSget_subscription_guid
  19399.         select @sub_agent_id = virtual_agent_id from
  19400.             MSdistribution_agents where
  19401.             id = @agent_id
  19402.     end 
  19403.     else
  19404.     begin
  19405.         select @agent_id = id
  19406.         from MSdistribution_agents where
  19407.              publisher_id = @publisher_id and
  19408.              publisher_db = @publisher_db and
  19409.              (publication = @publication or
  19410.              (@publication is null and publication = N'ALL')) and
  19411.              subscription_type = @subscription_type and
  19412.              subscriber_id = @subscriber_id and
  19413.              subscriber_db = @subscriber_db
  19414.  
  19415.         -- If cannont find the agent entry, ignore @subscriber_db and try again 
  19416.         -- for non SQL subscribers
  19417.         -- Note that this preserved backward compatibility for 7.0 publisher, 7.0 pull distribution agent or 6.5 pub.
  19418.         -- In 7.0, we hard code name 'DSN'.
  19419.         -- In 6.5 pub, the db name is real database name.
  19420.         -- In 8.0, distribution agent sends in unlocalized '(default destination)' as default db name for 
  19421.         -- non SQL subscribers..
  19422.         if @agent_id is null 
  19423.         begin
  19424.             declare @publisher sysname
  19425.             declare @subscriber sysname
  19426.             select @publisher = srvname from master..sysservers where
  19427.                 srvid = @publisher_id
  19428.             select @subscriber = srvname from master..sysservers where
  19429.                 srvid = @subscriber_id
  19430.             if exists (select * from MSsubscriber_info where
  19431.                 publisher = @publisher and
  19432.                 subscriber = @subscriber and
  19433.                 type <> 0)
  19434.             begin
  19435.                 select @agent_id = id
  19436.                 from MSdistribution_agents where
  19437.                      publisher_id = @publisher_id and
  19438.                      publisher_db = @publisher_db and
  19439.                      (publication = @publication or
  19440.                      (@publication is null and publication = N'ALL')) and
  19441.                      subscription_type = @subscription_type and
  19442.                      subscriber_id = @subscriber_id 
  19443.             end
  19444.         end
  19445.  
  19446.         select @sub_agent_id = @agent_id
  19447.     end
  19448.  
  19449.     -- If cannot find the publication and the agent, raise error
  19450.     -- saying invalid publication.
  19451.     -- Note: can not fail if publication not exists but agent exists
  19452.     -- It is an upgrade case. 
  19453.     if @third_party_flag is null and @agent_id is null
  19454.     begin
  19455.         -- The publication(s) does not exist
  19456.         RAISERROR (21073, 16, -1)
  19457.         return(1)
  19458.     end
  19459.  
  19460.     if @agent_id is null
  19461.     begin
  19462.         -- Raise a special error for a common error case: user specified publication
  19463.         -- name for non independent agent publication.
  19464.         -- If the specified publication name is in MSpublications table then
  19465.         -- the publication is configured to use a non-independent distribution
  19466.         -- agent. Raise a different error if this is the case
  19467.         if @publication is not null and 
  19468.             exists (select * from MSpublications 
  19469.                     where publication = @publication and 
  19470.                           publisher_id = @publisher_id and
  19471.                           publisher_db = @publisher_db and
  19472.                           independent_agent = 0)  
  19473.         begin
  19474.             RAISERROR (21133, 16, -1, @publication)
  19475.         end
  19476.         else
  19477.         begin
  19478.             -- Invalid subscription
  19479.             RAISERROR (21056, 16, -1, @publication)
  19480.         end
  19481.         return(1)
  19482.     end
  19483.  
  19484.     -- Reset null properties
  19485.     -- It is an upgrade case. 
  19486.     if @third_party_flag is null 
  19487.         select @third_party_flag = 0
  19488.     if @allow_subscription_copy is null
  19489.         select @allow_subscription_copy = 0
  19490.  
  19491.     /*
  19492.     ** Get the time when the subscription is active and succeed.
  19493.     */
  19494.     /*
  19495.     select Top 1 @last_status=runstatus, @last_sync = time from MSdistribution_history 
  19496.         where agent_id = @agent_id order by timestamp DESC
  19497.     
  19498.     if @last_status = 6 and EXISTS (select * from MSdistribution_history where agent_id = @agent_id and runstatus = @success) 
  19499.                 select Top 1 @last_sync = time from MSdistribution_history where agent_id = @agent_id and runstatus = @success
  19500.                         order by timestamp DESC    
  19501.  
  19502.     if @last_sync is not NULL and @independent_agent = 1 --by pass the retention check for non-independent agnt
  19503.     begin
  19504.         if (@last_sync < dateadd(hour, -@retention, getdate()))
  19505.            and (@retention <> 0)
  19506.                  select @expired = 1 
  19507.     end
  19508.     */
  19509.  
  19510.     /* 
  19511.     ** Avoid returning a NULL value 
  19512.     ** Otherwise, distribution agent may fail
  19513.     */
  19514.     select @xact_seqno_length = 0
  19515.  
  19516.     /* 
  19517.     **  Get the lengh of xact_seqno
  19518.     **   Currently, unique across the publisher
  19519.     */
  19520.     select top 1 @xact_seqno_length = DATALENGTH(subscription_seqno)
  19521.     from MSsubscriptions s where
  19522.         agent_id = @sub_agent_id
  19523.  
  19524.     /* xact_seqno for snapshot trans are longer for native publishers*/
  19525.     if @third_party_flag = 0
  19526.     begin
  19527.         if @xact_seqno_length = 8 or @xact_seqno_length = 10
  19528.             select @xact_seqno_length = @xact_seqno_length + 4
  19529.     end
  19530.  
  19531.     -- Security check. Do it here to let the agent fail at the beginning
  19532.     exec @retcode = dbo.sp_MScheck_pull_access
  19533.         @agent_id = @sub_agent_id,
  19534.         @agent_type = 0 -- distribution agent
  19535.     if @@error <> 0 or @retcode <> 0
  19536.         return (1)
  19537.     
  19538.     -- Get update_mode
  19539.     declare @update_mode int
  19540.     
  19541.     -- Use max because:
  19542.     -- One agent can have mixed read only (0) and synctran (1) subscriptions. 
  19543.     -- The update mode value
  19544.     -- is used in subscriber triggers. It is ok to set update mode to synctran
  19545.     -- in mixed case because the triggers will not be create for read only.
  19546.     -- Queued mode require independent agent.
  19547.     select @update_mode = max(update_mode) from MSsubscriptions where
  19548.         agent_id = @agent_id
  19549.     
  19550.     -- For anonymous agents, update_mode is read only.
  19551.     if @update_mode is null
  19552.         set @update_mode = 0
  19553.  
  19554.     -- Get attach_version guid
  19555.     declare @attach_version binary(16)
  19556.     if @allow_subscription_copy <> 0
  19557.     begin
  19558.         declare @publication_id int
  19559.         declare @virtual_agent_id int
  19560.         declare @virtual smallint
  19561.         set @virtual = -1
  19562.  
  19563.         -- Get publication_id
  19564.         select @publication_id = publication_id
  19565.             from MSpublications where
  19566.             publisher_id = @publisher_id and
  19567.             publisher_db = @publisher_db and
  19568.             publication = @publication 
  19569.  
  19570.         if @publication_id is null
  19571.         begin
  19572.             RAISERROR (21040, 16, -1, @publication)
  19573.             return 1
  19574.         end
  19575.  
  19576.         -- Get version agent_id
  19577.         select top 1 @virtual_agent_id = agent_id from MSsubscriptions where
  19578.             publisher_id = @publisher_id and
  19579.             publisher_db = @publisher_db and
  19580.             publication_id = @publication_id and
  19581.             subscriber_id = @virtual
  19582.  
  19583.         select @attach_version = subscription_guid from MSdistribution_agents
  19584.             where id = @virtual_agent_id
  19585.     end
  19586.     else
  19587.         -- set a irrelevent guid. It should never be used.
  19588.         select @attach_version = newid()
  19589.  
  19590.     -- Get subscription guid
  19591.     -- Use sub_agent_id so that both anonymous and well-known work.
  19592.     -- Refer to sp_MSget_subscription_guid. You need to make change to that sp when changing
  19593.     -- this.
  19594.     declare @subscription_guid binary(16)
  19595.     select @subscription_guid = subscription_guid from MSdistribution_agents where
  19596.         id = @sub_agent_id
  19597.  
  19598.     select 
  19599.         'xact_seqno_length' = @xact_seqno_length,
  19600.         'agent_id' = @agent_id,
  19601.         'agent_name' = name,
  19602.         'anonymous subid' = anonymous_subid,
  19603.         'expired ' = convert(int, 0),
  19604.         'dts_package_name' = dts_package_name,
  19605.         'dts_package_password' = dts_package_password,
  19606.         'dts_package_location' = dts_package_location,
  19607.         'immediate_sync' = @immediate_sync,
  19608.         'allow_subscription_copy' = @allow_subscription_copy,
  19609.         'queue_id' = queue_id,
  19610.         'update_mode' = @update_mode,
  19611.         'attach_version' = @attach_version,
  19612.         'subscription_guid' = @subscription_guid
  19613.         
  19614.         from MSdistribution_agents where id = @agent_id
  19615.  
  19616. GO
  19617.  
  19618. raiserror(15339,-1,-1,'sp_MScheck_tran_retention')
  19619. GO
  19620.  
  19621. CREATE PROCEDURE sp_MScheck_tran_retention
  19622. @xact_seqno varbinary(16),
  19623. @agent_id int
  19624. as
  19625.  
  19626.     set nocount on
  19627.  
  19628.     declare @date datetime
  19629.     declare @retention int
  19630.     declare    @expired int
  19631.     declare @publisher_database_id int
  19632.  
  19633.     select @publisher_database_id = publisher_database_id from MSdistribution_agents
  19634.         where id = @agent_id
  19635.  
  19636.     select @date = entry_time from MSrepl_transactions where
  19637.         xact_seqno = @xact_seqno and
  19638.         publisher_database_id = @publisher_database_id
  19639.  
  19640.     select @retention = max_distretention from msdb..MSdistributiondbs where
  19641.         name = db_name()
  19642.  
  19643.     if (@date is not null and datediff(minute, @date, getdate()) < @retention*60) or
  19644.         -- For 'sync with backup' dist db where
  19645.         -- the dist db might be restored to a previous version so that the subscriber's
  19646.         -- xact_seqno is larger.
  19647.        (@date is null and not exists (select * from MSrepl_transactions where
  19648.         xact_seqno >= @xact_seqno and
  19649.         publisher_database_id = @publisher_database_id))
  19650.         select @expired = 0
  19651.     else
  19652.         select @expired = 1
  19653.     
  19654.     select N'expired' = @expired
  19655.  
  19656. GO
  19657.  
  19658. raiserror(15339,-1,-1,'sp_MSmarkreinit')
  19659. GO
  19660. CREATE PROCEDURE sp_MSmarkreinit
  19661. @publisher sysname,
  19662. @publisher_db sysname,
  19663. @publication sysname,
  19664. @subscriber sysname,       
  19665. @subscriber_db sysname,
  19666. @reset_reinit    int
  19667. AS
  19668.     set nocount on
  19669.  
  19670.     declare @publisher_id smallint
  19671.     declare @subscriber_id smallint
  19672.     declare @publication_id int
  19673.     declare @retcode int
  19674.     declare @reinited int
  19675.     declare @unreinited int
  19676.     declare @status int
  19677.  
  19678.     select @reinited = 4  -- status=4 means this subscription has been reinited
  19679.     select @unreinited = 1 -- status=1 means this subscription not reinited
  19680.  
  19681.     if @reset_reinit = 1
  19682.         select @status = @reinited
  19683.     else
  19684.         select @status = @unreinited
  19685.     
  19686. -- Check if publisher is a defined as a distribution publisher in the current database
  19687.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  19688.     if @retcode <> 0
  19689.     begin
  19690.         return(1)
  19691.     end
  19692.  
  19693.     -- Get the publication information 
  19694.     select @publication_id = publication_id
  19695.         from MSpublications where 
  19696.         publisher_id = @publisher_id and
  19697.         publisher_db = @publisher_db and
  19698.         publication = @publication
  19699.     if @publication_id is NULL
  19700.     begin
  19701.         raiserror (20026, 11, -1, @publication)
  19702.         return (1)
  19703.     end
  19704.  
  19705.     -- Get subscriber info
  19706.     select @subscriber_id = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  19707.  
  19708.     update MSmerge_subscriptions set status = @status where
  19709.         publisher_id = @publisher_id and 
  19710.         publisher_db = @publisher_db and 
  19711.         publication_id = @publication_id and
  19712.         subscriber_id = @subscriber_id and
  19713.         subscriber_db = @subscriber_db
  19714.     if @@error<>0 
  19715.         return (1)
  19716. GO        
  19717.  
  19718. raiserror('Creating procedure sp_MSfetchAdjustidentityrange', 0,1)
  19719. GO
  19720.  
  19721. CREATE PROCEDURE sp_MSfetchAdjustidentityrange 
  19722.     @publisher            sysname,
  19723.     @publisher_db        sysname,
  19724.     @tablename            sysname,
  19725.     @adjust_only        bit = 0,
  19726.     @for_publisher        tinyint = 0, --0 for subscriber, 1 for publisher, 2 for republisher
  19727.     @range                bigint = 0 output, -- This parameter is used as input for publisher but output for subscriber
  19728.     @next_seed            bigint = 0 output,
  19729.     @threshold            int = 0 output
  19730. as    
  19731.     if @adjust_only=0
  19732.         select identity_support, next_seed, range, threshold from MSrepl_identity_range
  19733.             where  tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  19734.  
  19735.     -- Note: there might be multiple sessions calling this sp at the same time
  19736.     -- Open a transaction so that the update row will be locked so that no one else can
  19737.     -- process this row.
  19738.     begin tran
  19739.     save TRAN sp_MSfetchAdjustidentityrange
  19740.  
  19741.     if @for_publisher=2 --republishing scenario
  19742.     begin
  19743.         update MSrepl_identity_range set max_identity=@next_seed + @range, next_seed=@next_seed
  19744.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db            
  19745.     end
  19746.     else
  19747.     begin    
  19748.         update MSrepl_identity_range set next_seed = case @for_publisher
  19749.             -- use subscriber's range 
  19750.             when 0 then next_seed + range
  19751.             -- use @range sent in by the publisher
  19752.             else next_seed + @range
  19753.             end
  19754.         where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  19755.     end
  19756.  
  19757.     -- for tran pub, max_identity is null
  19758.     if @@ERROR<>0 OR exists (select * from MSrepl_identity_range where ABS(next_seed)>ABS(max_identity))
  19759.     begin
  19760.         raiserror(21195, 16, -1)
  19761.         goto UNDO
  19762.     end
  19763.  
  19764.     select @next_seed = next_seed, @range = range, @threshold = threshold from MSrepl_identity_range
  19765.         where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  19766.     
  19767.     commit tran
  19768.     return 0
  19769.  
  19770. UNDO:
  19771.     if @@TRANCOUNT > 0
  19772.     begin
  19773.         ROLLBACK TRAN sp_MSfetchAdjustidentityrange
  19774.         COMMIT TRAN
  19775.     end
  19776.     return(1)
  19777.  
  19778. go            
  19779. exec dbo.sp_MS_marksystemobject sp_MSfetchAdjustidentityrange 
  19780. go
  19781. grant exec on dbo.sp_MSfetchAdjustidentityrange to public
  19782. go
  19783.  
  19784. raiserror(15339,-1,-1,'sp_MSreinit_subscription')
  19785. GO
  19786. CREATE PROCEDURE sp_MSreinit_subscription
  19787. @publisher_name sysname,
  19788. @publisher_db sysname,
  19789. @publication sysname = 'all',
  19790. @subscriber_name    sysname = 'all',
  19791. @subscriber_db sysname = 'all'
  19792. as
  19793.     set nocount on
  19794.     declare @proc nvarchar(2048)
  19795.     declare @retcode int
  19796.  
  19797.     if @publisher_name IS NULL or NOT EXISTS (select * from master..sysservers as ss, MSpublications as msp
  19798.         where lower(ss.srvname) = lower(@publisher_name) and msp.publisher_id = ss.srvid)
  19799.     begin
  19800.         return (1)
  19801.     end
  19802.  
  19803.     if @publisher_db IS NULL
  19804.         select @publisher_db = ''
  19805.  
  19806.     select @proc = @publisher_name + '.' + @publisher_db + '.dbo.sp_reinitsubscription '
  19807.     exec @retcode = @proc @publication, 'all', @subscriber_name, @subscriber_db
  19808.  
  19809.     return (@retcode)
  19810. go
  19811.  
  19812.    -- View for delivered and undelivered commands.   RHS  6-4-98
  19813.    -- Since the view is likely to change, just recreate it each time.
  19814.    IF EXISTS (SELECT * FROM sysobjects where name='MSdistribution_status' and type='V')
  19815.     DROP VIEW dbo.MSdistribution_status
  19816.  
  19817.     /****************************************************************************/
  19818.     raiserror('Creating view MSdistribution_status', 0,1)
  19819.         /****************************************************************************/    
  19820. go
  19821.  
  19822. CREATE VIEW MSdistribution_status (article_id,agent_id,UndelivCmdsInDistDB,DelivCmdsInDistDB)
  19823. as
  19824. -- Note that this view does not account for (i.e. exclude from counts) commands that do not need to be delivered 
  19825. -- because of loopback or syncronous updating subscribers, nor subscriptions never activated.
  19826. -- It also may not be exact due to use of NOLOCK - so that it does not cause blocking or deadlock issues.
  19827. SELECT t.article_id,s.agent_id,
  19828. 'UndelivCmdsInDistDB'=SUM(CASE WHEN xact_seqno > h.maxseq THEN 1 ELSE 0 END),
  19829. 'DelivCmdsInDistDB'=SUM(CASE WHEN xact_seqno <=  h.maxseq THEN 1 ELSE 0 END)
  19830. FROM    (SELECT    article_id,publisher_database_id, xact_seqno
  19831.     FROM MSrepl_commands (NOLOCK) ) as t
  19832. JOIN (SELECT agent_id,article_id,publisher_database_id FROM MSsubscriptions (NOLOCK) ) AS s 
  19833. ON (t.article_id = s.article_id AND t.publisher_database_id=s.publisher_database_id )
  19834. JOIN (SELECT agent_id,'maxseq'= isnull(max(xact_seqno),0x0) FROM MSdistribution_history (NOLOCK) GROUP BY agent_id) as h
  19835. ON (h.agent_id=s.agent_id)
  19836. GROUP BY t.article_id,s.agent_id
  19837. go
  19838.     
  19839. EXEC dbo.sp_MS_marksystemobject 'MSdistribution_status'
  19840. -- As this view can add considerable overhead when queried, it intentionally is not granted public access by default.
  19841. -- A site may so grant it if it wants to of course>
  19842. GRANT SELECT ON MSdistribution_status to dbo
  19843. go
  19844.  
  19845.  
  19846. raiserror(15339,-1,-1,'sp_browsereplcmds')
  19847. GO
  19848.  
  19849. create procedure sp_browsereplcmds 
  19850. @xact_seqno_start nchar(22) = NULL, 
  19851. @xact_seqno_end nchar(22) = NULL,
  19852. @originator_id int = NULL,
  19853. @publisher_database_id int = NULL,
  19854. @article_id int = NULL,
  19855. @command_id int = NULL,
  19856. @results_table sysname = NULL
  19857. as
  19858. declare @query nvarchar( 4000 )
  19859. declare @dbname sysname
  19860.  
  19861. if( @command_id is not null )
  19862. begin
  19863.     if( @xact_seqno_start is null or @publisher_database_id is null )
  19864.     begin
  19865.         raiserror( 21110, 16, -1 )
  19866.         return 1
  19867.     end
  19868.     else if @xact_seqno_start != @xact_seqno_end 
  19869.     begin
  19870.         raiserror( 21109, 16, -1 )
  19871.         return 1
  19872.     end
  19873. end
  19874.  
  19875. if @results_table is not null
  19876. begin
  19877.     select @query = N'create table ' + @results_table + N'('
  19878.     select @query = @query + N'xact_seqno varbinary(16) null,'
  19879.     select @query = @query + N'originator_id int null,'
  19880.     select @query = @query + N'publisher_database_id int null,'
  19881.     select @query = @query + N'article_id int null,'
  19882.     select @query = @query + N'type int null,'
  19883.     select @query = @query + N'command nvarchar( 1024 ) null )'
  19884.  
  19885.     exec ( @query )
  19886.     if @@error <> 0
  19887.     begin
  19888.         return 1
  19889.     end
  19890. end
  19891.  
  19892. if @xact_seqno_start is null
  19893. begin
  19894.     select @xact_seqno_start = N'0x00000000000000000000'
  19895. end
  19896. if @xact_seqno_end is null
  19897. begin
  19898.     select @xact_seqno_end = N'0xFFFFFFFFFFFFFFFFFFFF'
  19899. end
  19900.  
  19901. select @query = N'select xact_seqno, convert( int, originator_id ), convert( int, publisher_database_id ), convert(int, article_id), convert( int, type ), convert( int, partial_command ), command from MSrepl_commands '
  19902.  
  19903. if @command_id is not null
  19904. begin
  19905.     select @query = @query + N'where xact_seqno = ' + @xact_seqno_start  
  19906. end
  19907. else
  19908. begin
  19909.     select @query = @query + N'where xact_seqno >= ' + @xact_seqno_start + N' and xact_seqno <= ' + @xact_seqno_end 
  19910. end
  19911.  
  19912. if @originator_id is not null
  19913. begin
  19914.     select @query = @query + N' and originator_id = ' + convert( nvarchar, @originator_id )
  19915. end
  19916.  
  19917. if @publisher_database_id is not null
  19918. begin
  19919.     select @query = @query + N' and publisher_database_id = ' + convert( nvarchar, @publisher_database_id )
  19920. end
  19921.  
  19922. if @article_id is not null
  19923. begin
  19924.     select @query = @query + N' and article_id = ' + convert( nvarchar, @article_id )
  19925. end
  19926.  
  19927. if @command_id is not null
  19928. begin
  19929.     -- No need to use article_id and originator_id
  19930.     select @query = @query + N' and command_id >= ' + convert( nvarchar, @command_id )
  19931.     select @query = @query + N' and command_id <= ( select min( command_id ) from MSrepl_commands c '
  19932.     select @query = @query + N' where c.xact_seqno = ' + @xact_seqno_start  
  19933.     select @query = @query + N' and c.publisher_database_id = ' + convert( nvarchar, @publisher_database_id )
  19934.     select @query = @query + N' and c.command_id >= ' + convert( nvarchar, @command_id )
  19935.     select @query = @query + N' and c.partial_command = 0 )'  
  19936. end
  19937.  
  19938. select @query = @query + N' order by originator_id, publisher_database_id, xact_seqno, article_id, command_id asc'
  19939.  
  19940. select @dbname = db_name()
  19941.  
  19942. if @results_table is not null
  19943. begin
  19944.     declare @q2 nvarchar(4000)
  19945.     select @query = replace( @query, '''', '''''' )
  19946.     select @q2 = N'insert into ' + @results_table + N' exec master..xp_printstatements N'''+ @query + N''',N''' + @dbname  +''''
  19947.     exec (@q2)
  19948. end
  19949. else
  19950. begin
  19951.     exec master..xp_printstatements @query, @dbname
  19952. end
  19953. go
  19954.  
  19955.  
  19956.  
  19957. raiserror(15339,-1,-1,'sp_dumpparamcmd')
  19958. GO
  19959.  
  19960. create procedure sp_dumpparamcmd
  19961. @originator_id int,
  19962. @publisher_database_id int,
  19963. @article_id int,
  19964. @xact_seqno nchar(22)
  19965. as
  19966. declare @query nvarchar(2048)
  19967. declare @dbname sysname
  19968.  
  19969. select @query = N'select convert(int, partial_command) , command from MSrepl_commands '
  19970. select @query = @query + 'where type = 30 and xact_seqno = ' + @xact_seqno
  19971. select @query = @query + N' and originator_id = ' + convert( nvarchar, @originator_id )
  19972. select @query = @query + N' and publisher_database_id = ' + convert( nvarchar, @publisher_database_id )
  19973. select @query = @query + N' and article_id = ' + convert( nvarchar, @article_id )
  19974. select @query = @query + N' order by command_id asc'
  19975. select @dbname = db_name()
  19976.  
  19977. exec master..xp_displayparamstmt @query, @dbname, 1
  19978. go
  19979.  
  19980. raiserror(15339,-1,-1,'sp_MSbrowsesnapshotfolder')
  19981. GO
  19982.  
  19983. create procedure sp_MSbrowsesnapshotfolder (
  19984.     @publisher     sysname,
  19985.     @publisher_db  sysname,
  19986.     @article_id    int,
  19987.     @subscriber    sysname = NULL,
  19988.     @subscriber_db sysname = NULL
  19989.     )
  19990. AS
  19991.     SET NOCOUNT ON
  19992.  
  19993.  
  19994.     DECLARE @alt_directory_type     INT
  19995.     DECLARE @directory_type         INT
  19996.     DECLARE @publisher_id           INT
  19997.     DECLARE @publisher_database_id  INT
  19998.     DECLARE @subscriber_id          INT
  19999.     DECLARE @snapshot_bit           INT
  20000.     DECLARE @snapshot_mask          INT
  20001.     DECLARE @xact_seqno             VARBINARY(16)
  20002.     DECLARE @sync_init              INT
  20003.     DECLARE @sync_done              INT
  20004.  
  20005.     SELECT @alt_directory_type = 25
  20006.     SELECT @directory_type = 7
  20007.     SELECT @subscriber_id = NULL
  20008.     SELECT @snapshot_bit = 0x80000000
  20009.     SELECT @snapshot_mask = ~@snapshot_bit
  20010.     SELECT @xact_seqno = NULL
  20011.     SELECT @sync_init = 37
  20012.     SELECT @sync_done = 38
  20013.  
  20014.     SELECT @publisher_id = srvid 
  20015.       FROM master.dbo.sysservers 
  20016.      WHERE UPPER(@publisher) = UPPER(srvname)
  20017.  
  20018.     SELECT @publisher_database_id = publisher_database_id 
  20019.       FROM MSsubscriptions
  20020.      WHERE publisher_id = @publisher_id
  20021.        AND publisher_db = @publisher_db
  20022.        AND article_id = @article_id  
  20023.  
  20024.  
  20025.     -- @subscriber is null implies @subscriber_db is null also because 
  20026.     -- this sp can only be called by sp_browsesnapshotfolder
  20027.     IF @subscriber IS NULL
  20028.     BEGIN
  20029.         SELECT @xact_seqno = MAX(xact_seqno) 
  20030.           FROM MSrepl_commands
  20031.          WHERE publisher_database_id = @publisher_database_id
  20032.            AND article_id = @article_id
  20033.            AND (type & @snapshot_bit) <> 0            
  20034.            AND (type & @snapshot_mask) <> @sync_init
  20035.            AND (type & @snapshot_mask) <> @sync_done
  20036.     END
  20037.     ELSE 
  20038.     BEGIN
  20039.         -- Both @subscriber and @subscriber_db are non-null
  20040.         SELECT @subscriber_id = srvid 
  20041.           FROM master.dbo.sysservers
  20042.          WHERE UPPER(@subscriber) = UPPER(srvname)
  20043.         
  20044.         IF @subscriber_id IS NULL
  20045.         BEGIN
  20046.             RAISERROR(21150, 16, -1)  
  20047.             RETURN 1
  20048.         END
  20049.         
  20050.         SELECT @xact_seqno = subscription_seqno 
  20051.           FROM MSsubscriptions
  20052.          WHERE publisher_database_id = @publisher_database_id
  20053.            AND publisher_id = @publisher_id 
  20054.            AND article_id = @article_id
  20055.            AND subscriber_id = @subscriber_id
  20056.            AND subscriber_db = @subscriber_db
  20057.  
  20058.         IF @xact_seqno IS NULL
  20059.         BEGIN
  20060.             RAISERROR(14055, 16, -1)
  20061.             RETURN 1
  20062.         END                  
  20063.     END
  20064.  
  20065.     SELECT 'snapshot_folder' = CONVERT(NVARCHAR(255), command) 
  20066.       FROM MSrepl_commands 
  20067.      WHERE publisher_database_id = @publisher_database_id
  20068.        AND (type & @snapshot_bit) <> 0
  20069.        AND xact_seqno = @xact_seqno
  20070.        AND (((type & ~@snapshot_bit) = @alt_directory_type) OR
  20071.             ((type & ~@snapshot_bit) = @directory_type))
  20072.   ORDER BY command_id ASC
  20073.     IF @@ERROR <> 0
  20074.     BEGIN
  20075.         RETURN 1
  20076.     END
  20077.     ELSE
  20078.     BEGIN
  20079.         RETURN 0
  20080.     END
  20081. GO
  20082.  
  20083. raiserror(15339,-1,-1,'sp_MSchange_subscription_dts_info')
  20084. GO
  20085.  
  20086. CREATE PROCEDURE sp_MSdist_adjust_identity
  20087.     @agent_id    int,
  20088.     @tablename    sysname
  20089. as    
  20090.     declare @publisher sysname
  20091.     declare @publisher_db sysname
  20092.     declare @publisher_id smallint
  20093.     declare @publication sysname
  20094.     declare @next_seed bigint
  20095.     declare @range bigint
  20096.     declare @threshold int
  20097.     declare @retcode int
  20098.  
  20099.     -- Security check.
  20100.     exec @retcode = dbo.sp_MScheck_pull_access
  20101.         @agent_id = @agent_id,
  20102.         @agent_type = 0 -- distribution agent
  20103.     if @@error <> 0 or @retcode <> 0
  20104.         return (1)
  20105.  
  20106.     select @publication = publication, @publisher_id = publisher_id,
  20107.         @publisher_db = publisher_db from MSdistribution_agents where
  20108.         id = @agent_id
  20109.  
  20110.     select @publisher = srvname from master..sysservers where 
  20111.         srvid = @publisher_id
  20112.     -- Get the publication id.
  20113.     -- Note: auto identity range is only supported for queued tran pub
  20114.     -- which implies independent agent.
  20115.     declare @publication_id int
  20116.     select @publication_id = publication_id from MSpublications    where
  20117.         publication =  @publication and
  20118.         publisher_id = @publisher_id and
  20119.         publisher_db = @publisher_db
  20120.  
  20121.     -- Get the source object name
  20122.     declare @src_object sysname
  20123.     select @src_object = source_object from MSarticles where
  20124.         publication_id = @publication_id and
  20125.         destination_object = @tablename
  20126.  
  20127.     if @src_object is not null
  20128.     begin
  20129.         exec @retcode = dbo.sp_MSfetchAdjustidentityrange
  20130.             @publisher = @publisher,
  20131.             @publisher_db = @publisher_db,
  20132.             @tablename = @src_object,
  20133.             @adjust_only = 1,
  20134.             @for_publisher = 0,
  20135.             @next_seed = @next_seed output,
  20136.             @range = @range output,
  20137.             @threshold = @threshold output
  20138.         if @@error <> 0 or @retcode <> 0
  20139.             return 1
  20140.     end
  20141.  
  20142.     -- Return nothing if the table is not found in the table collection served by
  20143.     -- the distribution agent.
  20144.     select 'next_seed' = @next_seed, 'range' = @range, 'threshold' = @threshold
  20145.         where @next_seed is not null 
  20146. go            
  20147.  
  20148. raiserror(15339,-1,-1,'sp_MSdist_adjust_identity')
  20149. GO
  20150.  
  20151. CREATE PROCEDURE sp_MSchange_subscription_dts_info (
  20152.     @job_id varbinary(16),
  20153.     @dts_package_name sysname,
  20154.     @dts_package_password nvarchar(524),
  20155.     @dts_package_location int,
  20156.     @change_password bit
  20157.  
  20158.     ) AS
  20159.  
  20160.     /*
  20161.     ** Declarations.
  20162.     */
  20163.     declare @subscriber sysname
  20164.     declare @publisher sysname
  20165.     declare @subscriber_id smallint
  20166.     declare @publisher_id smallint
  20167.  
  20168.     /*
  20169.     ** Initializations.
  20170.     */
  20171.     SET NOCOUNT ON
  20172.     
  20173.     select @subscriber_id = subscriber_id, @publisher_id = publisher_id 
  20174.         from MSdistribution_agents where 
  20175.         job_id = @job_id
  20176.     
  20177.     select @subscriber = srvname from master..sysservers where srvid = @subscriber_id
  20178.     select @publisher = srvname from master..sysservers where srvid = @publisher_id
  20179.  
  20180.     declare @oledb_subscriber tinyint
  20181.     select @oledb_subscriber = 3
  20182.     
  20183.     -- Only SQL Server and OLEDB subscriber support dts
  20184.     if not exists (select * from MSsubscriber_info where 
  20185.         UPPER(publisher) = UPPER(@publisher) and 
  20186.         UPPER(subscriber) = UPPER(@subscriber) and
  20187.         (type = 0 or type = @oledb_subscriber))
  20188.     begin
  20189.         raiserror(21170, 16, -1)
  20190.         return 1
  20191.     end
  20192.     
  20193.     
  20194.     update MSdistribution_agents set
  20195.         dts_package_name = case 
  20196.             when @dts_package_name is null then dts_package_name
  20197.             when @dts_package_name = N'' then null
  20198.             else @dts_package_name
  20199.             end, 
  20200.         dts_package_password = case @change_password
  20201.             when 0 then dts_package_password
  20202.             else @dts_package_password
  20203.             end, 
  20204.         dts_package_location = case
  20205.             when @dts_package_location is null then dts_package_location
  20206.             else @dts_package_location
  20207.             end
  20208.         where
  20209.             job_id = @job_id
  20210.  
  20211.     RETURN (0)
  20212. go
  20213.  
  20214. raiserror(15339,-1,-1,'sp_MSrefresh_anonymous')
  20215. GO
  20216. CREATE PROCEDURE sp_MSrefresh_anonymous (
  20217. @publication            sysname,
  20218. @publisher                sysname,
  20219. @publisher_db            sysname
  20220. )AS
  20221.  
  20222. declare @retcode         int
  20223. declare @publisher_id    int
  20224. declare @success        int
  20225. declare @agent_id        int
  20226.  
  20227. SELECT @publisher_id = NULL 
  20228. SELECT @publisher_id = srvid FROM master..sysservers WHERE UPPER(@publisher) = UPPER(srvname)  
  20229. IF @publisher_id IS NULL
  20230.     BEGIN
  20231.         RAISERROR(21169, 16, -1, @publisher, @@SERVERNAME, @publisher)    
  20232.         return (1)
  20233.     END
  20234. select @success = 2 --agent history status
  20235.  
  20236. select @agent_id = id from MSmerge_agents where 
  20237.     anonymous_subid is not NULL and --touch anonymous only
  20238.     publication like @publication and 
  20239.     publisher_id=@publisher_id and 
  20240.     publisher_db=@publisher_db
  20241.  
  20242. set rowcount 1
  20243. update MSmerge_history set time=getdate() where agent_id=@agent_id and runstatus=@success
  20244. if @@ERROR<>0
  20245.     return (1)
  20246. GO
  20247.  
  20248. raiserror(15339,-1,-1,'sp_MScheck_pub_identity')
  20249. GO
  20250. CREATE PROCEDURE sp_MScheck_pub_identity (
  20251. @publisher            sysname,
  20252. @publisher_db        sysname,
  20253. @tablename            sysname, 
  20254. @current_max        bigint  = NULL OUTPUT,
  20255. @pub_range            bigint  = NULL OUTPUT,
  20256. @threshold            int  = NULL OUTPUT,
  20257. @range                bigint  = NULL OUTPUT,
  20258. @next_seed            bigint  = NULL OUTPUT,
  20259. @max_identity        bigint = NULL OUTPUT
  20260. )AS
  20261.  
  20262.     declare @retcode        int
  20263.  
  20264.     if @current_max is not NULL
  20265.     begin
  20266.         select @current_max=current_max from MSrepl_identity_range 
  20267.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20268.         if @@ERROR<>0    
  20269.             return (1)
  20270.     end
  20271.  
  20272.     if @max_identity is not NULL
  20273.     begin
  20274.         select @max_identity=max_identity from MSrepl_identity_range 
  20275.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20276.         if @@ERROR<>0    
  20277.             return (1)
  20278.     end
  20279.  
  20280.     if @pub_range is not NULL
  20281.     begin
  20282.         select @pub_range=pub_range from MSrepl_identity_range 
  20283.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20284.         if @@ERROR<>0    
  20285.             return (1)
  20286.     end
  20287.  
  20288.     if @threshold is not NULL
  20289.     begin
  20290.         select @threshold=threshold from MSrepl_identity_range 
  20291.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20292.         if @@ERROR<>0    
  20293.             return (1)
  20294.     end
  20295.     if @next_seed is not NULL
  20296.     begin
  20297.         select @next_seed=next_seed from MSrepl_identity_range 
  20298.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20299.         if @@ERROR<>0    
  20300.             return (1)
  20301.     end
  20302.     if @range is not NULL
  20303.     begin
  20304.         select @range=range from MSrepl_identity_range 
  20305.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20306.         if @@ERROR<>0    
  20307.             return (1)
  20308.     end
  20309.  
  20310. return (0)
  20311. GO
  20312.  
  20313. raiserror(15339,-1,-1,'sp_MSadjust_pub_identity')
  20314. GO
  20315.  
  20316. CREATE PROCEDURE sp_MSadjust_pub_identity (
  20317. @publisher            sysname,
  20318. @publisher_db        sysname,
  20319. @tablename            sysname,
  20320. @current_max        int  = NULL,
  20321. @threshold            int  = NULL,
  20322. @range                int = NULL,
  20323. @next_seed            int  = NULL
  20324. )AS
  20325.  
  20326.     declare @retcode        int
  20327.     if @current_max is NOT NULL
  20328.     begin
  20329.         update MSrepl_identity_range set current_max=@current_max 
  20330.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20331.         if @@ERROR<>0    
  20332.             return (1)
  20333.         if exists (select * from MSrepl_identity_range where max_identity is not NULL 
  20334.             and ABS(current_max) > ABS(max_identity))
  20335.         begin
  20336.             raiserror(21195, 16, -1)
  20337.             return (1)
  20338.         end
  20339.     end
  20340.     if @threshold is NOT NULL
  20341.     begin
  20342.     update MSrepl_identity_range set threshold=@threshold 
  20343.         where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20344.     if @@ERROR<>0    
  20345.         return (1)
  20346.     end
  20347.     if @next_seed is NOT NULL
  20348.     begin
  20349.     update MSrepl_identity_range set next_seed=@next_seed 
  20350.         where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20351.     if @@ERROR<>0
  20352.         return (1)
  20353.     end
  20354.     if @range is NOT NULL
  20355.     begin
  20356.     update MSrepl_identity_range set range=@range 
  20357.         where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db    
  20358.     if @@ERROR<>0
  20359.         return (1)
  20360.     end
  20361. return (0)
  20362. GO
  20363.  
  20364. raiserror(15339,-1,-1,'sp_MSinsert_identity')
  20365. GO
  20366.  
  20367. CREATE PROCEDURE sp_MSinsert_identity (
  20368.     @publisher             sysname,
  20369.     @publisher_db         sysname,
  20370.     @tablename             sysname,
  20371.     @identity_support    int,
  20372.     @pub_identity_range bigint,
  20373.     @identity_range     bigint,
  20374.     @threshold             int,
  20375.     @next_seed            bigint,
  20376.     @max_identity        bigint
  20377.     ) AS
  20378.     
  20379.     declare @pub_seed         bigint    
  20380.     declare @current_max     bigint
  20381.     if not exists (select * from MSrepl_identity_range 
  20382.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db)
  20383.     begin
  20384.         select @pub_seed = @pub_identity_range + @next_seed
  20385.         select @current_max = @pub_seed - 1
  20386.         insert MSrepl_identity_range(publisher, publisher_db, tablename, identity_support, next_seed, pub_range, range, max_identity, threshold, current_max    )
  20387.                 values (@publisher, @publisher_db, @tablename, @identity_support, @pub_seed,  @pub_identity_range, @identity_range, @max_identity, @threshold, @current_max)
  20388.         if @@ERROR<>0
  20389.             return 1
  20390.     end
  20391.     else if 1 > 1 --disable this segment for now.
  20392.         begin --adjust republisher's resource table
  20393.             select @pub_seed = @pub_identity_range - 1
  20394.             /* update range, threshold at republisher as needed. Max and next_seed has been set already. */
  20395.             update MSrepl_identity_range set    range = @identity_range,
  20396.                                                 pub_range = @pub_identity_range,
  20397.                                                 threshold=@threshold, 
  20398.                                                 next_seed=next_seed + @pub_identity_range,
  20399.                                                 current_max=next_seed + @pub_seed --new next_seed not yet picked up
  20400.             where tablename=@tablename and LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db
  20401.             if @@ERROR<>0
  20402.                 return (1)
  20403.         end
  20404. GO
  20405.  
  20406. raiserror(15339,-1,-1,'sp_MSget_subscription_dts_info')
  20407. GO
  20408.  
  20409. CREATE PROCEDURE sp_MSget_subscription_dts_info (
  20410.     @job_id varbinary(16)
  20411.  
  20412.     ) AS
  20413.  
  20414.     /*
  20415.     ** Declarations.
  20416.     */
  20417.  
  20418.     /*
  20419.     ** Initializations.
  20420.     */
  20421.     SET NOCOUNT ON
  20422.  
  20423.     select dts_package_name, dts_package_location 
  20424.         from MSdistribution_agents where
  20425.         job_id = @job_id
  20426.  
  20427.     RETURN (0)
  20428. go
  20429.  
  20430. raiserror(15339, -1, -1, 'sp_MSenumdistributionagentproperties')
  20431. GO
  20432.  
  20433. CREATE PROCEDURE sp_MSenumdistributionagentproperties (
  20434.     @publisher        sysname,
  20435.     @publisher_db     sysname,
  20436.     @publication      sysname
  20437.     ) AS
  20438.     DECLARE @independent_agent bit 
  20439.     DECLARE @publisher_id int  -- Server id of the Publisher with respect to the Distributor
  20440.    
  20441.     SELECT @publisher_id = NULL 
  20442.     SELECT @publisher_id = srvid 
  20443.       FROM master..sysservers
  20444.      WHERE UPPER(@publisher) = UPPER(srvname)  
  20445.     
  20446.     IF @publisher_id IS NULL
  20447.     BEGIN
  20448.         RAISERROR(21169, 16, -1, @publisher, @@SERVERNAME, @publisher)    
  20449.     END
  20450.  
  20451.     IF @publication <> '%' -- A publication name is specified 
  20452.     BEGIN
  20453.         -- Determine whether the given publication shares an 
  20454.         -- agent with other publicaitons in the same database
  20455.         -- or not
  20456.         SELECT @independent_agent = 0
  20457.         SELECT @independent_agent = independent_agent 
  20458.           FROM MSpublications
  20459.          WHERE publisher_id = @publisher_id
  20460.            AND publisher_db = @publisher_db
  20461.            AND publication = @publication  
  20462.         
  20463.         IF @independent_agent IS NULL
  20464.         BEGIN
  20465.             RAISERROR(20026, 16, -1)
  20466.         END
  20467.  
  20468.         IF @independent_agent = 0 
  20469.         BEGIN
  20470.             -- If the publication shares an agent with 
  20471.             -- other publications, change the publication
  20472.             -- name to 'ALL' before querying the MSdistribution_agents
  20473.             -- table
  20474.             SELECT @publication = N'ALL'                
  20475.         END
  20476.  
  20477.         SELECT job_id, offload_enabled, offload_server, 
  20478.                dts_package_name, dts_package_location,
  20479.                -- status of this agent, only useful in detecting
  20480.                -- whether or not the agent has be deactivated by cleanup
  20481.                -- If so, all the rows in MSsubscriptions will be 0
  20482.                (select top 1 s.status from MSsubscriptions s where
  20483.                     s.agent_id = a.id)
  20484.           FROM MSdistribution_agents a
  20485.          WHERE a.publisher_id = @publisher_id 
  20486.            AND a.publisher_db = @publisher_db
  20487.            AND a.publication = @publication
  20488.     END
  20489.     ELSE
  20490.     BEGIN
  20491.         SELECT job_id, offload_enabled, offload_server, 
  20492.                dts_package_name, dts_package_location,
  20493.                -- status of this agent, only useful in detecting
  20494.                -- whether or not the agent has be deactivated by cleanup
  20495.                -- If so, all the rows in MSsubscriptions will be 0
  20496.                (select top 1 s.status from MSsubscriptions s where
  20497.                     s.agent_id = a.id)
  20498.           FROM MSdistribution_agents a
  20499.          WHERE a.publisher_id = @publisher_id 
  20500.            AND a.publisher_db = @publisher_db
  20501.     END
  20502. GO
  20503.     
  20504. raiserror(15339, -1, -1, 'sp_MSenum_merge_agent_properties')
  20505. GO
  20506. CREATE PROCEDURE sp_MSenum_merge_agent_properties (
  20507.     @publisher        sysname,
  20508.     @publisher_db     sysname,
  20509.     @publication      sysname
  20510.     ) AS
  20511.     
  20512.     DECLARE @publisher_id int  -- Server id of the Publisher with respect to the Distributor
  20513.  
  20514.     SELECT @publisher_id = NULL 
  20515.     SELECT @publisher_id = srvid 
  20516.       FROM master..sysservers
  20517.      WHERE UPPER(@publisher) = UPPER(srvname)  
  20518.  
  20519.     IF @publisher_id IS  NULL
  20520.     BEGIN
  20521.         RAISERROR(21169, 16, -1, @publisher, @@SERVERNAME, @publisher)    
  20522.     END
  20523.  
  20524.     SELECT job_id, offload_enabled, offload_server 
  20525.       FROM MSmerge_agents
  20526.      WHERE publisher_id = @publisher_id 
  20527.        AND publisher_db = @publisher_db
  20528.        AND (@publication = N'%' OR publication = @publication)
  20529. GO
  20530.  
  20531. raiserror(15339, -1, -1, 'sp_dropanonymoussubscription')
  20532. GO
  20533. CREATE PROCEDURE sp_dropanonymoussubscription
  20534. @agent_id int,
  20535. @type int -- 1 tran sub, 2 merge sub
  20536. as
  20537.     declare @retcode int
  20538.     if @type not in (1,2)
  20539.     begin
  20540.         raiserror(20587, 16, -1, '@type', 'sp_dropanonymoussubscription')
  20541.         return (1)
  20542.     end
  20543.     -- If tran
  20544.     if @type = 1
  20545.     begin
  20546.         if not exists (select * from MSdistribution_agents where
  20547.             id = @agent_id and
  20548.             subscriber_name is not null)
  20549.         begin
  20550.             RAISERROR (14055, 11, -1)
  20551.             return(1)
  20552.         end
  20553.         exec @retcode = dbo.sp_MSdrop_distribution_agentid @agent_id
  20554.         if @retcode <> 0 or @@error <> 0
  20555.             return 1
  20556.     end
  20557.     else
  20558.     begin
  20559.         if not exists (select * from MSmerge_agents where
  20560.             id = @agent_id and
  20561.             subscriber_name is not null)
  20562.         begin
  20563.             RAISERROR (14055, 11, -1)
  20564.             return(1)
  20565.         end
  20566.         exec @retcode = dbo.sp_MSdrop_merge_agentid @agent_id
  20567.         if @retcode <> 0 or @@error <> 0
  20568.             return 1
  20569.     end
  20570. go
  20571.  
  20572. raiserror(15339, -1, -1, 'sp_MSdrop_anonymous_entry')
  20573. GO
  20574. CREATE PROCEDURE sp_MSdrop_anonymous_entry
  20575. @subid uniqueidentifier,
  20576. @login sysname,
  20577. @type int -- 1 tran sub, 2 merge sub
  20578. as
  20579.     declare @sid varbinary(85)
  20580.     declare @agent_id int, @retcode int
  20581.     set nocount on 
  20582.     if @type not in (1,2)
  20583.     begin
  20584.         raiserror(20587, 16, -1, '@type', 'sp_MSdrop_anonymous_entry')
  20585.         return (1)
  20586.     end
  20587.     -- If tran
  20588.     if @type = 1
  20589.     begin
  20590.         select @sid = sid from MSdistribution_agents where
  20591.             anonymous_subid = @subid
  20592.     end
  20593.     else
  20594.     begin
  20595.         select @sid = sid from MSmerge_agents where
  20596.             anonymous_subid = @subid
  20597.     end
  20598.     if @sid is null
  20599.     begin
  20600.         RAISERROR (14055, 11, -1)
  20601.         return(1)
  20602.     end
  20603.     -- null login means no security check needed
  20604.     if @login is not null and suser_sid(@login) <> @sid
  20605.     begin
  20606.         set @login = suser_sname(@sid)
  20607.         RAISERROR (20596, 11, -1, @login)
  20608.         RETURN (1)
  20609.     end
  20610.  
  20611.     if @type = 1
  20612.     begin
  20613.         select @agent_id = id from MSdistribution_agents where anonymous_subid = @subid
  20614.         if @agent_id is not null
  20615.         begin
  20616.             exec @retcode = dbo.sp_MSdrop_distribution_agentid @agent_id
  20617.             if @retcode <> 0 or @@error <> 0
  20618.                 return 1
  20619.         end
  20620.     end
  20621.     else
  20622.     begin
  20623.         select @agent_id = id from MSmerge_agents where anonymous_subid = @subid
  20624.         if @agent_id is not null
  20625.         begin
  20626.             exec @retcode = dbo.sp_MSdrop_merge_agentid @agent_id
  20627.             if @retcode <> 0 or @@error <> 0
  20628.                 return 1
  20629.         end
  20630.     end
  20631. go
  20632.  
  20633. raiserror(15339, -1, -1, 'sp_MSadddynamicsnapshotjobatdistributor')
  20634. go
  20635. --
  20636. -- Name: sp_MSadddynamicsnapshotjobatdistributor
  20637. --
  20638. -- Description: This function is called by sp_MSaddmergedynamicsnapshotjob 
  20639. --              at the publisher to set up a dynamic snapshot job in msdb
  20640. --              at the distributor. 
  20641. -- Notes: This procedure will only perform implicit checking for scheduling 
  20642. --        parameters as most parameters are expected to have been checked 
  20643. --        in sp_MSaddmergedynamicsnapshotjob
  20644. --
  20645. -- Parameters: @regular_snapshot_jobid uniqueidentifier (mandatory)
  20646. --             @dynamic_filter_login sysname (optional, default null)
  20647. --             @dynamic_filter_hostname sysname (optional, default null)
  20648. --             @dynamic_snapshot_location nvarchar(255) (mandatory)
  20649. --             @dynamic_snapshot_jobid uniqueidentifier (mandatory)
  20650. --             Scheduling information:
  20651. --             @freqtype int (optional, default 4 == Daily)
  20652. --             @freqinterval int (optional, default 1 == Every day)
  20653. --             @freqsubtype int (optional, default 4 (Sub interval = Minute))
  20654. --             @freqsubinterval int (optional, default 5 == Every five minutes)
  20655. --             @freqrelativeinterval int (optional, default 1) 
  20656. --             @freqrecurrencefactor int (optional, default 0) 
  20657. --             @activestartdate int (optional, default 0 == Today)
  20658. --             @activeenddate int (optional, default 99991231) 
  20659. --             @activestarttimeofday int (optional, default 0 == Now)        
  20660. --             @activeendtimeofday int (optional, default 235959)
  20661. --
  20662. -- Returns: 0 - succeeded
  20663. --          1 - failed
  20664. --
  20665. -- Security: Only members of the 'sysadmin' server role and members of the 
  20666. --           'db_owner' database role at the distributor can call this 
  20667. --           procedure. This procedure is intended to be called through 
  20668. --           the distributor_admin remote login in the case where
  20669. --           the distributor is a different machine from the publisher. 
  20670. --
  20671. create procedure sp_MSadddynamicsnapshotjobatdistributor (
  20672.     @regular_snapshot_jobid uniqueidentifier,
  20673.     @dynamic_filter_login sysname = null,
  20674.     @dynamic_filter_hostname sysname = null,
  20675.     @dynamic_snapshot_location nvarchar(255),
  20676.     @dynamic_snapshot_jobname sysname output,
  20677.     @dynamic_snapshot_jobid uniqueidentifier output,
  20678.  
  20679.     -- Scheduling information
  20680.     @freqtype               int = 4,
  20681.     @freqinterval           int = 1,
  20682.     @freqsubtype            int = 4,
  20683.     @freqsubinterval        int = 5,
  20684.     @freqrelativeinterval   int = 1, 
  20685.     @freqrecurrencefactor   int = 0,
  20686.     @activestartdate        int = 0,
  20687.     @activeenddate          int = 99991231,
  20688.     @activestarttimeofday   int = 0, 
  20689.     @activeendtimeofday     int = 235959
  20690.     )
  20691. as
  20692. begin
  20693.     set nocount on
  20694.  
  20695.     declare @retcode int
  20696.     declare @agent_command_line nvarchar(4000)
  20697.     declare @agent_id int
  20698.     declare @db_name sysname    
  20699.     declare @category_name sysname
  20700.     declare @nullchar nchar(20)
  20701.  
  20702.     declare @dynamicfilterloginparam nvarchar(50)
  20703.     declare @dynamicfilterhostnameparam nvarchar(50)
  20704.     declare @dynamicsnapshotlocationparam nvarchar(50)
  20705.     
  20706.     select @retcode = 0
  20707.     select @agent_command_line = null
  20708.     select @agent_id = null
  20709.     select @db_name = db_name()
  20710.     select @category_name = name 
  20711.       from msdb.dbo.syscategories 
  20712.      where category_id = 15
  20713.     select @nullchar = null
  20714.  
  20715.     select @dynamicfilterloginparam = N' -DynamicFilterLogin '
  20716.     select @dynamicfilterhostnameparam = N' -DynamicFilterHostName '
  20717.     select @dynamicsnapshotlocationparam = N' -DynamicSnapshotLocation '
  20718.  
  20719.     -- Get the regular snapshot agent command line
  20720.     select @agent_command_line = command 
  20721.       from msdb..sysjobsteps
  20722.      where job_id = @regular_snapshot_jobid
  20723.        and subsystem = N'Snapshot'
  20724.        and step_id = 2
  20725.         
  20726.     if @agent_command_line is null
  20727.     begin
  20728.         raiserror(21319, 11, -1)        
  20729.         return 1        
  20730.     end  
  20731.     
  20732.     -- Get the agent id    
  20733.     select @agent_id = id
  20734.       from MSsnapshot_agents
  20735.      where job_id = @regular_snapshot_jobid
  20736.  
  20737.     if @agent_id is null
  20738.     begin
  20739.         raiserror(21325, 11, -1)
  20740.         return 1
  20741.     end
  20742.  
  20743.     if @dynamic_snapshot_jobname is null or @dynamic_snapshot_jobname = N''
  20744.     begin
  20745.         -- Get the job name of the regular snapshot job. This is going to be used
  20746.         -- to derive a uniquefied job name for the dynamic snapshot job
  20747.         select @dynamic_snapshot_jobname = name 
  20748.           from msdb..sysjobs 
  20749.          where job_id = @regular_snapshot_jobid
  20750.     
  20751.         select @dynamic_snapshot_jobname = N'dyn_' + left(@dynamic_snapshot_jobname,88) + convert(nvarchar(36), newid()) 
  20752.     end
  20753.  
  20754.     if @dynamic_filter_login is not null and @dynamic_filter_login <> N''
  20755.     begin
  20756.         select @agent_command_line = @agent_command_line + @dynamicfilterloginparam + N'[' + rtrim(@dynamic_filter_login) + N']' 
  20757.     end
  20758.  
  20759.     if @dynamic_filter_hostname is not null and @dynamic_filter_hostname <> N''
  20760.     begin
  20761.         select @agent_command_line = @agent_command_line + @dynamicfilterhostnameparam + N'[' + rtrim(@dynamic_filter_hostname) + N']' 
  20762.     end
  20763.  
  20764.     -- @dynamic_snapshot_location is assumed to be non-empty
  20765.     select @agent_command_line = @agent_command_line + @dynamicsnapshotlocationparam + N'[' + @dynamic_snapshot_location + N']'
  20766.  
  20767.     -- Add the job
  20768.     exec @retcode = dbo.sp_MSadd_repl_job
  20769.          @name = @dynamic_snapshot_jobname,
  20770.          @subsystem = 'Snapshot',
  20771.          @server = @@servername,
  20772.          @databasename = @db_name,
  20773.          @enabled = 1,
  20774.          @freqtype = @freqtype,
  20775.          @freqinterval = @freqinterval,
  20776.          @freqsubtype = @freqsubtype,
  20777.          @freqsubinterval = @freqsubinterval,
  20778.          @freqrecurrencefactor = @freqrecurrencefactor,
  20779.          @activestartdate = @activestartdate,
  20780.          @activeenddate = @activeenddate,
  20781.          @activestarttimeofday = @activestarttimeofday,
  20782.          @activeendtimeofday = @activeendtimeofday,
  20783.          @nextrundate = 0,
  20784.          @nextruntime = 0,
  20785.          @runpriority = 0,
  20786.          @emailoperatorname = @nullchar,
  20787.          @retryattempts = 10,
  20788.          @retrydelay = 1,
  20789.          @command = @agent_command_line,
  20790.          @loghistcompletionlevel = 0,
  20791.          @emailcompletionlevel = 0,
  20792.          @description = @nullchar,
  20793.          @tagobjectid = 0,
  20794.          @tagobjecttype = 0,
  20795.          @category_name = @category_name,
  20796.          @failure_detection = 1,
  20797.          @agent_id = @agent_id,
  20798.          @job_id = @dynamic_snapshot_jobid output            
  20799.  
  20800.     return @retcode
  20801. end
  20802. go
  20803.  
  20804. raiserror(15339, -1, -1, 'sp_MSdeleterepljob')
  20805. go
  20806. --
  20807. -- Name: sp_MSdeleterepljob
  20808. --
  20809. -- Description: This is a lightweight wrapper of sp_delete_job to be used
  20810. --              by remote publishers.
  20811. --
  20812. -- Parameter: @job_id uniqueidentifier (mandatory)
  20813. --
  20814. -- Returns 0 - succeeded
  20815. --         1 - failed
  20816. -- 
  20817. -- Security: Only members of the sysadmin server role and members of the 
  20818. -- db_owner role of the distribution database can execute this function. This
  20819. -- procedure is intended to be called through the distribution_admin remote 
  20820. -- login from remote publishers
  20821. --
  20822. create procedure sp_MSdeleterepljob (
  20823.     @job_id uniqueidentifier
  20824.     )
  20825. as
  20826. begin
  20827.     set nocount on
  20828.     declare @retcode int
  20829.     declare @job_name sysname 
  20830.  
  20831.     select @retcode = 0
  20832.     exec @retcode = msdb..sp_delete_job @job_id = @job_id
  20833.  
  20834.     return @retcode
  20835. end
  20836. go
  20837.  
  20838. raiserror(15339, -1, -1, 'sp_MSdeletefoldercontents')
  20839. go
  20840. --
  20841. -- Name: sp_MSdeletefoldercontents
  20842. --
  20843. -- Description: This is a lighweight wrapper for deleting all files in the
  20844. --              specified. This procedure is meant to be called by a remote 
  20845. --              publisher for deleting files in the distributor's context.
  20846. --
  20847. -- Parameter: @folder nvarchar(255) (mandatory)
  20848. --
  20849. -- Returns 0 - succeeded
  20850. --         1 - failed
  20851. --
  20852. -- Security: Only members of the sysadmin server role and members of the 
  20853. -- db_owner role of the distribution database can execute this function. This
  20854. -- procedure is intended to be called through the distribution_admin remote 
  20855. -- login from remote publishers
  20856. --
  20857. create procedure sp_MSdeletefoldercontents (
  20858.     @folder nvarchar(255)
  20859.     )
  20860. as
  20861. begin
  20862.     set nocount on
  20863.  
  20864.     declare @command nvarchar(4000)
  20865.     declare @retcode int
  20866.  
  20867.     select @retcode = 0
  20868.     if len(@folder) = 0 or @folder is null
  20869.     begin
  20870.         return 0
  20871.     end
  20872.  
  20873.     -- Append '\*' to the given path 
  20874.     if substring(@folder, len(@folder), 1) <> N'\'
  20875.     begin
  20876.         select @folder = @folder + N'\'
  20877.     end 
  20878.  
  20879.     select @folder = @folder + '*'    
  20880.  
  20881.     if (platform() & 0x1) = 0x1 
  20882.     begin
  20883.         select @command = 'del /q /f "' + @folder + '"'
  20884.     end
  20885.     else
  20886.     begin
  20887.         -- Win9x 'del' command does not support the /q and /f switches
  20888.         select @command = 'del "' + @folder + '.*"'
  20889.     end
  20890.  
  20891.     exec @retcode = master..xp_cmdshell @command, no_output
  20892.     return @retcode
  20893.  
  20894. end
  20895. go
  20896.  
  20897. CREATE PROCEDURE sp_MSinvalidate_snapshot
  20898. @publisher sysname,
  20899. @publisher_db sysname,
  20900. @publication sysname
  20901.  
  20902. as
  20903.     set nocount on
  20904.     declare @publisher_id smallint  
  20905.     declare @automatic tinyint
  20906.     declare @virtual smallint 
  20907.     declare @retcode int
  20908.     declare @active tinyint
  20909.         , @initiated tinyint
  20910.         , @subscribed tinyint
  20911.     declare @publication_id int
  20912.  
  20913.     select @automatic = 1
  20914.     select @virtual = - 1
  20915.     select @active = 2
  20916.         , @initiated = 3
  20917.         , @subscribed = 1
  20918.  
  20919.     -- Check if publisher is a defined as a distribution publisher in the current database
  20920.     exec @retcode = dbo.sp_MSvalidate_distpublisher @publisher, @publisher_id OUTPUT
  20921.     if @retcode <> 0
  20922.     begin
  20923.         return(1)
  20924.     end
  20925.  
  20926.     -- Make sure publication exists
  20927.     select @publication_id = publication_id
  20928.         from MSpublications where publication = @publication and
  20929.         publisher_id = @publisher_id and publisher_db = @publisher_db
  20930.  
  20931.     -- Set the virtual subscription status to be 'subscribed' so that
  20932.     -- new subscription will wait for the next snapshot.
  20933.     update MSsubscriptions set status = @subscribed where 
  20934.         publication_id = @publication_id and
  20935.         sync_type = @automatic and
  20936.         status in (@active, @initiated) and
  20937.         subscriber_id = @virtual
  20938.  
  20939.     return (0)
  20940. GO
  20941.  
  20942. create procedure sp_MSrepl_init_backup_lsns
  20943. as
  20944.     -- The stored procedure is called by sp_replicationoption when changing a dist
  20945.     -- db to 'sync with backup' mode
  20946.     set nocount on
  20947.     
  20948.     -- Set the truncate lsns to null. By doing this
  20949.     -- the distribution agent will stop calling sp_repldone untill a dist db
  20950.     -- backup is done.
  20951.     update MSrepl_backup_lsns set valid_xact_seqno = NULL,
  20952.         valid_xact_id = NULL
  20953.     if @@error <> 0
  20954.         return 1
  20955.     return 0
  20956. go
  20957.  
  20958. --
  20959. -- Name: sp_MSispublicationqueued
  20960. --
  20961. -- Description: This procedure is invoked by sp_MShelp_replication_status 
  20962. --                to find out if the specified publication supports queued
  20963. --                updating subscribers. 
  20964. --
  20965. -- Parameter: 
  20966. --                @publisher sysname (mandatory)
  20967. --                @publisher_db sysname (mandatory)
  20968. --                @publication sysname (mandatory)
  20969. --                @allow_queued_tran bit OUTPUT (mandatory)
  20970. --
  20971. -- Returns 0 - succeeded
  20972. --         1 - failed
  20973. --
  20974. -- Security: Only members of the sysadmin server role and members of the 
  20975. -- db_owner role of the distribution database can execute this function.
  20976. --
  20977. raiserror(15339,-1,-1,'sp_MSispublicationqueued')
  20978. go
  20979. create procedure sp_MSispublicationqueued (
  20980.     @publisher sysname
  20981.     ,@publisher_db sysname
  20982.     ,@publication sysname
  20983.     ,@allow_queued_tran bit OUTPUT
  20984.     )
  20985. as
  20986. begin
  20987.     --
  20988.     -- get the queued tran state for the publication
  20989.     --
  20990.     if exists (select * from dbo.sysobjects where name = N'MSpublications')
  20991.     begin
  20992.         select @allow_queued_tran = pub.allow_queued_tran 
  20993.         from (dbo.MSpublications as pub join master.dbo.sysservers as srv
  20994.                 on pub.publisher_id = srv.srvid)
  20995.         where UPPER(srv.srvname) = UPPER(@publisher)
  20996.             and pub.publisher_db = @publisher_db
  20997.             and pub.publication = @publication
  20998.     end
  20999.     else
  21000.         select @allow_queued_tran = 0
  21001.  
  21002.     --
  21003.     -- all done
  21004.     --
  21005.     return 0
  21006. end
  21007. go
  21008.  
  21009. raiserror(15339,-1,-1,'sp_MSlog_agent_cancel')
  21010. go
  21011. create procedure sp_MSlog_agent_cancel
  21012. @job_id binary(16),
  21013. @category_id int,
  21014. @message nvarchar(1024)
  21015. as
  21016.     -- This stored procedure is called by msdb proc, sp_sqlagent_log_jobhistory to
  21017.     -- log a agent cancel message to repl monitor (agent history tables) when the
  21018.     -- agent fails to log a complete message to repl monitor directly. 
  21019.     -- sp_MSdetect_nonlogged_shutdown would not help in this case, because that step
  21020.     -- will not be executed because the job is canceled before the step.
  21021.     declare @agent_id int
  21022.  
  21023.     if @category_id = 15
  21024.     begin
  21025.         -- Get agent_id
  21026.         select @agent_id = id from MSsnapshot_agents where job_id = @job_id
  21027.         if exists (select runstatus from MSsnapshot_history where 
  21028.             agent_id = @agent_id and
  21029.             runstatus <> 2 and 
  21030.             runstatus <> 5 and 
  21031.             runstatus <> 6 and
  21032.             timestamp = (select max(timestamp) from MSsnapshot_history where agent_id = @agent_id))
  21033.         begin
  21034.             -- Log success message.
  21035.             exec dbo.sp_MSadd_snapshot_history @agent_id = @agent_id, @runstatus = 2,
  21036.                     @comments = @message
  21037.         end
  21038.     end
  21039.     else if @category_id = 13
  21040.     begin
  21041.         -- Get agent_id
  21042.         select @agent_id = id from MSlogreader_agents where job_id = @job_id
  21043.         if exists (select runstatus from MSlogreader_history where 
  21044.             agent_id = @agent_id and
  21045.             runstatus <> 2 and 
  21046.             runstatus <> 5 and 
  21047.             runstatus <> 6 and
  21048.             timestamp = (select max(timestamp) from MSlogreader_history where agent_id = @agent_id))
  21049.             begin
  21050.                 -- Log success message.
  21051.                 exec dbo.sp_MSadd_logreader_history @agent_id = @agent_id, @runstatus = 2,
  21052.                         @comments = @message
  21053.             end
  21054.     end
  21055.     else if @category_id = 10
  21056.     begin
  21057.         -- Get agent_id
  21058.         select @agent_id = id from MSdistribution_agents where job_id = @job_id
  21059.         if exists (select runstatus from MSdistribution_history where 
  21060.             agent_id = @agent_id and
  21061.             runstatus <> 2 and 
  21062.             runstatus <> 5 and 
  21063.             runstatus <> 6 and
  21064.             timestamp = (select max(timestamp) from MSdistribution_history where agent_id = @agent_id))
  21065.             begin
  21066.                 -- Log success message.
  21067.                 exec dbo.sp_MSadd_distribution_history @agent_id = @agent_id, @runstatus = 2,
  21068.                         @comments = @message
  21069.             end
  21070.     end
  21071.     else if @category_id = 14
  21072.     begin
  21073.         -- Get agent_id
  21074.         select @agent_id = id from MSmerge_agents where job_id = @job_id
  21075.         if exists (select runstatus from MSmerge_history where 
  21076.             agent_id = @agent_id and
  21077.             runstatus <> 2 and 
  21078.             runstatus <> 5 and 
  21079.             runstatus <> 6 and
  21080.             timestamp = (select max(timestamp) from MSmerge_history where agent_id = @agent_id))
  21081.             begin
  21082.                 -- Log success message.
  21083.                 exec dbo.sp_MSadd_merge_history @agent_id = @agent_id, @runstatus = 2,
  21084.                         @comments = @message
  21085.             end
  21086.     end
  21087.     else if @category_id = 19
  21088.     begin
  21089.         -- Get agent_id
  21090.         select @agent_id = id from MSqreader_agents where job_id = @job_id
  21091.         if exists (select runstatus from MSqreader_history where 
  21092.             agent_id = @agent_id and
  21093.             runstatus <> 2 and 
  21094.             runstatus <> 5 and 
  21095.             runstatus <> 6 and
  21096.             timestamp = (select max(timestamp) from MSqreader_history where agent_id = @agent_id))
  21097.             begin
  21098.                 -- Log success message.
  21099.                 exec dbo.sp_MSadd_qreader_history @agent_id = @agent_id, @runstatus = 2,
  21100.                         @comments = @message
  21101.             end
  21102.     end
  21103.  
  21104. GO
  21105.  
  21106. create procedure sp_MSwritemergeperfcounter (
  21107.     @agent_id int,
  21108.     @thread_num int,
  21109.     @counter_desc nvarchar(100),
  21110.     @counter_value int
  21111.     )
  21112. AS
  21113.     if (not exists (select * from sysobjects where name = 'MSmerge_perfcounters'))
  21114.     begin
  21115.         create table MSmerge_perfcounters
  21116.         (
  21117.             agent_id int NOT NULL,
  21118.             thread_num int NULL,
  21119.             counter_desc nvarchar(100) NOT NULL,
  21120.             counter_value int NOT NULL,
  21121.             cur_time datetime NOT NULL
  21122.         )
  21123.     end
  21124.  
  21125.     insert into MSmerge_perfcounters values (@agent_id, @thread_num, @counter_desc, @counter_value, getdate())
  21126.  
  21127.     return 0
  21128. go
  21129. EXEC dbo.sp_MS_marksystemobject 'sp_MSwritemergeperfcounter'
  21130. go
  21131. grant execute on sp_MSwritemergeperfcounter to public
  21132. go
  21133.  
  21134. go
  21135.  
  21136. /****************************************************************************/
  21137. print ''
  21138. print 'Adding user ''guest''.'
  21139. print ''
  21140. /****************************************************************************/
  21141. if not exists (select * from sysusers where
  21142.     name = N'guest' and
  21143.     hasdbaccess = 1)
  21144.     EXEC  dbo.sp_adduser 'guest'
  21145.  
  21146. /****************************************************************************/
  21147. print ''
  21148. print 'Adding role ''replmonitor''.'
  21149. print ''
  21150. /****************************************************************************/
  21151. if not exists (select * from sysusers where
  21152.     name = N'replmonitor' and
  21153.     issqlrole = 1)
  21154.     EXEC  dbo.sp_addrole 'replmonitor'
  21155.  
  21156.  
  21157. grant execute on dbo.sp_MSdistribution_counters to public
  21158. GO 
  21159. grant execute on dbo.sp_MShelp_profile to public
  21160. GO
  21161. grant execute on dbo.sp_MShelp_subscriber_info to public
  21162. GO
  21163.  
  21164.  
  21165. /* 
  21166. Stored procedures called by dist publisher.
  21167. distributor_admin will be added to db_owner role. Members of
  21168. db_owner have permission on all the stored procedures. 
  21169.  
  21170. -- Stored procedure used by remote publisher RPC
  21171. grant execute on dbo.sp_MSbrowsesnapshotfolder to db_owner
  21172. grant execute on dbo.sp_MSadd_publication to db_owner
  21173. grant execute on dbo.sp_MSchange_publication to db_owner
  21174. grant execute on dbo.sp_MSdrop_publication to db_owner
  21175. grant execute on dbo.sp_MSadd_article to db_owner
  21176. grant execute on dbo.sp_MSchange_article to db_owner
  21177. grant execute on dbo.sp_MSdrop_article to db_owner
  21178. grant execute on dbo.sp_MSadd_subscriber_info to db_owner
  21179. grant execute on dbo.sp_MSupdate_subscriber_info to db_owner
  21180. grant execute on dbo.sp_MSadd_subscriber_schedule to db_owner
  21181. grant execute on dbo.sp_MSupdate_subscriber_schedule to db_owner
  21182. grant execute on dbo.sp_MShelp_subscriber_info to db_owner
  21183. grant execute on dbo.sp_MSdrop_subscriber_info to db_owner
  21184. grant execute on dbo.sp_MSadd_snapshot_agent to db_owner
  21185. grant execute on dbo.sp_MSdrop_snapshot_agent to db_owner
  21186. grant execute on dbo.sp_MSadd_logreader_agent to db_owner
  21187. grant execute on dbo.sp_MSdrop_logreader_agent to db_owner
  21188. grant execute on dbo.sp_MSreset_subscription to db_owner
  21189. grant execute on dbo.sp_MSenableagentoffload to db_owner
  21190. grant execute on dbo.sp_MSdisableagentoffload to db_owner
  21191. grant execute on dbo.sp_MSinsert_identity to db_owner
  21192. grant execute on dbo.sp_MSadjust_pub_identity to db_owner
  21193. grant execute on dbo.sp_MScheck_pub_identity to db_owner
  21194. grant execute on dbo.sp_MSadddynamicsnapshotjobatdistributor to db_owner
  21195. grant execute on dbo.sp_MSdrop_repl_job to db_owner
  21196. -- Stored procedure used by snapshot and logreader agents
  21197. grant execute on dbo.sp_MSadd_repl_command to db_owner
  21198. grant execute on dbo.sp_MSadd_repl_commands27 to db_owner
  21199. grant execute on dbo.sp_MSadd_repl_commands27hp to db_owner
  21200. grant execute on dbo.sp_MSadd_repl_commands27hp6x to db_owner
  21201. grant execute on dbo.sp_MSget_last_transaction to db_owner
  21202. grant execute on dbo.sp_MSset_snapshot_xact_seqno to db_owner
  21203. grant execute on dbo.sp_MSadd_snapshot_history to db_owner
  21204. grant execute on dbo.sp_MSadd_logreader_history to db_owner
  21205. grant execute on dbo.sp_MSdist_activate_auto_sub to db_owner
  21206. grant execute on dbo.sp_MSlock_auto_sub to db_owner
  21207. grant execute on dbo.sp_MSget_new_xact_seqno to db_owner
  21208. grant execute on dbo.sp_MSactivate_subscriptions to db_owner
  21209. grant execute on dbo.sp_MShelp_snapshot_agentid to db_owner
  21210. grant execute on dbo.sp_MShelp_logreader_agentid to db_owner
  21211. grant execute on dbo.sp_MSadd_subscription to public
  21212. grant execute on dbo.sp_MSupdate_subscription to public
  21213. grant execute on dbo.sp_MSdrop_subscription to public
  21214. grant execute on dbo.sp_MSadd_merge_subscription to public
  21215. grant execute on dbo.sp_MSdrop_merge_subscription to public
  21216. */
  21217.  
  21218.  
  21219.  
  21220. -- Stored procedures used by dist and merge agents. They are granted to public
  21221.  
  21222. grant execute on dbo.sp_MSmarkreinit to public
  21223. go
  21224.  
  21225. -- Procedures to retrieve actual data. Need security check inside
  21226. grant execute on dbo.sp_MSget_repl_commands to public
  21227. GO
  21228. grant execute on dbo.sp_MSget_repl_cmds_anonymous to public
  21229. GO
  21230.  
  21231. -- Procedures to modify meta data. Need security check inside.
  21232. grant execute on dbo.sp_MSadd_distribution_history to public
  21233. grant execute on dbo.sp_MSadd_repl_error to public
  21234. grant execute on dbo.sp_MSadd_repl_alert to public
  21235. grant execute on dbo.sp_MSadd_replmergealert to public
  21236. grant execute on dbo.sp_MSadd_merge_history to public
  21237. grant execute on dbo.sp_MSadd_anonymous_agent to public
  21238. grant execute on dbo.sp_MSadd_merge_anonymous_agent to public
  21239. grant execute on dbo.sp_MSdist_adjust_identity to public
  21240. GO
  21241.  
  21242. -- Procedures to retrieve meta data. No security check inside.
  21243. grant execute on dbo.sp_MSget_subscription_guid to public
  21244. grant execute on dbo.sp_MSreset_subscription_seqno to public
  21245. grant execute on dbo.sp_MSanonymous_status to public
  21246. grant execute on dbo.sp_MSsubscription_status to public
  21247. grant execute on dbo.sp_MShelp_merge_agentid to public
  21248. grant execute on dbo.sp_MScheckretention to public
  21249. grant execute on dbo.sp_MShelp_distribution_agentid to public
  21250. grant execute on dbo.sp_MScheck_tran_retention to public
  21251. grant execute on dbo.sp_MSgetagentoffloadinfo to public
  21252. grant execute on dbo.sp_MSenumdistributionagentproperties to public
  21253. grant execute on dbo.sp_MSenum_merge_agent_properties to public
  21254. grant execute on dbo.sp_MSrepl_raiserror to public
  21255. -- sp_MShelp_publication is used by the distribution control add anonymous
  21256. -- subscription logic to ascertain the existence of a publication 
  21257. grant execute on dbo.sp_MShelp_publication to public
  21258. -- sp_MSenum_replication_status to load repl monitor status table
  21259. -- The status table is global and shared by all users. A user in
  21260. -- replmonitor role in any dist db may load the table, the proc
  21261. -- has to be granted to public.
  21262. grant execute on sp_MSenum_replication_status to public
  21263. go
  21264.  
  21265. -- grant monitoring sps to replmonitor
  21266. GRANT exec on sp_MShelp_publication to replmonitor 
  21267. GRANT exec on sp_MSenum_subscriptions to replmonitor 
  21268. GRANT exec on sp_MSIfExistsSubscription to replmonitor 
  21269. GRANT exec on sp_MSenum_merge_subscriptions to replmonitor 
  21270. GRANT exec on sp_MSenum_distribution to replmonitor 
  21271. GRANT exec on sp_MSenum_merge to replmonitor 
  21272. GRANT exec on sp_MSenum_snapshot to replmonitor 
  21273. GRANT exec on sp_MSenum_logreader to replmonitor
  21274. GRANT exec on sp_MSenum_qreader to replmonitor 
  21275. GRANT exec on sp_MSenum_snapshot_s to replmonitor 
  21276. GRANT exec on sp_MSenum_logreader_s to replmonitor
  21277. GRANT exec on sp_MSenum_distribution_s to replmonitor
  21278. GRANT exec on sp_MSenum_merge_s to replmonitor 
  21279. GRANT exec on sp_MSenum_qreader_s to replmonitor 
  21280. GRANT exec on sp_MSenum_snapshot_sd to replmonitor 
  21281. GRANT exec on sp_MSenum_logreader_sd to replmonitor
  21282. GRANT exec on sp_MSenum_distribution_sd to replmonitor
  21283. GRANT exec on sp_MSenum_merge_sd to replmonitor
  21284. GRANT exec on sp_MSenum_qreader_sd to replmonitor
  21285. GRANT exec on sp_MSget_repl_error to replmonitor
  21286. go
  21287.  
  21288.  
  21289. declare @dbname sysname
  21290. select  @dbname = db_name()
  21291. execute('dump transaction ' +@dbname+ ' with no_log')
  21292. go
  21293. checkpoint
  21294.  
  21295. go
  21296.  
  21297. exec dbo.sp_MS_upd_sysobj_category 2  --Now do catalog updates.
  21298.  
  21299. go
  21300.  
  21301. EXEC dbo.sp_configure 'allow updates', 0
  21302. GO
  21303.  
  21304. reconfigure with override
  21305. GO
  21306. -- - ----
  21307.