home *** CD-ROM | disk | FTP | other *** search
/ Enter 2001 April / EnterCD4.iso / Update / SQL Server SP3 / sql70sp3i.exe / INSTALL / sp2_repl.sql < prev    next >
Encoding:
Text File  |  2000-02-17  |  730.3 KB  |  22,340 lines

  1. /*------------------------------------------------------------------------------
  2.  
  3. sp2_repl.sql
  4.  
  5. THIS SCRIPT UPDATES REPLICATION SYSTEM STORED PROCEDURES FROM 7.0 SP1 and SP2.
  6.  
  7. Changes in this file are organized as follows (please maintain):
  8.     Common system objects (replsys.sql)
  9.     Common repl objects (replcom.sql)
  10.     Tran repl objects (repltran.sql) 
  11.     Merge repl objects (rladmin.sql, rlrecon.sql, rlcore.sql)
  12.  
  13. Notes:
  14. + Catalog-updates and sp_MS_upd_sysobj_category are enabled for the entire
  15.     file.  Do not disable or re-enable them.  Please do not change set options.
  16. + grep for "--.
  17. ------------------------------------------------------------------------------*/
  18.  
  19.  
  20. --------------------------------------------------------------------------------
  21. -- VERIFY Server is started in single-user-mode (catalog-updates enabled), and
  22. --    start marking of system-objects.
  23. --------------------------------------------------------------------------------
  24. use master
  25. go
  26.  
  27. dump tran master with no_log
  28. go
  29.  
  30. exec dbo.sp_configure 'allow updates',1
  31. go
  32. reconfigure with override
  33. go
  34.  
  35. set ANSI_NULLS off
  36.  
  37. exec sp_MS_upd_sysobj_category 1
  38. go
  39.  
  40. --------------------------------------------------------------------------------
  41. --.    Common system objects (replsys.sql)
  42. --------------------------------------------------------------------------------
  43.  
  44. --------------------------------------------------------------------------------
  45. --. Update MSreplication_options indexes
  46. --------------------------------------------------------------------------------
  47. raiserror('Creating ucMSreplication_options if needed', 0,1)
  48. GO
  49. IF NOT EXISTS ( SELECT * FROM sysindexes where name = 'ucMSreplication_options' and 
  50.                 id = OBJECT_ID('MSreplication_options'))
  51. CREATE UNIQUE CLUSTERED INDEX ucMSreplication_options ON MSreplication_options(optname)
  52. GO
  53.  
  54. --------------------------------------------------------------------------------
  55. --. Drop sp_vupgrade_MSsubscription_properties - no longer used
  56. --------------------------------------------------------------------------------
  57. raiserror('Dropping procedure sp_vupgrade_MSsubscription_properties if needed', 0,1)
  58. GO
  59. if exists (select * from sysobjects    where type = 'P'
  60.     and name = 'sp_vupgrade_MSsubscription_properties')
  61.     drop procedure sp_vupgrade_MSsubscription_properties
  62. go
  63.  
  64. --------------------------------------------------------------------------------
  65. --. Drop sp_vupgrade_publisher - no longer used
  66. --------------------------------------------------------------------------------
  67. raiserror('Dropping procedure sp_vupgrade_publisher if needed', 0,1)
  68. GO
  69. if exists (select * from sysobjects    where type = 'P'
  70.     and name = 'sp_vupgrade_publisher')
  71.     drop procedure sp_vupgrade_publisher
  72. go
  73.  
  74. --------------------------------------------------------------------------------
  75. --. Drop sp_vupgrade_publisherdb - no longer used
  76. --------------------------------------------------------------------------------
  77. raiserror('Dropping procedure sp_vupgrade_publisherdb if needed', 0,1)
  78. GO
  79. if exists (select * from sysobjects    where type = 'P'
  80.     and name = 'sp_vupgrade_publisherdb')
  81.     drop procedure sp_vupgrade_publisherdb
  82. go
  83.  
  84. --------------------------------------------------------------------------------
  85. --. sp_MSreplcheck_name
  86. --------------------------------------------------------------------------------
  87. if exists (select * from sysobjects    where type = 'P'
  88.     and name = 'sp_MSreplcheck_name')
  89.     drop procedure sp_MSreplcheck_name
  90. go
  91.  
  92. raiserror('Creating procedure sp_MSreplcheck_name', 0,1)
  93. GO
  94.  
  95. CREATE PROCEDURE sp_MSreplcheck_name
  96.     @name            sysname,
  97.     @raise_error    bit = 1
  98. AS
  99.     declare @index    int
  100.  
  101.     Set nocount on
  102.  
  103.     -- Name cannot be NULL or empty ("")
  104.     -- Blank identifiers (" ") are allowed
  105.     IF (@name is null OR datalength(@name) = 0)
  106.     begin
  107.         if @raise_error = 1
  108.             raiserror (15004,16,-1)
  109.         return (1)
  110.     end
  111.  
  112.     -- Check for proscribed characters
  113.  
  114.     declare @length int
  115.     select @length = datalength( @name ) / 2
  116.     select @index = 1
  117.     while @index < @length
  118.     begin
  119.         if( 0 = unicode( substring( @name, @index, 1 ) ) )
  120.         begin
  121.             if @raise_error = 1
  122.                 raiserror(15006,16,-1,@name)
  123.             return (1)
  124.         end
  125.  
  126.         select @index = @index + 1
  127.     end
  128.  
  129.     --check for other proscribed characters
  130.  
  131.     select @index = charindex( N'%', @name)
  132.     if (@index <> 0)
  133.     begin
  134.         if @raise_error = 1
  135.             raiserror(15006,16,-1,@name)
  136.         return (1)
  137.     end
  138.     select @index = charindex(N'*', @name)
  139.     if (@index <> 0)
  140.     begin
  141.         if @raise_error = 1
  142.             raiserror(15006,16,-1,@name)
  143.         return (1)
  144.     end
  145.     select @index = charindex(N'[', @name)
  146.     if (@index <> 0)
  147.     begin
  148.         if @raise_error = 1
  149.             raiserror(15006,16,-1,@name)
  150.         return (1)
  151.     end
  152.     select @index = charindex(N']', @name)
  153.     if (@index <> 0)
  154.     begin
  155.         if @raise_error = 1
  156.             raiserror(15006,16,-1,@name)
  157.         return (1)
  158.     end
  159.     select @index = charindex(N'|', @name)
  160.     if (@index <> 0)
  161.     begin
  162.         if @raise_error = 1
  163.             raiserror(15006,16,-1,@name)
  164.         return (1)
  165.     end
  166.     select @index = charindex(N':', @name)
  167.     if (@index <> 0)
  168.     begin
  169.         if @raise_error = 1
  170.             raiserror(15006,16,-1,@name)
  171.         return (1)
  172.     end
  173.     select @index = charindex(N'"', @name)
  174.     if (@index <> 0)
  175.     begin
  176.         if @raise_error = 1
  177.             raiserror(15006,16,-1,@name)
  178.         return (1)
  179.     end
  180.     select @index = charindex(N'?', @name)
  181.     if (@index <> 0)
  182.     begin
  183.         if @raise_error = 1
  184.             raiserror(15006,16,-1,@name)
  185.         return (1)
  186.     end
  187.     /*
  188.     ** Fix 52855 - allow single quote
  189.     **
  190.     select @index = charindex(N'''', @name)
  191.     if (@index <> 0)
  192.     begin
  193.         if @raise_error = 1
  194.             raiserror(15006,16,-1,@name)
  195.         return (1)
  196.     end
  197.     */
  198.     select @index = charindex(N'\', @name)
  199.     if (@index <> 0)
  200.     begin
  201.         if @raise_error = 1
  202.             raiserror(15006,16,-1,@name)
  203.         return (1)
  204.     end
  205.     select @index = charindex(N'/', @name)
  206.     if (@index <> 0)
  207.     begin
  208.         if @raise_error = 1
  209.             raiserror(15006,16,-1,@name)
  210.         return (1)
  211.     end
  212.     select @index = charindex(N'<', @name)
  213.     if (@index <> 0)
  214.     begin
  215.         if @raise_error = 1
  216.             raiserror(15006,16,-1,@name)
  217.         return (1)
  218.     end
  219.     select @index = charindex(N'>', @name)
  220.     if (@index <> 0)
  221.     begin
  222.         if @raise_error = 1
  223.             raiserror(15006,16,-1,@name)
  224.         return (1)
  225.     end
  226.     
  227.     -- return success
  228.  
  229.     return (0) 
  230. GO
  231.     
  232. --------------------------------------------------------------------------------
  233. --. sp_MScreate_mergesystables
  234. --------------------------------------------------------------------------------
  235. if exists (select * from sysobjects    where type = 'P'
  236.     and name = 'sp_MScreate_mergesystables')
  237.     drop procedure sp_MScreate_mergesystables
  238. go
  239.  
  240. raiserror('Creating procedure sp_MScreate_mergesystables',0,1)
  241. GO
  242. create procedure sp_MScreate_mergesystables as
  243.  
  244.     /* This is to make sure that the varbinary columns do not get padded */
  245.  
  246.     set ANSI_PADDING off
  247.  
  248.     DECLARE @exist bit 
  249.     DECLARE @validsubs  int
  250.     select @exist = 1
  251.     
  252.     begin tran
  253.     save transaction MScreate_mergesystables
  254.  
  255.     exec dbo.sp_MScheckvalidsystables  @validsubs  output
  256.     if @validsubs = 0
  257.         exec dbo.sp_MSdrop_mergesystables
  258.         
  259.     if not exists (select * from sysobjects where name = 'sysmergepublications')
  260.         begin
  261.  
  262.             raiserror('Creating table sysmergepublications',0,1)
  263.             
  264.             create table dbo.sysmergepublications
  265.             (    publisher                sysname NOT NULL default @@servername,
  266.                 publisher_db            sysname NOT NULL default db_name(),
  267.                 name                    sysname                NOT NULL,
  268.                 description                nvarchar(255)         NULL,
  269.                 retention                int                    NULL,
  270.                 publication_type         tinyint                NULL,
  271.                 pubid                     uniqueidentifier     NOT NULL,
  272.                 designmasterid            uniqueidentifier     NULL,
  273.                 parentid                uniqueidentifier     NULL,
  274.                 sync_mode                tinyint                NULL,
  275.                 allow_push                int                    NULL,
  276.                 allow_pull                int                    NULL,
  277.                 allow_anonymous            int                    NULL,
  278.                 centralized_conflicts    int                    NULL,
  279.                 status                    tinyint                NULL,
  280.                 snapshot_ready            tinyint                NULL,
  281.                 enabled_for_internet    bit                    NOT NULL default 0,
  282.                 dynamic_filters            bit                    NOT NULL default 0,
  283.                 keep_before_values            int                NULL default 0
  284.  
  285.             )
  286.             if @@ERROR <> 0
  287.                 goto Error
  288.             else
  289.                 begin
  290.                     create unique nonclustered index nc1sysmergepublications
  291.                         on sysmergepublications(pubid) 
  292.                     if @@ERROR <> 0
  293.                         goto Error
  294.                 end
  295.             
  296.             exec dbo.sp_MS_marksystemobject sysmergepublications
  297.             if @@ERROR <> 0
  298.                 goto Error
  299.             grant select on sysmergepublications to public
  300.         end
  301.  
  302.  
  303.     if not exists (select * from sysobjects where name = 'sysmergearticles')
  304.         begin
  305.         
  306.             raiserror('Creating table sysmergearticles',0,1)
  307.  
  308.             
  309.             create table dbo.sysmergearticles (
  310.                 name                    sysname                NOT NULL,
  311.                 type                    tinyint                NULL,
  312.                 objid                    int                    NOT NULL,
  313.                 sync_objid                int                    NOT NULL,
  314.                 view_type                 tinyint                NULL,
  315.                 artid                    uniqueidentifier    NOT NULL,
  316.                 description                nvarchar(255)        NULL,
  317.                 pre_creation_command    tinyint                NULL,
  318.                 pubid                    uniqueidentifier     NOT NULL,
  319.                 nickname                int                    NOT NULL,
  320.                 column_tracking            int                    NOT NULL,
  321.                 status                    tinyint                NULL,
  322.                 conflict_table            sysname                NULL,
  323.                 creation_script            nvarchar(255)        NULL,
  324.                 conflict_script            nvarchar(255)        NULL,
  325.                 article_resolver        nvarchar(255)        NULL,
  326.                 ins_conflict_proc        sysname                NULL,
  327.                 insert_proc                sysname                NULL,
  328.                 update_proc                sysname                NULL,
  329.                 select_proc                sysname                NULL,
  330.                 schema_option             binary(8)             NULL,
  331.                 destination_object        sysname                NOT NULL,
  332.                 resolver_clsid            nvarchar(50)        NULL,
  333.                 subset_filterclause        nvarchar(1000)      NULL,
  334.                 missing_col_count        int                    NULL,
  335.                 missing_cols            varbinary(128)        NULL,
  336.                 columns                    varbinary(128)       NULL,
  337.                 resolver_info            nvarchar(255)        NULL,
  338.                 view_sel_proc            nvarchar(290)        NULL,
  339.                 gen_cur                    int                    NULL,
  340.                 before_image_objid        int                    NULL,
  341.                 before_view_objid        int                    NULL
  342.  
  343.             )
  344.         
  345.             if @@error<>0
  346.                 goto Error
  347.             else
  348.                 begin
  349.                     create unique clustered index uc1sysmergearticles
  350.                         on sysmergearticles(artid, pubid) 
  351.                     if @@ERROR <> 0
  352.                         goto Error
  353.                 end
  354.             exec dbo.sp_MS_marksystemobject sysmergearticles
  355.             if @@ERROR <> 0
  356.                 goto Error
  357.             grant select on sysmergearticles to public
  358.             
  359.         end
  360.  
  361.     if not exists (select * from sysobjects    where name = 'sysmergesubscriptions')
  362.         begin
  363.         
  364.             raiserror('Creating table sysmergesubscriptions',0,1)
  365.  
  366.             
  367.             create table dbo.sysmergesubscriptions
  368.             (
  369.                 subid                 uniqueidentifier     NOT NULL,
  370.                 partnerid             uniqueidentifier     NOT NULL,
  371.                 datasource_type        int                    NOT NULL,
  372.                 datasource_path        nvarchar(255)        NULL,
  373.                 srvid                 int                    NOT NULL,
  374.                 db_name                  sysname                 NOT NULL
  375.                 constraint             unique_pubsrvdb     unique nonclustered (pubid, srvid, db_name),
  376.                 pubid                uniqueidentifier     NULL,
  377.                 status                tinyint             NOT NULL,
  378.                 subscriber_type        int                    NOT NULL,
  379.                 subscription_type    int                    NOT NULL,
  380.                 priority            real                NOT NULL,
  381.                 sync_type             tinyint                NOT NULL,    -- 1 = automatic 2 = no sync
  382.                 description            nvarchar(255)        NULL,
  383.                 login_name            sysname                NOT NULL,
  384.                 last_validated        datetime            NULL
  385.             )
  386.         
  387.             if @@error<>0
  388.                 goto Error
  389.             else
  390.                 begin
  391.                     create unique clustered index uc1sysmergesubscriptions 
  392.                         on sysmergesubscriptions (subid) 
  393.                     if @@ERROR<>0
  394.                         goto Error
  395.                 end
  396.             exec dbo.sp_MS_marksystemobject sysmergesubscriptions
  397.             if @@ERROR <> 0
  398.                 goto Error
  399.             grant select on sysmergesubscriptions to public
  400.             
  401.         end
  402.  
  403.     if not exists (select * from sysobjects    where name = 'MSmerge_replinfo')
  404.         begin
  405.             raiserror('Creating table MSmerge_replinfo',0,1)
  406.             
  407.             create table dbo.MSmerge_replinfo
  408.             (
  409.                 repid                     uniqueidentifier     NOT NULL,
  410.                 replnickname            int                    NOT NULL,
  411.                 recgen                    int                 NULL,
  412.                 recguid                    uniqueidentifier     NULL,
  413.                 sentgen                    int                 NULL,
  414.                 sentguid                uniqueidentifier     NULL,
  415.                 schemaversion            int                 NULL,
  416.                 schemaguid                uniqueidentifier     NULL,
  417.                 merge_jobid                binary(16)            NULL,
  418.                 snapshot_jobid            binary(16)            NULL
  419.             )
  420.         
  421.             if @@ERROR <> 0
  422.                 goto Error
  423.             else
  424.                 begin
  425.                     create unique clustered index uc1MSmerge_replinfo
  426.                         on MSmerge_replinfo (repid)
  427.                     if @@ERROR <> 0
  428.                         goto Error
  429.                 end
  430.             exec dbo.sp_MS_marksystemobject MSmerge_replinfo
  431.             if @@ERROR <> 0
  432.                 goto Error
  433.             grant select on MSmerge_replinfo to public
  434.             
  435.         end
  436.  
  437.     if not exists (select * from sysobjects    where name = 'MSmerge_tombstone')
  438.         begin
  439.             raiserror('Creating table MSmerge_tombstone',0,1)
  440.             
  441.             create table dbo.MSmerge_tombstone
  442.             (
  443.                 rowguid            uniqueidentifier rowguidcol NOT NULL,
  444.                 tablenick        int                NOT NULL,
  445.                 type            tinyint            NOT NULL,
  446.                 lineage            varbinary(255)    NOT NULL,
  447.                 generation        int                NOT NULL,
  448.                 reason            nvarchar(255)    NOT NULL,
  449.             )
  450.  
  451.             if @@ERROR <> 0
  452.                 goto Error
  453.             else
  454.                 begin
  455.                     create unique clustered index uc1MSmerge_tombstone
  456.                         on MSmerge_tombstone (tablenick, rowguid) 
  457.                     if @@ERROR <> 0
  458.                         goto Error
  459.                     create index nc2MSmerge_tombstone
  460.                         on MSmerge_tombstone (generation) 
  461.                     if @@ERROR <> 0
  462.                         goto Error
  463.                 end    
  464.              exec dbo.sp_MS_marksystemobject MSmerge_tombstone
  465.              if @@ERROR <> 0
  466.                 goto Error
  467.             grant select on MSmerge_tombstone to public
  468.             
  469.         end
  470.  
  471.     if not exists (select * from sysobjects    where name = 'MSmerge_contents')
  472.         begin
  473.             raiserror('Creating table MSmerge_contents',0,1)
  474.             
  475.             create table dbo.MSmerge_contents
  476.             (
  477.                 tablenick        int                    NOT NULL,
  478.                 rowguid            uniqueidentifier rowguidcol   NOT NULL,
  479.                 generation        int                    NOT NULL,
  480.                 partchangegen    int                    NULL,
  481.                 joinchangegen    int                    NULL,
  482.                 lineage            varbinary(249)        NOT NULL,
  483.                 colv1            varbinary(2048)        NULL,
  484.             )
  485.         
  486.             if @@ERROR <> 0
  487.                 goto Error
  488.             else
  489.                 begin
  490.                     create unique clustered index uc1SycContents on MSmerge_contents( tablenick, rowguid )
  491.                     if @@ERROR <> 0
  492.                         goto Error
  493.                     create index nc2MSmerge_contents on MSmerge_contents(tablenick, generation) 
  494.                     if @@ERROR <> 0
  495.                         goto Error
  496.                     create index nc3MSmerge_contents on MSmerge_contents(tablenick, partchangegen) 
  497.                     if @@ERROR <> 0
  498.                         goto Error
  499.                     create index nc4MSmerge_contents on MSmerge_contents(generation, partchangegen) 
  500.                     if @@ERROR <> 0
  501.                         goto Error
  502.                 end
  503.             exec dbo.sp_MS_marksystemobject MSmerge_contents
  504.             if @@ERROR <> 0
  505.                 goto Error
  506.             grant select on MSmerge_contents to public
  507.             
  508.         end                
  509.  
  510.     if not exists (select * from sysobjects    where name = 'MSmerge_genhistory')
  511.         begin
  512.             raiserror('Creating table MSmerge_genhistory',0,1)
  513.             
  514.             create table dbo.MSmerge_genhistory
  515.             (
  516.                 guidsrc         uniqueidentifier     NOT NULL,
  517.                 guidlocal         uniqueidentifier     NOT NULL,
  518.                 pubid            uniqueidentifier     NULL,
  519.                 generation         int                    NOT NULL,
  520.                 art_nick        int                    NULL,
  521.                 nicknames        varbinary(255)        NOT NULL,
  522.                 coldate         datetime            NOT NULL
  523.             )
  524.         
  525.             if @@ERROR <> 0
  526.                 goto Error
  527.             create clustered index uc1MSmerge_genhistory on MSmerge_genhistory(guidsrc) 
  528.             if @@ERROR <> 0
  529.                 goto Error
  530.  
  531.             create  index nc1MSmerge_genhistory on MSmerge_genhistory(generation) 
  532.             if @@ERROR <> 0
  533.                 goto Error
  534.  
  535.             create  index nc2MSmerge_genhistory on MSmerge_genhistory(guidlocal) 
  536.             if @@ERROR <> 0
  537.                 goto Error
  538.  
  539.             create  unique index nc3MSmerge_genhistory on MSmerge_genhistory(guidsrc, pubid)
  540.             if @@ERROR <> 0
  541.                 goto Error
  542.  
  543.             create  index nc4MSmerge_genhistory on MSmerge_genhistory(coldate) 
  544.             if @@ERROR <> 0
  545.                 goto Error
  546.  
  547.              exec dbo.sp_MS_marksystemobject MSmerge_genhistory
  548.              if @@ERROR <> 0
  549.                 goto Error
  550.             grant select on MSmerge_genhistory to public
  551.             
  552.         end
  553.  
  554.     if not exists (select * from sysobjects    where name = 'MSmerge_delete_conflicts')
  555.         begin
  556.  
  557.             raiserror('Creating table MSmerge_delete_conflicts',0,1)
  558.             
  559.             create table dbo.MSmerge_delete_conflicts
  560.             (
  561.                 tablenick            int                NOT NULL,
  562.                 rowguid                uniqueidentifier rowguidcol NOT NULL,
  563.                 origin_datasource    nvarchar(255)    NULL,
  564.                 conflict_type        int NULL,
  565.                 reason_code            int NULL,
  566.                 reason_text            nvarchar(720)     NULL,
  567.                 pubid                uniqueidentifier NULL
  568.             )
  569.         
  570.             if @@ERROR <> 0
  571.                 goto Error
  572.             else
  573.                 begin
  574.                     create clustered index uc1MSmerge_delete_conflicts on MSmerge_delete_conflicts(tablenick, rowguid) 
  575.                     if @@ERROR <> 0
  576.                         goto Error
  577.                 end    
  578.  
  579.             create  unique index nc1MSmerge_delete_conflicts on MSmerge_delete_conflicts(tablenick, rowguid, origin_datasource)
  580.             if @@ERROR <> 0
  581.                 goto Error    
  582.                                 
  583.             exec dbo.sp_MS_marksystemobject MSmerge_delete_conflicts
  584.             if @@ERROR <> 0
  585.                 goto Error
  586.             grant select on MSmerge_delete_conflicts to public
  587.             
  588.         end
  589.  
  590.     if not exists (select * from sysobjects    where name = 'sysmergeschemachange')
  591.         begin
  592.         
  593.             raiserror('Creating table sysmergeschemachange',0,1)
  594.             
  595.             create table dbo.sysmergeschemachange
  596.             (
  597.                 pubid            uniqueidentifier     NOT NULL,
  598.                 artid            uniqueidentifier     NULL,
  599.                 schemaversion     int                    NOT NULL,
  600.                 schemaguid        uniqueidentifier     NOT NULL,
  601.                 schematype        int                      NOT NULL,
  602.                 schematext        nvarchar(2000)         NOT NULL
  603.             )
  604.         
  605.             if @@ERROR <> 0
  606.                 goto Error
  607.             else
  608.                 begin
  609.                     create unique clustered index schemachangeversion on sysmergeschemachange(schemaversion, pubid) 
  610.                     if @@ERROR <> 0
  611.                         goto Error
  612.                 end
  613.  
  614.             exec dbo.sp_MS_marksystemobject sysmergeschemachange
  615.             if @@ERROR <> 0
  616.                 goto Error
  617.             grant select on sysmergeschemachange to public
  618.             
  619.         end
  620.  
  621.     if not exists (select * from sysobjects where name = 'sysmergesubsetfilters')
  622.         begin
  623.             raiserror('Creating table sysmergesubsetfilters',0,1)
  624.  
  625.             
  626.             create table dbo.sysmergesubsetfilters (
  627.                 filtername              sysname                 NOT NULL,
  628.                 join_filterid            int                    identity NOT NULL,
  629.                 pubid                    uniqueidentifier    NOT NULL,
  630.                 artid                    uniqueidentifier    NOT NULL,
  631.                 art_nickname            int                    NOT NULL,
  632.                 join_articlename        sysname NOT NULL,
  633.                 join_nickname             int                    NOT NULL,
  634.                 join_unique_key            int                    NOT NULL,
  635.                 expand_proc                sysname                    NULL,
  636.                 join_filterclause        nvarchar(1000)          NULL
  637.             )
  638.             if @@ERROR <> 0
  639.                 goto Error
  640.             else 
  641.                 begin 
  642.                     create unique index nc1sysmergesubsetfilters on sysmergesubsetfilters(join_filterid, pubid)
  643.                         if @@ERROR <> 0
  644.                         goto Error
  645.                 end
  646.  
  647.             exec dbo.sp_MS_marksystemobject sysmergesubsetfilters
  648.             if @@ERROR <> 0
  649.                 goto Error
  650.             grant select on sysmergesubsetfilters to public
  651.             
  652.         end
  653.  
  654.         if @@error <> 0
  655.             return(1)
  656.  
  657.     commit transaction
  658.     return (0)
  659. Error:
  660.     if @@trancount > 0
  661.     begin
  662.         ROLLBACK TRANSACTION MScreate_mergesystables
  663.         COMMIT TRANSACTION
  664.     end
  665.     RAISERROR (20008, 16, -1)
  666.     return (1)
  667. go
  668.  
  669. --------------------------------------------------------------------------------
  670. --. Update permissions for sp_MStestbit
  671. --------------------------------------------------------------------------------
  672. raiserror('Granting execution on sp_MStestbit to public', 0,1)
  673. go
  674. grant exec on dbo.sp_MStestbit to public
  675. go
  676.  
  677. --------------------------------------------------------------------------------
  678. --. Update permissions for sp_MSsetbit
  679. --------------------------------------------------------------------------------
  680.  
  681. raiserror('Granting execution on sp_MSsetbit to public', 0,1)
  682. go
  683. grant exec on dbo.sp_MSsetbit to public
  684. go
  685.  
  686. --------------------------------------------------------------------------------
  687. --. sp_MSunmarkifneeded
  688. --------------------------------------------------------------------------------
  689. if exists (select * from sysobjects    where type = 'P'
  690.     and name = 'sp_MSunmarkifneeded')
  691.     drop procedure sp_MSunmarkifneeded
  692. go
  693.  
  694. raiserror('Creating procedure sp_MSunmarkifneeded',0,1)
  695. GO
  696.  
  697. CREATE PROCEDURE sp_MSunmarkifneeded(
  698. @object                sysname,
  699. @pubid                uniqueidentifier,
  700. @pre_command         int = 1,
  701. @publisher            sysname = NULL,
  702. @publisher_db        sysname = NULL
  703. )AS
  704. declare @table_in_use    int
  705. declare @retcode         int
  706.  
  707. select @table_in_use = 0
  708. --if pre-creation_command is 'drop (1)' or 'truncate (3)', then disallow this deployment if there is already an article using that table.
  709. --other commands, 'delete', and 'none' are fine', as long as the publication does not originate from same database.
  710.  
  711. if exists (select * from sysmergearticles where objid=object_id(@object) and pubid in
  712.     (select pubid from sysmergepublications where LOWER(publisher)=LOWER(@publisher) and 
  713.         publisher_db=@publisher_db and pubid<>@pubid))
  714.     OR
  715.     ((@pre_command=1 or @pre_command=3) and 
  716.         EXISTS (select * from sysmergearticles where objid=object_id(@object) and pubid <> @pubid))
  717. begin
  718.     select @table_in_use = 1
  719.     select @table_in_use
  720.     return (0)
  721. end
  722. exec @retcode = sp_MSunmarkreplinfo @object
  723. if @retcode <>0 or @@error<>0
  724.     return (1)
  725. select @table_in_use 
  726. return (0)
  727. GO
  728.  
  729. grant exec on dbo.sp_MSunmarkifneeded to public
  730. go
  731.  
  732. --------------------------------------------------------------------------------
  733. --. sp_reinitmergepullsubscription
  734. --------------------------------------------------------------------------------
  735. if exists (select * from sysobjects    where type = 'P'
  736.     and name = 'sp_reinitmergepullsubscription')
  737.     drop procedure sp_reinitmergepullsubscription
  738. go
  739.  
  740. raiserror('Creating procedure sp_reinitmergepullsubscription', 0, 1)
  741. GO
  742.  
  743. create procedure sp_reinitmergepullsubscription
  744.     @publisher        sysname  = 'all',
  745.     @publisher_db    sysname  = 'all',
  746.     @publication    sysname  = 'all'
  747. AS
  748.     declare @schemaversion            int
  749.     declare @schematype                smallint
  750.     declare @retcode                int
  751.     declare @schemaguid                uniqueidentifier
  752.     declare @pubname                sysname
  753.     declare @publisher_name            sysname
  754.     declare @pubdb                    sysname
  755.     declare @pubid                    uniqueidentifier
  756.     declare @subid                    uniqueidentifier
  757.     declare @artid                    uniqueidentifier
  758.     /*
  759.     ** Replace 'all' with '%'
  760.     */
  761.  
  762.     if LOWER(@publication) = 'all'
  763.         SELECT @publication = '%'
  764.  
  765.     if LOWER(@publisher) = 'all'
  766.         SELECT @publisher = '%'
  767.  
  768.     if LOWER(@publisher_db) = 'all'
  769.         SELECT @publisher_db = '%'
  770.     /*
  771.     ** At subscriber side, we need to qualify the publication with server name and database name
  772.     */
  773.     IF NOT EXISTS (SELECT * FROM sysmergepublications WHERE name LIKE @publication 
  774.         and ((@publisher = N'%') or (UPPER(publisher) = UPPER(@publisher))) 
  775.         and publisher_db like @publisher_db)
  776.         
  777.         BEGIN
  778.         IF @publication = '%'
  779.                 RAISERROR (14008, 11, -1)
  780.         ELSE
  781.                 RAISERROR (20026, 11, -1, @publication)
  782.         RETURN (1)
  783.         END
  784.     
  785.     Declare SYN_CUR CURSOR LOCAL FAST_FORWARD FOR 
  786.         select subs.subid, pubs.name, pubs.publisher, pubs.publisher_db 
  787.             from sysmergepublications pubs, sysmergesubscriptions subs
  788.                 where pubs.name LIKE  @publication
  789.                     AND ((@publisher = '%') OR (UPPER(pubs.publisher) = UPPER(@publisher)))
  790.                     AND pubs.publisher_db LIKE @publisher_db
  791.                     AND pubs.pubid=subs.pubid
  792.                     AND subs.pubid<>subs.subid
  793.     FOR READ ONLY
  794.     open SYN_CUR
  795.     fetch SYN_CUR into @subid, @pubname, @publisher_name, @pubdb
  796.     while (@@fetch_status<>-1)
  797.     BEGIN
  798.         exec @retcode=sp_MSCleanupForPullReinit @publication=@pubname, @publisher=@publisher_name, @publisher_db=@pubdb
  799.         if @retcode<>0 or @@ERROR<>0
  800.             return (1)
  801.         update MSmerge_replinfo set schemaversion=-1, recgen = NULL, recguid=NULL, sentgen=NULL, sentguid = NULL 
  802.             where repid=@subid  AND schemaversion is NOT NULL
  803.         fetch next from SYN_CUR into @subid, @pubname, @publisher_name, @pubdb
  804.             -- so that it won't be treated as a new susbscription    
  805.     END
  806.     close SYN_CUR
  807.     deallocate SYN_CUR
  808.     -- Forget that publisher ever sent us any generations.  They must be resent.
  809.     -- Publication cleanup will remove the genhistory rows.
  810.  
  811.     if @publication = '%'
  812.         -- get them all
  813.         update MSmerge_replinfo set recgen = NULL, recguid=NULL, sentgen=NULL, sentguid = NULL
  814.     else
  815.         begin
  816.         select @pubid = pubid from sysmergepublications where name = @publication
  817.         update MSmerge_replinfo set recgen = NULL, recguid=NULL, sentgen=NULL, sentguid = NULL
  818.             where repid in (select subid from sysmergesubscriptions where pubid = @pubid)
  819.         end
  820. GO
  821.  
  822. grant execute on dbo.sp_reinitmergepullsubscription to public
  823. go
  824.  
  825. --------------------------------------------------------------------------------
  826. --. sp_MSenumallpublications
  827. --------------------------------------------------------------------------------
  828. if exists (select * from sysobjects    where type = 'P'
  829.     and name = 'sp_MSenumallpublications')
  830.     drop procedure sp_MSenumallpublications
  831. go
  832.  
  833. raiserror('Creating procedure sp_MSenumallpublications', 0,1)
  834. go
  835.  
  836. CREATE PROCEDURE sp_MSenumallpublications(
  837. @publisherdb sysname = '%', 
  838. @replication_type tinyint = 1,
  839. @agent_login sysname = NULL,
  840. @security_check bit = 1 -- Security check by default so that things depending on security 
  841.                         -- filtering will not break immediately
  842. )
  843.  
  844. as
  845.     set nocount on
  846.     declare @dbname         sysname
  847.     declare @trans             tinyint
  848.     declare @merge             tinyint
  849.     declare @3rdparty        tinyint
  850.     declare @retcode        int
  851.     DECLARE @dist_rpcname    sysname
  852.     declare @distribdb        sysname
  853.     declare @login            sysname
  854.     declare @proc            nvarchar(255)
  855.     declare @distbit        int
  856.     declare @is_user_admin    bit
  857.     declare @same_as_user    bit
  858.  
  859.     -- UI: If the distributor is not installed, return empty result
  860.     if not exists (SELECT * FROM master..sysservers
  861.               WHERE  srvstatus & 8 <> 0)
  862.         return (0)
  863.  
  864.     -- UI: Win95 subscriber will send in null agent_login
  865.     -- Assume the agent login to be the current login if it is NT login
  866.     if @security_check = 1 and @agent_login is null
  867.         and not exists (select * from master.dbo.syslogins where
  868.             sid = suser_sid() and 
  869.             isntname = 0)
  870.         select @agent_login = suser_sname(suser_sid())
  871.  
  872.     /* Initializations */
  873.     select @trans = 1 
  874.     select @merge = 2
  875.     select @3rdparty = 0
  876.     select @login = suser_sname(suser_sid())
  877.     SELECT @distbit = 16
  878.     select @is_user_admin = 0
  879.     select @same_as_user = 0
  880.  
  881.     -- Get publication list
  882.     create table #pubdbs (publisher_db sysname NOT NULL, replication_type int NOT NULL)
  883.  
  884.     /* Return everything if @replication_type is not in (@3rdparty, @trans, @merge) */
  885.     if not @replication_type in (@3rdparty, @trans, @merge)
  886.         select @replication_type = null
  887.  
  888.     if @replication_type = @trans or @replication_type is null
  889.         insert into #pubdbs select name, @trans from master..sysdatabases where 
  890.             name like @publisherdb and category & 1 <> 0 and 
  891.             (isnull(databaseproperty(name, N'issuspect'), 0) = 0 and isnull(databaseproperty(name, N'isshutdown'), 0) = 0) and 
  892.             has_dbaccess(name) = 1
  893.     if @replication_type = @merge or @replication_type is null
  894.         insert into #pubdbs select name, @merge from master..sysdatabases where 
  895.             name like @publisherdb and category & 4 <> 0 and 
  896.             (isnull(databaseproperty(name, N'issuspect'), 0) = 0 and isnull(databaseproperty(name, N'isshutdown'), 0) = 0) and 
  897.             has_dbaccess(name) = 1
  898.     if @replication_type = @3rdparty
  899.         insert into #pubdbs select name, @3rdparty from master..sysdatabases where 
  900.             name like @publisherdb and category & @distbit <> 0 and 
  901.             (isnull(databaseproperty(name, N'issuspect'), 0) = 0 and isnull(databaseproperty(name, N'isshutdown'), 0) = 0) and 
  902.             has_dbaccess(name) = 1
  903.  
  904.     create table #MSenumpublications 
  905.             (publisher_db sysname NOT NULL, publication sysname NOT NULL, replication_type tinyint NOT NULL, 
  906.             immediate_sync bit NOT NULL, allow_pull bit NOT NULL, allow_anonymous bit NOT NULL, 
  907.             enabled_for_internet bit NOT NULL, repl_freq tinyint NOT NULL, immediate_sync_ready bit NOT NULL, 
  908.             allow_sync_tran bit NOT NULL, independent_agent bit NOT NULL, is_db_owner int NOT NULL, 
  909.             thirdparty_flag bit NOT NULL, vendor_name sysname NULL, publisher sysname NULL, description nvarchar(255) NULL, distribution_db sysname NULL)
  910.  
  911.     declare hCForEachDb CURSOR LOCAL FAST_FORWARD FOR select publisher_db, replication_type from  #pubdbs
  912.     FOR READ ONLY
  913.     open hCForEachDb
  914.     fetch hCForEachDb into @dbname, @replication_type
  915.     /* Loop for each database */
  916.     while (@@fetch_status >= 0) 
  917.     begin
  918.         if (@replication_type) = @trans
  919.             select @proc = quotename(@dbname) + '.dbo.sp_MSenumtranpublications'
  920.         else if (@replication_type) = @merge
  921.             select @proc = quotename(@dbname) + '.dbo.sp_MSenummergepublications'
  922.         else if (@replication_type) = @3rdparty
  923.             select @proc = quotename(@dbname) + '.dbo.sp_MSenum3rdpartypublications'
  924.         insert into #MSenumpublications exec @retcode = @proc
  925.         if @@ERROR <> 0 or @retcode <> 0
  926.             return (1)
  927.         fetch hCForEachDb into @dbname, @replication_type
  928.     end /* while FETCH_SUCCESS */
  929.  
  930.     -- Prepare for filtering.
  931.     create table #admin_publications (publisher_db sysname not null, 
  932.         publication sysname not null)
  933.  
  934.     create table #agent_publications (publisher_db sysname not null,
  935.         publication sysname not null)
  936.  
  937.  
  938.     IF (@security_check <> 0)
  939.     BEGIN
  940.     
  941.         EXEC @retcode = dbo.sp_helpdistributor     @rpcsrvname = @dist_rpcname OUTPUT,
  942.                                                @distribdb   = @distribdb   OUTPUT
  943.  
  944.         IF @@error <> 0 OR @retcode <> 0
  945.             RETURN (1)
  946.  
  947.         IF @distribdb is null
  948.         BEGIN
  949.             RAISERROR (14071, 16, -1)
  950.             RETURN (1)
  951.         END
  952.  
  953.         SELECT @proc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSpublication_access'
  954.  
  955.         -- Optimization
  956.         if is_srvrolemember('sysadmin') = 1
  957.             select @is_user_admin = 1
  958.         else
  959.             insert into #admin_publications EXEC @retcode = @proc
  960.                  @publisher = @@SERVERNAME,
  961.                  @operation = 'get_publications',
  962.                  @login = @login
  963.  
  964.  
  965.         if suser_sid(@agent_login) = suser_sid()
  966.             select @same_as_user = 1
  967.         else
  968.             insert into #agent_publications EXEC @retcode = @proc
  969.                 @publisher = @@SERVERNAME,
  970.                 @operation = 'get_publications',
  971.                 @login = @agent_login
  972.         
  973.     END -- IF (@security_check <> 0) 
  974.  
  975.     -- workaround of a server bug of leaving tran open when
  976.     -- insert into exec failed.
  977.     while(@@trancount <> 0) commit tran
  978.  
  979. DONE2:
  980.  
  981.     select pub.publisher_db, pub.publication, pub.replication_type, 
  982.             pub.immediate_sync, pub.allow_pull, pub.allow_anonymous, 
  983.             pub.enabled_for_internet, pub.repl_freq, pub.immediate_sync_ready, 
  984.             pub.allow_sync_tran, pub.independent_agent, N'agent_access' = case 
  985.                 when 
  986.                     (@same_as_user = 1 or
  987.                     exists (select * from #agent_publications agent where
  988.                     agent.publisher_db = pub.publisher_db and
  989.                     agent.publication = pub.publication))
  990.                     then convert(bit,1)
  991.                 else convert(bit,0)
  992.                 end,
  993.             pub.thirdparty_flag,
  994.             pub.vendor_name, pub.publisher, pub.description, pub.distribution_db
  995.      from #MSenumpublications pub where exists (select * from #admin_publications admin where
  996.         pub.publisher_db = admin.publisher_db and
  997.         pub.publication = admin.publication) or
  998.         @security_check = 0 or
  999.         pub.is_db_owner = 1 or
  1000.         @is_user_admin = 1
  1001.      order by pub.publication, pub.publisher_db
  1002.  
  1003.     return (0)
  1004. go
  1005.  
  1006. grant execute on dbo.sp_MSenumallpublications to public
  1007. go 
  1008.  
  1009. --------------------------------------------------------------------------------
  1010. --. sp_reinitpullsubscription
  1011. --------------------------------------------------------------------------------
  1012. if exists (select * from sysobjects    where type = 'P'
  1013.     and name = 'sp_reinitpullsubscription')
  1014.     drop procedure sp_reinitpullsubscription
  1015. go
  1016.  
  1017. raiserror('Creating procedure sp_reinitpullsubscription', 0,1)
  1018. go
  1019.  
  1020. CREATE PROCEDURE sp_reinitpullsubscription (
  1021.     @publisher sysname,
  1022.     @publisher_db sysname,
  1023.     @publication sysname = 'all'                       /* publication name */
  1024.     )AS
  1025.  
  1026.     SET NOCOUNT ON
  1027.     
  1028.     declare @subscription_type int    
  1029.     declare @sync_type tinyint
  1030.     /*
  1031.     ** Security Check
  1032.     */
  1033.     
  1034.       declare @retcode     int  
  1035.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  1036.     IF @@ERROR <> 0 or @retcode <> 0
  1037.         RETURN(1)
  1038.  
  1039.     /*
  1040.     ** Initializations.
  1041.     */
  1042.    
  1043.     /*
  1044.     ** Parameter Check: @publisher
  1045.     ** Check to make sure that the publisher is define
  1046.     */
  1047.     IF @publisher IS NULL
  1048.     BEGIN
  1049.         RAISERROR (14043, 16, -1, '@publisher')
  1050.         RETURN (1)
  1051.     END
  1052.  
  1053.     IF @publisher = 'all'
  1054.     BEGIN
  1055.         RAISERROR (14136, 16, -1)
  1056.         RETURN (1)
  1057.     END
  1058.  
  1059.     EXECUTE @retcode = dbo.sp_validname @publisher
  1060.  
  1061.     IF @@ERROR <> 0 OR @retcode <> 0
  1062.        RETURN (1)
  1063.     
  1064.  
  1065.     /*
  1066.     ** Parameter Check: @publisher_db
  1067.     */
  1068.  
  1069.     IF @publisher_db IS NULL
  1070.     BEGIN
  1071.         RAISERROR (14043, 16, -1, '@publisher_db')
  1072.         RETURN (1)
  1073.     END
  1074.  
  1075.     IF @publisher_db = 'all'
  1076.     BEGIN
  1077.         RAISERROR (14136, 16, -1)
  1078.         RETURN (1)
  1079.     END
  1080.  
  1081.     EXECUTE @retcode = dbo.sp_validname @publisher_db
  1082.  
  1083.     IF @@ERROR <> 0 OR @retcode <> 0
  1084.        RETURN (1)
  1085.  
  1086.     /*
  1087.     ** Parameter Check: @publication
  1088.     ** 
  1089.     */
  1090.     IF @publication IS NULL
  1091.     BEGIN
  1092.         RAISERROR (14043, 16, -1, '@publication')
  1093.         RETURN (1)
  1094.     END
  1095.  
  1096.     IF LOWER(@publication) = 'all'
  1097.         select @publication = '%'
  1098.     ELSE
  1099.     BEGIN
  1100.         EXECUTE @retcode = dbo.sp_validname @publication
  1101.  
  1102.         IF @@ERROR <> 0 OR @retcode <> 0
  1103.         RETURN (1)
  1104.     END
  1105.         
  1106.     IF NOT EXISTS (SELECT * FROM  MSreplication_subscriptions 
  1107.                 WHERE UPPER(publisher) = UPPER(@publisher) AND
  1108.                       publisher_db  = @publisher_db AND
  1109.                       publication like @publication )
  1110.     BEGIN
  1111.             RAISERROR(14135, 11, -1,  @publisher, @publisher_db, @publication)
  1112.             RETURN(1)
  1113.     END
  1114.         
  1115.     select @sync_type = immediate_sync 
  1116.         from MSreplication_subscriptions
  1117.         WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db  = @publisher_db AND publication like @publication 
  1118.  
  1119.     IF @sync_type = 0
  1120.     BEGIN
  1121.         raiserror(21059, 16, -1)
  1122.         return (1)
  1123.     END
  1124.         
  1125.     UPDATE MSreplication_subscriptions set 
  1126.         transaction_timestamp = 0x00
  1127.         WHERE UPPER(publisher) = UPPER(@publisher) AND
  1128.                       publisher_db  = @publisher_db AND
  1129.                       publication like @publication 
  1130.     if @@ERROR<>0 
  1131.         RETURN (1)
  1132. GO
  1133.  
  1134. grant execute on dbo.sp_reinitpullsubscription to public
  1135. go
  1136.     
  1137. --------------------------------------------------------------------------------
  1138. --. sp_droppullsubscription
  1139. --------------------------------------------------------------------------------
  1140. if exists (select * from sysobjects    where type = 'P'
  1141.     and name = 'sp_droppullsubscription')
  1142.     drop procedure sp_droppullsubscription
  1143. go
  1144.  
  1145. raiserror('Creating procedure sp_droppullsubscription', 0,1)
  1146. go
  1147.  
  1148. CREATE PROCEDURE sp_droppullsubscription (
  1149.     @publisher sysname,
  1150.     @publisher_db sysname,
  1151.     @publication sysname,   /* publication name */
  1152.     @reserved bit = 0
  1153.     ) AS
  1154.  
  1155.     SET NOCOUNT ON
  1156.  
  1157.     /*
  1158.     ** Declarations.
  1159.     */
  1160.  
  1161.  
  1162.     DECLARE @name nvarchar(255)
  1163.     DECLARE @retcode int
  1164.     DECLARE @agent_id binary(16)
  1165.     DECLARE @publisher_ex sysname          /* Expression used in the cursor */
  1166.     DECLARE @publisher_db_ex sysname     /* Expression used in the cursor */
  1167.     DECLARE @publication_ex sysname      /* Expression used in the cursor */
  1168.     DECLARE @expanded bit
  1169.     DECLARE @subscription_type_id int
  1170.     DECLARE @count_sub int
  1171.     DECLARE @drop_null_pub bit
  1172.     DECLARE @drop_push_bit bit
  1173.     DECLARE @push int
  1174.     DECLARE @implicit_transaction int
  1175.     DECLARE @close_cursor_at_commit int
  1176.     DECLARE @owner_sid varbinary(85)
  1177.     DECLARE @owner_name sysname
  1178.     DECLARE @qualified_publication_name nvarchar(512)
  1179.     
  1180.     /* 
  1181.     ** Initialization
  1182.     */
  1183.     SELECT @expanded = 0
  1184.     SELECT @drop_null_pub = 0
  1185.     SELECT @push = 0
  1186.  
  1187.     /*
  1188.     ** Get the original set value off IMPLICIT_TRANSACTIONS and CURSOR_CLOSE_ON_COMMIT
  1189.     **      before set these two to off
  1190.     */
  1191.     select @implicit_transaction = 0
  1192.     select @close_cursor_at_commit = 0
  1193.     IF (@reserved = 0)
  1194.     BEGIN
  1195.         SELECT @implicit_transaction = @@options & 2
  1196.         SELECT @close_cursor_at_commit = @@options & 4
  1197.         SET IMPLICIT_TRANSACTIONS OFF
  1198.         SET CURSOR_CLOSE_ON_COMMIT OFF
  1199.     END
  1200.  
  1201.     /*
  1202.     ** Security Check
  1203.     */
  1204.  
  1205.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  1206.     IF @@ERROR <> 0 or @retcode <> 0
  1207.         RETURN(1)
  1208.  
  1209.     SELECT @drop_push_bit = 0    
  1210.     
  1211.     /*
  1212.     ** Check parameter and set expressions used by cursor
  1213.     */
  1214.     
  1215.     /* Publisher */
  1216.     IF @publisher IS NULL
  1217.     BEGIN
  1218.         RAISERROR (14043, 16, -1, '@publisher')
  1219.         RETURN (1)
  1220.     END
  1221.  
  1222.     IF @publisher = 'all'
  1223.     BEGIN
  1224.         SELECT @publisher_ex = '%'
  1225.         SELECT @expanded = 1
  1226.     END
  1227.     ELSE
  1228.     BEGIN
  1229.         EXECUTE @retcode = dbo.sp_validname @publisher
  1230.         IF @retcode <> 0
  1231.         RETURN (1)
  1232.         SELECT @publisher_ex = @publisher
  1233.     END
  1234.  
  1235.  
  1236.     /* Publisher_db */
  1237.     IF @publisher_db IS NULL
  1238.     BEGIN
  1239.             RAISERROR (14043, 16, -1, '@publisher_db')
  1240.             RETURN (1)
  1241.     END
  1242.  
  1243.     IF @publisher_db = 'all'
  1244.     BEGIN
  1245.         SELECT @publisher_db_ex = '%'
  1246.         select @expanded = 1
  1247.     END
  1248.     ELSE
  1249.     BEGIN
  1250.         /*
  1251.         EXECUTE @retcode = dbo.sp_validname @publisher_db
  1252.         IF @retcode <> 0
  1253.         RETURN (1)
  1254.         */
  1255.         SELECT @publisher_db_ex = @publisher_db
  1256.     END
  1257.  
  1258.     /* 
  1259.     ** Publication
  1260.     ** '' is not a valid name but it may be in the publication name in the table. 
  1261.     */
  1262.     IF @publication IS NULL OR @publication = ''
  1263.     BEGIN
  1264.         SELECT @drop_null_pub = 1
  1265.     END
  1266.     ELSE IF @publication = 'all'
  1267.     BEGIN
  1268.         SELECT @publication_ex = '%'
  1269.         SELECT @expanded = 1
  1270.         SELECT @drop_null_pub = 1
  1271.     END
  1272.     ELSE
  1273.     BEGIN
  1274.         EXECUTE @retcode = dbo.sp_validname @publication
  1275.         IF @retcode <> 0
  1276.         RETURN (1)
  1277.         SELECT @publication_ex = @publication
  1278.     END
  1279.  
  1280.     /*
  1281.     ** Check to see if the  subscription table exists
  1282.     */
  1283.     IF NOT EXISTS (SELECT * FROM sysobjects 
  1284.                 WHERE type = 'U' AND
  1285.                       name = 'MSreplication_subscriptions')
  1286.     BEGIN
  1287.         IF @expanded = 0
  1288.         BEGIN
  1289.             RAISERROR(14135, 11, -1,  @publisher, 
  1290.                 @publisher_db, @publication)
  1291.             RETURN(1)
  1292.         END
  1293.         ELSE
  1294.             RETURN(0)
  1295.     END
  1296.  
  1297.     IF @expanded = 0 
  1298.     BEGIN 
  1299.         /*
  1300.         **
  1301.         ** Check to see if the subscription entry exists
  1302.         */
  1303.         IF  NOT EXISTS (SELECT * FROM  MSreplication_subscriptions 
  1304.                     WHERE UPPER(publisher) = UPPER(@publisher) AND
  1305.                       publisher_db = @publisher_db AND
  1306.                       publication = @publication)     
  1307.         BEGIN
  1308.             RAISERROR(14135, 11, -1, @publisher, @publisher_db, @publication)
  1309.             RETURN(1)
  1310.         END
  1311.  
  1312.         /* 
  1313.         ** Make sure the subscription is not push type if @drop_push_bit = 0
  1314.         */
  1315.         IF @drop_push_bit = 0
  1316.         BEGIN
  1317.             IF EXISTS (SELECT * FROM MSreplication_subscriptions 
  1318.                 WHERE UPPER(publisher) = UPPER(@publisher) AND
  1319.                   publisher_db = @publisher_db AND
  1320.                   publication = @publication AND
  1321.                   subscription_type = @push AND
  1322.                   @drop_push_bit = 0)
  1323.             BEGIN
  1324.                 RAISERROR(20017, 16, -1)
  1325.                 RETURN(1)
  1326.             END
  1327.         END
  1328.  
  1329.     END
  1330.     ELSE
  1331.     /* 
  1332.     ** Open a cursor and call recursively if
  1333.     ** parameters are expanded.
  1334.     */
  1335.     BEGIN
  1336.  
  1337.         /*        
  1338.         **  Note: Any expression check on null value is false
  1339.         ** @subscription_type_id is NULL <==> push
  1340.         ** @subscription_type_id is NOT NULL <==> non push
  1341.         */
  1342.         DECLARE hCdroppullsubscription CURSOR LOCAL FAST_FORWARD FOR
  1343.             SELECT DISTINCT publisher, publisher_db, publication    
  1344.                 FROM MSreplication_subscriptions
  1345.                 WHERE ((@publisher_ex = N'%') OR (UPPER(publisher) = UPPER(@publisher_ex))) AND
  1346.                       publisher_db LIKE @publisher_db_ex AND
  1347.                       (publication LIKE @publication_ex OR
  1348.                       (@drop_null_pub = 1 AND
  1349.                       publication IS NULL)) AND
  1350.                       ((@drop_push_bit =0 AND
  1351.                       subscription_type <> @push) OR
  1352.                       @drop_push_bit = 1)
  1353.         FOR READ ONLY
  1354.         OPEN hCdroppullsubscription
  1355.  
  1356.         FETCH hCdroppullsubscription INTO @publisher, 
  1357.             @publisher_db, @publication
  1358.         WHILE (@@fetch_status <> -1)
  1359.         BEGIN
  1360.             EXECUTE @retcode  = dbo.sp_droppullsubscription @publisher = @publisher, 
  1361.                 @publisher_db = @publisher_db, @publication = @publication, 
  1362.                 @reserved = 1
  1363.  
  1364.             FETCH hCdroppullsubscription INTO @publisher, 
  1365.                 @publisher_db, @publication
  1366.         END
  1367.  
  1368.         CLOSE hCdroppullsubscription
  1369.         DEALLOCATE hCdroppullsubscription
  1370.         RETURN (0)
  1371.     END
  1372.     
  1373.     /*
  1374.     ** Only members of the sysadmin group and the creator of the distribution
  1375.     ** agent can drop a pull subscription successfully. This behavior matches 
  1376.     ** the behavior of the sysjobs_view. DBO of the subscriber database, 
  1377.     ** sysadmins (owner is undefined) can drop a subscription if the owner_sid 
  1378.     ** is null.
  1379.     */
  1380.  
  1381.     EXEC sp_MSget_pullsubsagent_owner @publisher = @publisher,
  1382.                                       @publisher_db = @publisher_db,
  1383.                                       @publication = @publication,
  1384.                                       @owner_sid = @owner_sid OUTPUT
  1385.  
  1386.     IF (@owner_sid is not null AND
  1387.         (SUSER_SID() <> @owner_sid) AND
  1388.         (ISNULL(IS_SRVROLEMEMBER('sysadmin'),0) = 0))
  1389.     BEGIN
  1390.         SELECT @owner_name = SUSER_SNAME(@owner_sid)
  1391.         SELECT @qualified_publication_name = @publisher + N':' + 
  1392.                                              @publisher_db + N':' +
  1393.                                              @publication
  1394.         RAISERROR(21121,16,-1,@owner_name, @qualified_publication_name) 
  1395.         RETURN (1)
  1396.     END
  1397.  
  1398.     /* 
  1399.     ** Get the agent name, it may be dropped later.
  1400.     */
  1401.     SELECT @agent_id = agent_id FROM MSreplication_subscriptions
  1402.                     WHERE UPPER(publisher) = UPPER(@publisher) AND
  1403.                           publisher_db  = @publisher_db AND
  1404.                           publication = @publication 
  1405.  
  1406.     -- If the agent is used by other subscription, don't drop it.
  1407.     if (select count(*) from MSreplication_subscriptions where
  1408.         agent_id = @agent_id) > 1
  1409.         select @agent_id = NULL
  1410.  
  1411.     begin tran
  1412.     save TRAN droppullsubscription
  1413.  
  1414.     /*
  1415.     ** Drop the subscription entry and the distribution agent if it exists 
  1416.     */
  1417.  
  1418.  
  1419.     /* 
  1420.     ** If the distribution agent is not used anymore,
  1421.     ** drop the agent if it exists
  1422.     */
  1423.  
  1424.     IF @agent_id IS NOT NULL
  1425.     BEGIN
  1426.         IF (EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @agent_id))
  1427.         BEGIN
  1428.                 EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @agent_id
  1429.              IF @@ERROR <> 0 or @retcode <> 0
  1430.                 GOTO UNDO
  1431.  
  1432.             -- Delete MSreplication_subsciptions table after dropping 
  1433.             -- the distribution agent and delay one second
  1434.             -- to avoid deadlock with it.
  1435.             WAITFOR DELAY '00:00:01'
  1436.         END
  1437.  
  1438.     END
  1439.  
  1440.     /* Call sp_MSunregistersubscription so that the reg entries get deleted */
  1441.     declare @subscriber_db sysname
  1442.     set @subscriber_db = DB_NAME()
  1443.     exec @retcode = dbo.sp_MSunregistersubscription @publisher = @publisher,
  1444.                                 @publisher_db = @publisher_db,
  1445.                                 @publication = @publication,
  1446.                                 @subscriber = @@SERVERNAME,
  1447.                                 @subscriber_db = @subscriber_db
  1448.  
  1449.     IF @retcode<>0 or @@ERROR<>0
  1450.         GOTO UNDO
  1451.     /*
  1452.     -- Delete MSreplication_subsciptions table after dropping the distribution agent\
  1453.     -- To avoid deadlock with it.
  1454.     --DELETE MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher)    AND
  1455.         --publisher_db  = @publisher_db AND
  1456.         --publication = @publication 
  1457.     
  1458.     --IF @@ERROR <> 0 
  1459.     --    GOTO UNDO
  1460.  
  1461.     */
  1462.  
  1463.     IF EXISTS(select * from sysobjects where type='U' and name = 'MSsubscription_properties')
  1464.     BEGIN
  1465.         DELETE FROM MSsubscription_properties 
  1466.         WHERE UPPER(publisher) = UPPER(@publisher)    AND
  1467.         publisher_db  = @publisher_db AND
  1468.         publication = @publication 
  1469.  
  1470.         IF @@ERROR <> 0 
  1471.             GOTO UNDO
  1472.  
  1473.         IF NOT EXISTS (SELECT * FROM MSsubscription_properties)
  1474.         BEGIN
  1475.             DROP TABLE MSsubscription_properties
  1476.             IF @@ERROR <> 0 
  1477.                 GOTO UNDO
  1478.         END
  1479.     END
  1480.     
  1481.     /*
  1482.     ** Clean up metadata at subscriber side
  1483.     */
  1484.     exec @retcode = dbo.sp_subscription_cleanup @publisher = @publisher,
  1485.                                             @publisher_db  = @publisher_db,
  1486.                                             @publication = @publication
  1487.     IF @retcode<>0 or @@ERROR<>0
  1488.         GOTO UNDO
  1489.  
  1490.     --
  1491.     -- drop table MSreplication_subscriptions if empty and
  1492.     -- not in recursive call
  1493.     --
  1494.     IF (@reserved = 0 AND 
  1495.         NOT EXISTS (SELECT * FROM MSreplication_subscriptions))
  1496.     BEGIN
  1497.         DROP TABLE MSreplication_subscriptions
  1498.         IF @@ERROR <> 0 
  1499.             GOTO UNDO
  1500.     END
  1501.     
  1502.  
  1503.     COMMIT TRAN
  1504.     /*
  1505.     ** set back the two settings if needed 
  1506.     */
  1507.     if @reserved = 0
  1508.     BEGIN
  1509.         IF @implicit_transaction <>0 
  1510.             SET IMPLICIT_TRANSACTIONS ON
  1511.         IF @close_cursor_at_commit <>0 
  1512.             SET CURSOR_CLOSE_ON_COMMIT ON
  1513.     END
  1514.     RETURN (0)
  1515.  
  1516. UNDO:
  1517.     IF @@TRANCOUNT > 0
  1518.     begin
  1519.         ROLLBACK TRAN droppullsubscription
  1520.         COMMIT TRAN   
  1521.     end
  1522.     /*
  1523.     ** set back the two settings if needed
  1524.     */
  1525.     if @reserved = 0
  1526.     BEGIN
  1527.         IF @implicit_transaction <>0 
  1528.             SET IMPLICIT_TRANSACTIONS ON
  1529.         IF @close_cursor_at_commit <>0 
  1530.             SET CURSOR_CLOSE_ON_COMMIT ON
  1531.     END
  1532.  
  1533.     return 1
  1534. go
  1535.  
  1536. grant execute on dbo.sp_droppullsubscription to public
  1537. go
  1538.  
  1539. --------------------------------------------------------------------------------
  1540. --. sp_addmergepullsubscription
  1541. --------------------------------------------------------------------------------
  1542. if exists (select * from sysobjects    where type = 'P'
  1543.     and name = 'sp_addmergepullsubscription')
  1544.     drop procedure sp_addmergepullsubscription
  1545. go
  1546.  
  1547. raiserror('Creating procedure sp_addmergepullsubscription', 0,1)
  1548. GO
  1549.  
  1550. CREATE PROCEDURE sp_addmergepullsubscription (
  1551.     @publication             sysname,                      /* Publication name */
  1552.     @publisher                sysname = @@SERVERNAME,      /* Publisher server */
  1553.     @publisher_db            sysname = NULL,              /* Publication database */
  1554.     @subscriber_type         nvarchar(15) = 'local',            /* Subscriber type */ 
  1555.     @subscription_priority     real         = NULL,                /* Subscription priority */
  1556.     @sync_type                 nvarchar(15) = 'automatic', /* subscription sync type */
  1557.     @description nvarchar(255) = NULL              
  1558.      ) AS
  1559.  
  1560.     SET NOCOUNT ON
  1561.  
  1562.     /*
  1563.     ** Declarations.
  1564.     */
  1565.     declare @retcode                int
  1566.     declare    @subscriber_db            sysname
  1567.     declare @subnickname            int
  1568.     declare @subscriber_srvid        int 
  1569.     declare @publisher_srvid        int 
  1570.     declare @priority                 real
  1571.     declare @subid                     uniqueidentifier
  1572.     declare @subscriber_typeid         smallint
  1573.     declare @subscription_type         smallint
  1574.     declare @command                 nvarchar(255)
  1575.     declare @inactive                tinyint 
  1576.     declare @global                 tinyint        /* subscriber type is global */
  1577.     declare @push                     tinyint        /* subscription type is push */
  1578.      
  1579.     declare @sync_typeid             tinyint
  1580.     declare @nosync                 tinyint        
  1581.     declare @automatic                tinyint             
  1582.     declare @pubid                    uniqueidentifier             
  1583.     declare @partnerid                uniqueidentifier             
  1584.     declare @parentid               uniqueidentifier
  1585.  
  1586.     /*
  1587.     ** Initializations.
  1588.     */
  1589.  
  1590.     SET @nosync             = 2       /* Const: synchronization type 'nosync' */
  1591.     SET @automatic             = 1       /* Const: synchronization type 'automatic' */
  1592.     SET @inactive             = 0
  1593.     SET @global             = 1
  1594.     SET @push                 = 0   
  1595.  
  1596.  
  1597.     set @pubid                 = newid()
  1598.     set @partnerid            = @pubid
  1599.     
  1600.     set @parentid            = '00000000-0000-0000-0000-000000000000'
  1601.      
  1602.     /* 
  1603.     ** Check if replication components are installed on this server
  1604.     */
  1605.     exec @retcode = dbo.sp_MS_replication_installed
  1606.     if (@retcode <> 1)
  1607.     begin
  1608.         return (1)
  1609.     end
  1610.  
  1611.     /*
  1612.     ** Security Check.
  1613.     */
  1614.  
  1615.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  1616.     if @@ERROR <> 0 or @retcode <> 0
  1617.         return(1)
  1618.  
  1619.     /*
  1620.     **    Check to see if merge system tables exist. Create them unless they already
  1621.     **  exist.
  1622.     */
  1623.     IF not exists (select name from sysobjects where name='sysmergesubscriptions')
  1624.         BEGIN
  1625.             execute @retcode = dbo.sp_MScreate_mergesystables
  1626.                 if @@ERROR <> 0 or @retcode <> 0
  1627.                     begin
  1628.                         return (1)
  1629.                     end
  1630.         END    
  1631.  
  1632.     if UPPER(@publisher) = UPPER(@@SERVERNAME) and @publisher_db = db_name()
  1633.         begin
  1634.             raiserror(21126, 16, -1)
  1635.             return (1)
  1636.         end
  1637.  
  1638.     if exists (select pubid from sysmergepublications where UPPER(publisher) = UPPER(@@SERVERNAME) and publisher_db=db_name()) and @subscriber_type in ('local', 'anonymous')
  1639.         begin
  1640.             declare @dbname sysname
  1641.             select @dbname = DB_NAME()
  1642.             raiserror(21127, 16, -1, @dbname)
  1643.             return (1)
  1644.         end
  1645.     /* 
  1646.     ** When adding a pull subscription, if a push subscription for that publication already exists, 
  1647.     ** we will cleanup all the traces of that subscription
  1648.     */
  1649.     IF EXISTS (select name from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db)
  1650.     BEGIN
  1651.         select @pubid=pubid from sysmergepublications 
  1652.             where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  1653.         IF EXISTS (select subid from sysmergesubscriptions where pubid=@pubid and subid<>@pubid and subscription_type=0)
  1654.             begin
  1655.                 exec @retcode = dbo.sp_MSpublicationcleanup @publisher=@publisher,
  1656.                                                         @publisher_db=@publisher_db,
  1657.                                                         @publication=@publication
  1658.                 IF @@ERROR <> 0 or @retcode <>0
  1659.                     BEGIN
  1660.                     RAISERROR (20025, 16, -1, @publication)
  1661.                     return (1)
  1662.                     END    
  1663.             end
  1664.         ELSE
  1665.             begin
  1666.                 IF EXISTS (select status from sysmergesubscriptions where pubid=@pubid and status =    2)
  1667.                     begin
  1668.                         select @subid = subid from sysmergesubscriptions where pubid=@pubid and subid<>pubid
  1669.                         delete sysmergesubscriptions where pubid=@pubid
  1670.                         delete MSmerge_replinfo where repid = @subid
  1671.                     end
  1672.                 ELSE 
  1673.                     begin
  1674.                         RAISERROR (14058, 16, -1)
  1675.                         return (1)
  1676.                     end
  1677.             end
  1678.     END
  1679.     
  1680.     set @partnerid = @pubid
  1681.      
  1682.       /*
  1683.     ** Assign parameter values appropriately for the local server database
  1684.     */
  1685.     set @subscriber_db = DB_NAME()
  1686.     select @subscriber_srvid = 0
  1687.  
  1688.     /*
  1689.     ** Parameter Check: @publisher
  1690.     ** Check to make sure that the publisher is defined
  1691.     */
  1692.     IF @publisher IS NULL
  1693.     BEGIN
  1694.         RAISERROR (14043, 16, -1, '@publisher')
  1695.         RETURN (1)
  1696.     END
  1697.  
  1698.     IF LOWER(@publisher) = 'all'
  1699.     BEGIN
  1700.         RAISERROR (14136, 16, -1)
  1701.         RETURN (1)
  1702.     END
  1703.  
  1704.     EXECUTE @retcode = dbo.sp_validname @publisher
  1705.     IF @@ERROR <> 0 OR @retcode <> 0
  1706.        RETURN (1)
  1707.     /*
  1708.     ** Validate that the publisher is a valid server
  1709.     */
  1710.     select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  1711.     IF @publisher_srvid IS NULL
  1712.         BEGIN
  1713.             EXECUTE @retcode = dbo.sp_addserver @publisher
  1714.             IF @@error <> 0 OR @retcode <> 0
  1715.                 BEGIN
  1716.                     RAISERROR (14010, 16, -1)
  1717.                        RETURN (1)
  1718.                 END
  1719.             ELSE
  1720.                 select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  1721.         END
  1722.  
  1723.  
  1724.     /*
  1725.     ** Parameter Check: @publisher_db
  1726.     */
  1727.     IF @publisher_db IS NULL
  1728.     BEGIN
  1729.         RAISERROR (14043, 16, -1, '@publisher_db')
  1730.         RETURN (1)
  1731.     END
  1732.  
  1733.     IF LOWER(@publisher_db) = 'all'
  1734.     BEGIN
  1735.         RAISERROR (14136, 16, -1)
  1736.         RETURN (1)
  1737.     END
  1738.     
  1739.     /*
  1740.     ** Check to see if the publication name is already used in the subscription 
  1741.     ** database - This is the case where we are resubscribing to the same publication.
  1742.     ** Execute dbo.sp_MSpublicationcleanup to cleanup all all the defunct rows
  1743.     
  1744.     ** if exists (select * from sysmergepublications where name = @publication)
  1745.     ** begin
  1746.     **    exec @retcode = dbo.sp_MSpublicationcleanup 
  1747.     **    IF @@ERROR <> 0 OR @retcode <> 0
  1748.     **        BEGIN
  1749.     **            RAISERROR (20025, 16, -1, @publication)
  1750.     **            RETURN (1)
  1751.     **        END                        
  1752.     ** end
  1753.     */
  1754.  
  1755.     /*
  1756.     ** Parameter Check: @subscriber_type.
  1757.     ** Set subscriber_typeid based on the @subscriber_type specified.
  1758.     **
  1759.     **   subscriber_type     subscriber_type
  1760.     **   =================    ===============
  1761.     **             1             global
  1762.     **             2             local
  1763.     **             3             anonymous
  1764.     **             NO support for republisher for B 3
  1765.     */
  1766.     if LOWER(@subscriber_type) NOT IN ('local', 'global', 'anonymous')
  1767.         BEGIN
  1768.               RAISERROR (20023, 16, -1)
  1769.             RETURN (1)
  1770.         END
  1771.  
  1772.     set @subscription_type = 1 /* pull by default */
  1773.     if LOWER(@subscriber_type) IN ('global')
  1774.         set @subscriber_typeid = 1
  1775.     else if LOWER(@subscriber_type) IN ('local')
  1776.         set @subscriber_typeid = 2
  1777.     else if LOWER(@subscriber_type) IN ('anonymous')       
  1778.         begin
  1779.             /* For anonymous subscribers set subscription type appropriately */
  1780.             set @subscriber_typeid = 3
  1781.             set @subscription_type = 2
  1782.         end            
  1783.  
  1784.     /* 
  1785.     ** Assign priority appropriately - choose 0.99 times the minimum priority
  1786.     ** of the global replicas.
  1787.     */
  1788.     if (@subscription_priority > 100.0 or @subscription_priority < 0.0)
  1789.         set @subscription_priority = NULL        
  1790.     if (@subscription_priority IS NULL)
  1791.         begin
  1792.             select @priority = 0.99 * min(priority) from sysmergesubscriptions where subscriber_type  = 1 /* global/loopback */
  1793.             if (@priority IS NOT NULL)
  1794.                 select @subscription_priority = @priority
  1795.             if (@subscription_priority IS NULL) 
  1796.                 select @subscription_priority = 0.0
  1797.         end
  1798.     /*
  1799.     ** For local and anonymous subscriptions the priority is 0.0
  1800.     */
  1801.     if LOWER(@subscriber_type) IN ('local', 'anonymous')
  1802.         select @subscription_priority = 0.0
  1803.  
  1804.     /*
  1805.      ** If the subscription already exists, don't add it.
  1806.     
  1807.      ** if EXISTS (select db_name, srvid
  1808.      **        FROM sysmergesubscriptions
  1809.     **         WHERE db_name = @subscriber_db
  1810.     **         AND srvid = @subscriber_srvid                           
  1811.     **        AND pubid = @pubid)
  1812.     **    BEGIN
  1813.     **        RAISERROR (14058, 16, -1)
  1814.     **        RETURN (1)
  1815.      **    END
  1816.     */
  1817.  
  1818.    /*
  1819.    ** Parameter Check: @sync_type.
  1820.    ** Set sync_typeid based on the @sync_type specified.
  1821.    **
  1822.    **   sync_typeid     sync_type
  1823.    **   ===========     =========
  1824.    **             1     automatic
  1825.    **             2     nosync
  1826.    */
  1827.  
  1828.  
  1829.    IF LOWER(@sync_type) NOT IN ('automatic', 'none')
  1830.        BEGIN
  1831.            RAISERROR (14052, 16, -1)
  1832.            RETURN (1)
  1833.        END
  1834.  
  1835.  
  1836.    IF LOWER(@sync_type) = 'automatic'
  1837.    BEGIN
  1838.         SET @sync_typeid = @automatic
  1839.    END
  1840.    ELSE
  1841.    BEGIN
  1842.         SET @sync_typeid = @nosync
  1843.    END
  1844.  
  1845.  
  1846.     /*
  1847.     ** UNDONE: Validate that the publisher is of type 'republisher'
  1848.     */
  1849.  
  1850.     begin tran
  1851.     save TRAN addmergepullsubscription
  1852.         
  1853.         /* Generate a guid for the Subscriber ID */
  1854.         set @subid = newid()
  1855.  
  1856.         /* Look for existing nickname from any other subscription */
  1857.         exec dbo.sp_MSgetreplnick NULL, NULL , NULL,  @subnickname out
  1858.         if (@@error <> 0) 
  1859.             begin
  1860.             goto FAILURE
  1861.             end                 
  1862.  
  1863.  
  1864.         /* Generate a new replica nickname from the @subid */
  1865.         if (@subnickname is null)
  1866.             EXECUTE dbo.sp_MSgenreplnickname @subid, @subnickname output
  1867.  
  1868.     
  1869.         /* 
  1870.         ** Check to see if MSsubscription_properties table exists.
  1871.         ** If not, create it.
  1872.         */
  1873.         exec @retcode = dbo.sp_MScreate_sub_tables
  1874.         IF @@ERROR <> 0 or @retcode <> 0
  1875.             goto FAILURE
  1876.  
  1877.         /*
  1878.         ** The subscription doesn't exist, so let's add it to sysmergesubscriptions 
  1879.         */
  1880.         INSERT sysmergesubscriptions (subid, partnerid, datasource_type, srvid, db_name, 
  1881.                 pubid, status, subscriber_type, subscription_type, priority, sync_type, description, login_name)
  1882.                     VALUES (@subid,
  1883.                             @partnerid,
  1884.                             0,
  1885.                             @subscriber_srvid,
  1886.                             @subscriber_db,
  1887.                             @pubid,
  1888.                             @inactive,
  1889.                             @subscriber_typeid,
  1890.                             @subscription_type,     /* for a pull/anon subscription */
  1891.                             @subscription_priority,
  1892.                             @sync_typeid,
  1893.                             @description,
  1894.                             suser_sname(suser_sid()))            
  1895.         if @@ERROR <> 0
  1896.             BEGIN
  1897.                 GOTO FAILURE
  1898.             END
  1899.  
  1900.         /* Add a self-subscribed subscription to represent the publication */
  1901.             
  1902.         insert sysmergepublications(publisher, publisher_db, pubid, name, parentid) 
  1903.             values(@publisher, @publisher_db, @pubid, @publication, @parentid)
  1904.         if @@ERROR <> 0
  1905.             begin
  1906.                 goto FAILURE
  1907.             end
  1908.         insert sysmergesubscriptions(subid, partnerid, datasource_type, srvid, db_name, 
  1909.                 pubid, subscriber_type, subscription_type, status, priority, sync_type, description, login_name)
  1910.             values (@pubid, @pubid, 0, @publisher_srvid, @publisher_db, 
  1911.                 @pubid, @global, @push, @inactive, 100.0, @sync_typeid, @description, suser_sname(suser_sid()))  
  1912.                         
  1913.         if @@ERROR <> 0
  1914.             begin
  1915.                 goto FAILURE
  1916.             end
  1917.                     
  1918.         /*
  1919.         **  Add row for subscription in MSmerge_replinfo.
  1920.         */
  1921.         insert MSmerge_replinfo(repid, replnickname)
  1922.                 values (@subid, @subnickname)
  1923.         if @@ERROR <> 0
  1924.             BEGIN
  1925.                 GOTO FAILURE
  1926.             END
  1927.  
  1928.     COMMIT TRAN
  1929.     return (0)
  1930.  
  1931. FAILURE:
  1932.     RAISERROR (14057, 16, -1)
  1933.     if @@trancount > 0
  1934.     begin
  1935.         ROLLBACK TRANSACTION addmergepullsubscription
  1936.         COMMIT TRANSACTION
  1937.     end
  1938.     RETURN (1)
  1939.  
  1940. go
  1941.  
  1942. grant execute on dbo.sp_addmergepullsubscription to public
  1943. go
  1944.  
  1945. --------------------------------------------------------------------------------
  1946. --. sp_helpmergepullsubscription
  1947. --------------------------------------------------------------------------------
  1948. if exists (select * from sysobjects    where type = 'P'
  1949.     and name = 'sp_helpmergepullsubscription')
  1950.     drop procedure sp_helpmergepullsubscription
  1951. go
  1952.  
  1953. raiserror('Creating procedure sp_helpmergepullsubscription', 0,1)
  1954. GO
  1955.  
  1956. CREATE PROCEDURE sp_helpmergepullsubscription(
  1957.     @publication         sysname = '%',        /* Publication name */
  1958.     @publisher            sysname = '%',      /* Publisher server */
  1959.     @publisher_db        sysname = '%',      /* Publication database */
  1960.     @subscription_type    nvarchar(10) = 'pull'    /* Show only pull subscriptions */
  1961.     )AS
  1962.     
  1963.     SET NOCOUNT ON
  1964.  
  1965.     /*
  1966.     ** Declarations.
  1967.     */
  1968.  
  1969.     declare @retcode             int
  1970.     declare @srvid                 int
  1971.     declare    @pubid                 uniqueidentifier
  1972.     declare    @subid                 uniqueidentifier
  1973.     declare    @partnerid             uniqueidentifier
  1974.     declare @cursor_open        int
  1975.     declare @subscriber            sysname
  1976.     declare @subscriber_db        sysname
  1977.     declare @subscription_set     nvarchar(10)
  1978.     declare @publisher_local    sysname
  1979.     declare @publisher_db_local    sysname
  1980.     declare @publication_local    sysname
  1981.     declare @subscription_name     nvarchar(1000)
  1982.     declare @regkey                nvarchar(1000)
  1983.     declare @time                smalldatetime
  1984.     declare @syncmgr_keyexist                int
  1985.     declare @helpsubscriptioncursor_open    int
  1986.     
  1987.  
  1988.     /*
  1989.     ** Initializations.
  1990.     */
  1991.     set @cursor_open             = 0                    
  1992.  
  1993.     select @publisher_db = RTRIM(@publisher_db)
  1994.     select @publication = RTRIM(@publication)
  1995.     
  1996.     /*
  1997.     **    Calling sp_help* is all right whether current database is enabled for pub/sub or not
  1998.     */
  1999.  
  2000.     IF not exists (select * from sysobjects where name='sysmergesubscriptions')
  2001.         RETURN (0)
  2002.  
  2003.     /* Security check */
  2004.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  2005.     if @@ERROR <> 0 or @retcode <> 0
  2006.         return(1)
  2007.  
  2008.     set @subscriber = @@SERVERNAME     
  2009.     set @subscriber_db = DB_NAME()
  2010.  
  2011.     /*
  2012.     ** Parameter Check: @publisher
  2013.     ** Check to make sure that the publisher is defined
  2014.     */
  2015.     IF @publisher <> '%' AND @publisher IS NOT NULL
  2016.     BEGIN
  2017.         EXECUTE @retcode = dbo.sp_validname @publisher
  2018.  
  2019.         IF @@ERROR <> 0 OR @retcode <> 0
  2020.                RETURN (1)
  2021.     END
  2022.  
  2023.     /*
  2024.     ** Parameter Check:  @publication.
  2025.     ** If the publication name is specified, check to make sure that it
  2026.     ** conforms to the rules for identifiers and that the publication
  2027.     ** actually exists.  Disallow NULL.
  2028.     */
  2029.     if @publication IS NULL
  2030.         BEGIN
  2031.             RAISERROR (14043, 16, -1, '@publication')
  2032.             RETURN (1)
  2033.         END
  2034.  
  2035.     /*
  2036.     ** Parameter Check: @subscription_type.
  2037.     ** Set subscription_typeid based on the @subscription_type specified.
  2038.     **
  2039.     **   subscription_type    subscription_type
  2040.     **   =================    ===============
  2041.     **             0             push
  2042.     **             1             pull
  2043.     **              0,1            both
  2044.     */
  2045.     if LOWER(@subscription_type) NOT IN ('push', 'pull', 'both')
  2046.         BEGIN
  2047.               RAISERROR (14128, 16, -1)
  2048.             RETURN (1)
  2049.         END
  2050.     IF LOWER(@subscription_type) = 'both'
  2051.         set @subscription_set = '(0, 1)'
  2052.     else IF LOWER(@subscription_type) = 'push'
  2053.         set @subscription_set = '(0)'
  2054.     else 
  2055.         set @subscription_set = '(1,2)'   -- including pull subscription and pull/anonymous subscription
  2056.  
  2057.     /*
  2058.     ** Get subscriptions
  2059.     */
  2060.     
  2061.     create table #helpmergepullsubscription
  2062.                 (
  2063.                     publication                sysname        NOT NULL,
  2064.                     publisher                sysname        NOT NULL,
  2065.                     publisher_db            sysname        NOT NULL,
  2066.                     subscriber                sysname        NOT NULL,
  2067.                     subscriber_db             sysname        NOT NULL,
  2068.                     status                    int         NOT NULL,
  2069.                     subscriber_type         int            NOT NULL,
  2070.                     subscription_type         int            NOT NULL,
  2071.                     priority                float(8)    NOT NULL,
  2072.                     sync_type                tinyint        NOT NULL,
  2073.                     description                nvarchar(255) NULL,
  2074.                     merge_jobid                binary(16)    NULL,
  2075.                     enabled_for_syncmgr        int            NULL,
  2076.                     last_updated            nvarchar(40) NULL
  2077.                 )
  2078.  
  2079.     IF @publisher IS NULL and @publisher_db IS NULL
  2080.         BEGIN
  2081.             select @subid = subid from sysmergesubscriptions where subid = partnerid
  2082.             set @partnerid = @subid
  2083.             -- show the loopback subscription
  2084.             insert into #helpmergepullsubscription 
  2085.                 select pubs.name, servers2.srvname, subs2.db_name, servers1.srvname, subs1.db_name, 
  2086.                     subs1.status, subs1.subscriber_type, subs1.subscription_type, subs1.priority, 
  2087.                     subs1.sync_type, subs1.description, replinfo.merge_jobid, 0, NULL
  2088.                 FROM      sysmergesubscriptions     subs1,
  2089.                           sysmergesubscriptions     subs2,
  2090.                           MSmerge_replinfo         replinfo,
  2091.                         master..sysservers         servers1,
  2092.                         master..sysservers         servers2,
  2093.                         sysmergepublications     pubs
  2094.                 where subs1.subid = @subid
  2095.                     and subs2.subid = @partnerid
  2096.                     and pubs.pubid = subs1.pubid
  2097.                     and servers1.srvid = subs1.srvid
  2098.                     and servers2.srvid = subs2.srvid
  2099.                     and subs1.subid = subs1.partnerid 
  2100.                     and replinfo.repid = subs1.subid 
  2101.             
  2102.         END
  2103.     else
  2104.         begin
  2105.             declare #cursor cursor local FAST_FORWARD FOR select DISTINCT sub.subid, sub.partnerid 
  2106.                 FROM sysmergesubscriptions     sub,
  2107.                 sysmergesubscriptions         sub1, 
  2108.                 master..sysservers             ss,  
  2109.                 master..sysservers             ss1, 
  2110.                 sysmergepublications         pub 
  2111.                  WHERE ((@subscriber = N'%') OR (UPPER(ss.srvname) = UPPER(@subscriber))) 
  2112.                     AND ((@publisher = N'%') OR (UPPER(ss1.srvname) = UPPER(@publisher))) 
  2113.                     AND sub1.srvid = ss1.srvid 
  2114.                        AND sub.srvid = ss.srvid  
  2115.                        AND pub.name LIKE  @publication  
  2116.                        AND sub.pubid = pub.pubid 
  2117.                        AND sub.db_name LIKE  @subscriber_db 
  2118.                        AND sub1.db_name LIKE @publisher_db 
  2119.                     AND sub1.pubid = pub.pubid 
  2120.                     AND (sub.subscription_type=1 or sub.subscription_type=2) 
  2121.                 FOR READ ONLY
  2122.  
  2123.             open #cursor
  2124.             select @cursor_open = 1                    
  2125.             fetch next from #cursor into @subid, @partnerid
  2126.             while (@@fetch_status <> -1)
  2127.                 begin
  2128.                     insert into #helpmergepullsubscription 
  2129.                         select pubs.name, servers2.srvname, subs2.db_name, servers1.srvname, subs1.db_name, 
  2130.                             subs1.status, subs1.subscriber_type, subs1.subscription_type, subs1.priority, 
  2131.                             subs1.sync_type, subs1.description, replinfo.merge_jobid, 0, NULL
  2132.                         FROM      sysmergesubscriptions     subs1,
  2133.                                   sysmergesubscriptions     subs2,
  2134.                                   MSmerge_replinfo         replinfo,
  2135.                                 master..sysservers         servers1,
  2136.                                 master..sysservers         servers2,
  2137.                                 sysmergepublications     pubs
  2138.                         where subs1.subid = @subid
  2139.                             and subs2.subid = @partnerid
  2140.                             and pubs.pubid = subs1.pubid
  2141.                             and servers1.srvid = subs1.srvid
  2142.                             and servers2.srvid = subs2.srvid
  2143.                             and @subid <> @partnerid -- do not show the loopback subscription
  2144.                             and replinfo.repid = subs1.subid 
  2145.         
  2146.                     if @@ERROR <> 0
  2147.                         begin
  2148.                             set @retcode = 1
  2149.                             goto DONE
  2150.                         end                    
  2151.                 fetch next from #cursor into @subid, @partnerid
  2152.             end
  2153.         end
  2154.  
  2155.     declare #helpsubscriptioncursor CURSOR LOCAL FAST_FORWARD FOR 
  2156.         select DISTINCT publisher, publisher_db, publication
  2157.            FROM #helpmergepullsubscription
  2158.             FOR READ ONLY
  2159.     create table #syncmgr_keyexist (syncmgr_keyexist int)
  2160.     open #helpsubscriptioncursor
  2161.     select @helpsubscriptioncursor_open = 1                    
  2162.     fetch next from #helpsubscriptioncursor into @publisher_local, @publisher_db_local, @publication_local
  2163.     while (@@fetch_status <> -1)
  2164.         begin
  2165.             set @subscription_name = @publisher_local + ':' + @publisher_db_local + ':' + @publication_local + ':' + @subscriber + ':' + @subscriber_db
  2166.             /* Replace back slash with forward slash so that the key name is a valid REGISTRY key name */
  2167.             set @subscription_name = REPLACE(@subscription_name,'\','/')
  2168.             set @regkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\' + @subscription_name
  2169.             insert into #syncmgr_keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @regkey
  2170.             select @syncmgr_keyexist = syncmgr_keyexist from #syncmgr_keyexist
  2171.             update #helpmergepullsubscription set enabled_for_syncmgr = @syncmgr_keyexist 
  2172.                 where UPPER(publisher) = UPPER(@publisher_local)
  2173.                     and publisher_db = @publisher_db_local
  2174.                     and publication = @publication_local
  2175.             select @pubid = pubid from sysmergepublications where name=@publication_local
  2176.                                                             and UPPER(publisher) = UPPER(@publisher_local)
  2177.                                                             and publisher_db = @publisher_db_local
  2178.             select @time=max(coldate) from MSmerge_genhistory 
  2179.                 where art_nick in (select nickname from sysmergearticles where pubid=@pubid)
  2180.             update #helpmergepullsubscription set last_updated = convert(nvarchar(12), @time, 112) + substring(convert(nvarchar(24), @time, 121), 11,13) 
  2181.                 where UPPER(publisher) = UPPER(@publisher_local)
  2182.                     and publisher_db = @publisher_db_local
  2183.                     and publication = @publication_local 
  2184.             fetch next from #helpsubscriptioncursor into @publisher_local, @publisher_db_local, @publication_local
  2185.         end
  2186.  
  2187.     select 'subscription_name'= publisher + ':' + publisher_db + ':' + publication, *
  2188.                 from #helpmergepullsubscription 
  2189.             order by publisher, publisher_db, publication, subscriber, subscriber_db
  2190.          
  2191.     select @retcode = 0
  2192. DONE:
  2193.     if (@cursor_open = 1)
  2194.         begin
  2195.             close #cursor
  2196.             deallocate #cursor
  2197.         end            
  2198.     drop table #helpmergepullsubscription
  2199.  
  2200.     if (@helpsubscriptioncursor_open = 1)
  2201.         begin
  2202.             close #helpsubscriptioncursor
  2203.             deallocate #helpsubscriptioncursor
  2204.         end            
  2205.     drop table #syncmgr_keyexist    
  2206.     return @retcode    
  2207. go
  2208.  
  2209. grant execute on dbo.sp_helpmergepullsubscription to public
  2210. go
  2211.  
  2212. --------------------------------------------------------------------------------
  2213. --. sp_dropmergepullsubscription
  2214. --------------------------------------------------------------------------------
  2215. if exists (select * from sysobjects    where type = 'P'
  2216.     and name = 'sp_dropmergepullsubscription')
  2217.     drop procedure sp_dropmergepullsubscription
  2218. go
  2219.  
  2220. raiserror('Creating procedure sp_dropmergepullsubscription', 0,1)
  2221. GO
  2222. CREATE PROCEDURE sp_dropmergepullsubscription(
  2223.     @publication         sysname = NULL,                  /* Publication name */
  2224.     @publisher            sysname = NULL,              /* Publisher server */
  2225.     @publisher_db        sysname = NULL,              /* Publication database */
  2226.     @reserved            bit = 0
  2227.     )AS
  2228.  
  2229.     SET NOCOUNT ON
  2230.  
  2231.     /*
  2232.     ** Declarations.
  2233.     */
  2234.  
  2235.     declare @retcode                 int
  2236.     declare @subscriber_srvid         int
  2237.     declare @publisher_srvid         int
  2238.     declare    @pubid                     uniqueidentifier
  2239.     declare    @subid                     uniqueidentifier
  2240.     declare    @partnerid                 uniqueidentifier 
  2241.     declare @local_server            sysname
  2242.     declare @local_db                sysname
  2243.     declare @merge_jobid             binary(16)
  2244.     declare @cmd                     nvarchar(255)
  2245.     declare @pubidstr                nvarchar(38)
  2246.     declare @subscriber                sysname
  2247.     declare @subscriber_db            sysname
  2248.     declare @subscriber_type        int
  2249.     declare @local_job                 bit
  2250.     declare @implicit_transaction    int
  2251.     declare @close_cursor_at_commit int
  2252.     declare @owner_sid              varbinary(85)
  2253.     declare @owner_name             sysname
  2254.     declare @qualified_publication_name nvarchar(512)
  2255.  
  2256.  
  2257.     select @close_cursor_at_commit = 0
  2258.     select @implicit_transaction = 0
  2259.  
  2260.     /*
  2261.     ** Get original setting values before setting them to false for recursive calling
  2262.     */
  2263.     IF (@reserved = 0)
  2264.     BEGIN
  2265.         SELECT @implicit_transaction = @@options & 2
  2266.         SELECT @close_cursor_at_commit = @@options & 4
  2267.         SET IMPLICIT_TRANSACTIONS OFF
  2268.         SET CURSOR_CLOSE_ON_COMMIT OFF
  2269.     END
  2270.  
  2271.     /* 
  2272.     ** Security Check.
  2273.     */
  2274.     exec @retcode = dbo.sp_MSreplcheck_subscribe
  2275.     if @@ERROR <> 0 or @retcode <> 0
  2276.         return(1)
  2277.  
  2278.      /*
  2279.     ** Initializations.
  2280.     */                
  2281.     set @local_db = DB_NAME()
  2282.     set @local_server = @@SERVERNAME
  2283.     set @subscriber = @@SERVERNAME     
  2284.     set @subscriber_db = DB_NAME()
  2285.  
  2286.    /*
  2287.     ** Assign parameter values appropriately
  2288.     */
  2289.             
  2290.     select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  2291.     IF @subscriber_srvid IS NULL
  2292.         BEGIN
  2293.            RAISERROR (14010, 16, -1)
  2294.            RETURN (1)     
  2295.         END
  2296.         
  2297.     IF not exists (select name from sysobjects where name='sysmergesubscriptions')
  2298.         BEGIN
  2299.             RAISERROR (14055, 16, -1)
  2300.             RETURN (1)
  2301.         END        
  2302.  
  2303.     /*
  2304.     ** Parameter Check: @publisher
  2305.     ** Check to make sure that the publisher is defined
  2306.     */
  2307.             IF @publisher IS NULL
  2308.             BEGIN
  2309.                 RAISERROR (14043, 16, -1, '@publisher')
  2310.                 RETURN (1)
  2311.             END
  2312.  
  2313.             EXECUTE @retcode = dbo.sp_validname @publisher
  2314.             IF @@ERROR <> 0 OR @retcode <> 0
  2315.                RETURN (1)
  2316.  
  2317.     /*
  2318.     ** Parameter Check: @publisher_db
  2319.     */
  2320.             IF @publisher_db IS NULL
  2321.             BEGIN
  2322.                 RAISERROR (14043, 16, -1, '@publisher_db')
  2323.                 RETURN (1)
  2324.             END    
  2325.  
  2326.     /*
  2327.     ** Parameter Check:  @publication.
  2328.     ** If the publication name is specified, check to make sure that it
  2329.     ** conforms to the rules for identifiers and that the publication
  2330.     ** actually exists.  Disallow NULL.
  2331.     */
  2332.     if @publication IS NULL
  2333.         BEGIN
  2334.             RAISERROR (14043, 16, -1, '@publication')
  2335.             RETURN (1)
  2336.         END
  2337.  
  2338.     IF LOWER(@publication) = 'all'
  2339.         BEGIN
  2340.             declare hC1 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT name FROM sysmergepublications FOR READ ONLY
  2341.             
  2342.             OPEN hC1
  2343.             FETCH hC1 INTO @publication
  2344.             if @@fetch_status = -1 
  2345.                 begin
  2346.                     CLOSE hC1
  2347.                     DEALLOCATE hC1
  2348.                     RETURN (0) --- It's OK to have no publication when 'ALL'
  2349.                 end
  2350.             WHILE (@@fetch_status <> -1)
  2351.                 BEGIN
  2352.                     EXECUTE dbo.sp_dropmergepullsubscription @publication = @publication,
  2353.                                       @publisher = @publisher,
  2354.                                       @publisher_db = @publisher_db,
  2355.                                       @reserved = 1
  2356.                     FETCH hC1 INTO @publication
  2357.                 END
  2358.             CLOSE hC1
  2359.             DEALLOCATE hC1
  2360.             RETURN (0)
  2361.         END
  2362.         
  2363.     IF LOWER(@publisher) = 'all'
  2364.         BEGIN
  2365.             declare hC4 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT srvname FROM master..sysservers FOR READ ONLY
  2366.             
  2367.             OPEN hC4
  2368.             FETCH hC4 INTO @publisher
  2369.             WHILE (@@fetch_status <> -1)
  2370.                 BEGIN
  2371.                     EXECUTE dbo.sp_dropmergepullsubscription @publication = @publication,
  2372.                                                 @publisher = @publisher,
  2373.                                                 @publisher_db = @publisher_db,
  2374.                                                 @reserved = 1
  2375.                     FETCH hC4 INTO @publisher
  2376.                 END
  2377.             CLOSE hC4
  2378.             DEALLOCATE hC4
  2379.             RETURN (0)
  2380.         END
  2381.  
  2382.     /*
  2383.     ** Validate that the publisher is a valid server
  2384.     */
  2385.     select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  2386.     IF @publisher_srvid IS NULL
  2387.         BEGIN
  2388.             --RAISERROR (14010, 16, -1)
  2389.                RETURN (1)
  2390.         END
  2391.  
  2392.  
  2393.     /* Previously the condition is set as 'AND subid<>pubid' which is fatally errorous */
  2394.  
  2395.     IF LOWER(@publisher_db) = 'all'
  2396.         BEGIN
  2397.             declare hC5 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT db_name FROM sysmergesubscriptions 
  2398.                     WHERE subid = pubid and pubid in (select pubid from sysmergepublications 
  2399.                             where UPPER(publisher)=UPPER(@publisher) 
  2400.                                 and name=@publication)
  2401.                                 
  2402.                         FOR READ ONLY
  2403.             
  2404.             OPEN hC5
  2405.             FETCH hC5 INTO @publisher_db
  2406.             WHILE (@@fetch_status <> -1)
  2407.                 BEGIN
  2408.                     EXECUTE dbo.sp_dropmergepullsubscription @publication = @publication,
  2409.                                       @publisher = @publisher,
  2410.                                       @publisher_db = @publisher_db,
  2411.                                       @reserved = 1
  2412.                     FETCH hC5 INTO @publisher_db
  2413.                 END
  2414.             CLOSE hC5
  2415.             DEALLOCATE hC5
  2416.             RETURN (0)
  2417.         END
  2418.  
  2419.     /*
  2420.     ** return error if only there is no 'ALL'. Same is true for the rest of error handling.
  2421.     */
  2422.     if NOT EXISTS (select * FROM sysmergepublications 
  2423.     WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db) 
  2424.     BEGIN
  2425.         if @reserved = 0
  2426.             RAISERROR (20026, 16, -1, @publication)
  2427.         RETURN (1)
  2428.     END
  2429.         
  2430.     select @pubid = pubid from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  2431.     set @pubidstr = '''' + convert(nchar(36), @pubid) + ''''
  2432.     if @pubid is null  
  2433.         BEGIN
  2434.             if @reserved = 0
  2435.                 RAISERROR (20026, 16, -1, @publication)
  2436.                RETURN (1)
  2437.         END
  2438.  
  2439.     /*
  2440.     ** Only members of the sysadmin group and the creator of the distribution
  2441.     ** agent can drop a pull subscription successfully. This behavior matches 
  2442.     ** the behavior of the sysjobs_view. DBO of the subscriber database, 
  2443.     ** sysadmins (owner is undefined) can drop a subscription if the owner_sid 
  2444.     ** is null.
  2445.     */
  2446.     
  2447.     EXEC sp_MSget_mergepullsubsagent_owner @publisher = @publisher,
  2448.                                            @publisher_db = @publisher_db,
  2449.                                            @publication = @publication,
  2450.                                            @owner_sid = @owner_sid OUTPUT 
  2451.     
  2452.     IF (@owner_sid is not null AND
  2453.         (SUSER_SID() <> @owner_sid) AND
  2454.         (ISNULL(IS_SRVROLEMEMBER('sysadmin'),0) = 0))
  2455.     BEGIN
  2456.         SELECT @owner_name = SUSER_SNAME(@owner_sid)
  2457.         SELECT @qualified_publication_name = @publisher + N':' + 
  2458.                                              @publisher_db + N':' +
  2459.                                              @publication
  2460.         RAISERROR(21121,16,-1,@owner_name, @qualified_publication_name) 
  2461.         RETURN (1)
  2462.     END
  2463.  
  2464.     /*
  2465.     ** Get subscriptions from either local replicas or global replicas
  2466.     */
  2467.     select @subid = subs1.subid, @subscriber_type = subs1.subscriber_type, @partnerid = subs2.subid from
  2468.         sysmergesubscriptions     subs1,
  2469.           sysmergesubscriptions     subs2,
  2470.         sysmergepublications         pubs
  2471.         where subs1.srvid = @subscriber_srvid
  2472.             and subs1.db_name = @subscriber_db
  2473.             and subs2.srvid = @publisher_srvid
  2474.             and subs2.db_name = @publisher_db
  2475.             and subs1.pubid = subs2.subid
  2476.             and subs2.pubid = pubs.pubid
  2477.             and pubs.name = @publication
  2478.             and UPPER(pubs.publisher)=UPPER(@publisher)
  2479.             and pubs.publisher_db=@publisher_db
  2480.  
  2481.     if @subid IS NULL 
  2482.          begin
  2483.             if @reserved = 0 
  2484.                 raiserror (14050, 16, -1)
  2485.              RETURN (0)
  2486.         end                 
  2487.  
  2488.     begin tran
  2489.     save TRAN dropmergepullsubscription
  2490.     
  2491.         /*     
  2492.         ** Drop the local merge task
  2493.         */
  2494.         select @merge_jobid = merge_jobid from MSmerge_replinfo WHERE repid = @subid
  2495.         if (@merge_jobid IS NOT NULL)
  2496.         BEGIN
  2497.             IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @merge_jobid)
  2498.             BEGIN
  2499.                 EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @merge_jobid
  2500.                 IF @@ERROR <> 0 or @retcode <> 0
  2501.                     GOTO FAILURE
  2502.             END
  2503.         END                                    
  2504.  
  2505.         if @subid <> @partnerid
  2506.         BEGIN
  2507.             DELETE MSmerge_replinfo WHERE repid = @subid 
  2508.             IF @@ERROR <> 0
  2509.                 GOTO FAILURE
  2510.             delete from sysmergesubscriptions where subid = @subid
  2511.             if @@ERROR <> 0
  2512.                 GOTO FAILURE
  2513.  
  2514.             /* Call sp_MSunregistersubscription so that the reg entries get deleted */
  2515.             exec @retcode = dbo.sp_MSunregistersubscription @publisher = @publisher,
  2516.                                         @publisher_db = @publisher_db,
  2517.                                         @publication = @publication,
  2518.                                         @subscriber = @@SERVERNAME,
  2519.                                         @subscriber_db = @subscriber_db
  2520.             IF @retcode<>0 or @@ERROR<>0
  2521.                 GOTO FAILURE
  2522.  
  2523.             exec dbo.sp_MSpublicationcleanup @publisher=@publisher, 
  2524.                                             @publisher_db = @publisher_db,
  2525.                                             @publication = @publication
  2526.             IF @@ERROR <> 0 
  2527.                 BEGIN
  2528.                     RAISERROR (20025, 16, -1, @publication)
  2529.                     GOTO FAILURE
  2530.                 END
  2531.         END
  2532.         
  2533.         IF EXISTS(select * from sysobjects where type='U' and name = 'MSsubscription_properties')
  2534.         BEGIN
  2535.             DELETE FROM MSsubscription_properties 
  2536.             WHERE UPPER(publisher) = UPPER(@publisher)    AND
  2537.             publisher_db  = @publisher_db AND
  2538.             publication = @publication 
  2539.     
  2540.             IF @@ERROR <> 0 
  2541.                 GOTO FAILURE
  2542.     
  2543.             IF NOT EXISTS (SELECT * FROM MSsubscription_properties)
  2544.             BEGIN
  2545.                 DROP TABLE MSsubscription_properties
  2546.                 IF @@ERROR <> 0 
  2547.                     GOTO FAILURE
  2548.             END
  2549.         END
  2550.  
  2551.         /* 
  2552.         ** If last subscription is dropped and the DB is not enabled for publishing,
  2553.         ** then remove the merge system tables
  2554.         */
  2555.         IF (not exists (select * from sysmergesubscriptions )) 
  2556.             AND (select category & 4 FROM master..sysdatabases WHERE name = DB_NAME())=0
  2557.         BEGIN
  2558.                 execute @retcode = dbo.sp_MSdrop_mergesystables
  2559.                 if @@ERROR <> 0 or @retcode <> 0
  2560.                     begin
  2561.                         return (1)
  2562.                     end
  2563.         END    
  2564.     COMMIT TRAN
  2565.     /*
  2566.     ** Set back original settings
  2567.     */
  2568.     IF @reserved = 0
  2569.     BEGIN
  2570.         IF @implicit_transaction <>0 
  2571.             SET IMPLICIT_TRANSACTIONS ON
  2572.         IF @close_cursor_at_commit <>0 
  2573.             SET CURSOR_CLOSE_ON_COMMIT ON
  2574.     END
  2575.  
  2576.     RETURN(0)        
  2577.  
  2578. FAILURE:
  2579.     RAISERROR (14056, 16, -1)
  2580.     if @@trancount > 0
  2581.     begin
  2582.         ROLLBACK TRANSACTION dropmergepullsubscription
  2583.         COMMIT TRANSACTION
  2584.     end
  2585.     /*
  2586.     ** Set back original settings
  2587.     */    
  2588.     IF @reserved = 0
  2589.     BEGIN
  2590.         IF @implicit_transaction <>0 
  2591.             SET IMPLICIT_TRANSACTIONS ON
  2592.         IF @close_cursor_at_commit <>0 
  2593.             SET CURSOR_CLOSE_ON_COMMIT ON
  2594.     END
  2595.     return 1
  2596. go
  2597.  
  2598. grant execute on dbo.sp_dropmergepullsubscription to public
  2599. go
  2600.  
  2601. --------------------------------------------------------------------------------
  2602. --. sp_MSreplraiserror
  2603. --------------------------------------------------------------------------------
  2604. if exists (select * from sysobjects    where type = 'P'
  2605.     and name = 'sp_MSreplraiserror')
  2606.     drop procedure sp_MSreplraiserror
  2607. go
  2608.  
  2609. raiserror('Creating procedure sp_MSreplraiserror', 0,1)
  2610. go
  2611.  
  2612. create proc sp_MSreplraiserror @errorid int, @param1 sysname = null, @param2 sysname= null
  2613. as
  2614.     if @errorid = 20508 raiserror (20508, 16, 1)
  2615.     else if @errorid = 20509 raiserror (20509, 16, 1)
  2616.     else if @errorid = 20510 raiserror (20510, 16, 1)
  2617.     else if @errorid = 20511 raiserror (20511, 16, 1)
  2618.     else if @errorid = 20512 raiserror (20512, 16, 1)
  2619.     else if @errorid = 20515 raiserror (20515, 16, 1)
  2620.     else if @errorid = 20516 raiserror (20516, 16, 1)
  2621.     else if @errorid = 20517 raiserror (20517, 16, 1)
  2622.     else if @errorid = 20518 raiserror (20518, 16, 1)
  2623.     else if @errorid = 20519 raiserror (20519, 16, 1)
  2624.     else if @errorid = 20520 raiserror (20520, 16, 1)
  2625.     else if @errorid = 21034 raiserror (21034, 16, 1)
  2626.     else if @errorid = 21054 raiserror (21054, 16, 1)
  2627.     else if @errorid = 21161 raiserror (21161, 16, 1)
  2628. go
  2629.  
  2630. grant exec on dbo.sp_MSreplraiserror to public
  2631. go
  2632.  
  2633. --------------------------------------------------------------------------------
  2634. --. sp_MSget_col_position
  2635. --------------------------------------------------------------------------------
  2636. if exists (select * from sysobjects    where type = 'P'
  2637.     and name = 'sp_MSget_col_position')
  2638.     drop procedure sp_MSget_col_position
  2639. go
  2640.  
  2641. raiserror('Creating procedure sp_MSget_col_position', 0,1)
  2642. go
  2643. create procedure sp_MSget_col_position 
  2644.     @objid int,
  2645.     @columns binary(32),
  2646.     @key     sysname, 
  2647.     @colpos  sysname output,
  2648.     @art_col int = NULL output,
  2649.     @get_num_col bit = 0,
  2650.     @num_col  int = NULL output,
  2651.     @this_col int = null output
  2652. as
  2653.   
  2654.     declare @colname      sysname
  2655.     declare @ccoltype     sysname
  2656.     declare @src_cols     int
  2657.     declare @rc           int
  2658.     
  2659.     select @src_cols = count(*) from syscolumns where id = @objid
  2660.     select @this_col = 1
  2661.  
  2662.     select @num_col = 0
  2663.  
  2664.     
  2665.     while @this_col <= @src_cols 
  2666.     begin
  2667.         exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, @columns, 1, @colname output, @ccoltype output
  2668.         if @rc = 0
  2669.         begin
  2670.             set @num_col = @num_col + 1
  2671.             -- If @get_num_col is 1, we just need the number of columns in the partition.
  2672.             if @get_num_col = 0 and @colname = @key
  2673.             begin
  2674.                 select @colpos = 'c' + convert(varchar(4), @this_col)
  2675.                 set @art_col = @num_col
  2676.                 break
  2677.             end
  2678.         end
  2679.         set @this_col = @this_col + 1
  2680.     end
  2681.     return 0
  2682. go
  2683.  
  2684. --------------------------------------------------------------------------------
  2685. --. sp_MSscript_where_clause
  2686. --------------------------------------------------------------------------------
  2687. if exists (select * from sysobjects    where type = 'P'
  2688.     and name = 'sp_MSscript_where_clause')
  2689.     drop procedure sp_MSscript_where_clause
  2690. go
  2691.  
  2692. raiserror('Creating procedure sp_MSscript_where_clause', 0,1)
  2693. go
  2694. create procedure sp_MSscript_where_clause
  2695.     @objid          int,
  2696.     @columns      binary(32), 
  2697.     @clause_type  varchar(6) = 'pk_new', -- 'new pk', 'old pk', 'upd ts', 'upd rc', 'trg pk'
  2698.     @ts_col       sysname = NULL,
  2699.     @indent       int = 0,
  2700.     @op_type      char(3) = NULL -- 'ins', 'del'
  2701. as
  2702.     declare @cmd          nvarchar(4000)
  2703.     declare @colname      sysname
  2704.     declare @ccoltype     sysname
  2705.     declare @spacer       nvarchar(20)
  2706.     declare @indkey       int
  2707.     declare @indid        int
  2708.     declare @key          sysname
  2709.     declare @rc           int
  2710.     declare @this_col     int
  2711.     declare @art_col      int
  2712.     declare @src_cols     int
  2713.     declare @col          sysname
  2714.     declare @qualname     nvarchar(512)
  2715.  
  2716.     select @spacer = N' ', @cmd = N''
  2717.     select @indkey = 1, @indid = 0
  2718.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  2719.     select @src_cols = count(*) from syscolumns where id = @objid
  2720.     exec dbo.sp_MSpad_command @cmd output, @indent
  2721.     select @cmd = @cmd + N'where'
  2722.     exec dbo.sp_MSflush_command @cmd output, 1, @indent
  2723.  
  2724.     if @clause_type in ('new pk', 'old pk', 'upd ts', 'trg pk')
  2725.     begin
  2726.         exec @indid = dbo.sp_MStable_has_unique_index @objid
  2727.  
  2728.         if @indid > 0
  2729.         begin
  2730.             while @indkey < 16 and index_col(@qualname, @indid, @indkey) is not null
  2731.             begin
  2732.                 select @key = index_col(@qualname, @indid, @indkey)
  2733.                 --exec dbo.sp_MSget_col_position @objid, @columns, @key, @col output, @this_col output
  2734.                 exec dbo.sp_MSget_col_position @objid, @columns, @key, @col output, NULL, 0, NULL, @this_col output
  2735.         
  2736.                 if @clause_type = 'new pk'
  2737.                 begin
  2738.                     if ColumnProperty(@objid, @key, 'IsIdentity') = 1
  2739.                         select @cmd = @cmd + @spacer + quotename(@key) + N' = @@identity'
  2740.                     else
  2741.                         select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col
  2742.  
  2743.                     select @spacer = ' and
  2744.          '
  2745.                 end
  2746.                 else if @clause_type = 'upd ts'
  2747.                 begin
  2748.                     select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col + N'_old'
  2749.                     select @spacer = ' and
  2750.          '
  2751.                 end
  2752.                 else if @clause_type in ('trg pk', 'old pk')
  2753.                 begin
  2754.                     if @op_type = 'ins'
  2755.                         select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col + N'_old'
  2756.                     else
  2757.                         -- The vars correspoding to pk were set in sp_MSscript
  2758.                         -- _pkvar_assignment.
  2759.                         select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col 
  2760.  
  2761.                     select @spacer = ' and
  2762.          '
  2763.                 end
  2764.  
  2765.                 select @indkey = @indkey + 1
  2766.                 
  2767.                 -- flush command if necessary
  2768.                 exec dbo.sp_MSflush_command @cmd output, 0, @indent
  2769.             end
  2770.         end
  2771.  
  2772.         -- if clause_type is 'upd ts', add timestamp col
  2773.         if @clause_type = 'upd ts'
  2774.         begin
  2775.             exec dbo.sp_MSget_col_position @objid, @columns, @ts_col, @col output
  2776.             select @cmd = @cmd + @spacer + @ts_col + N' = @' + @col + N'_old'
  2777.         end
  2778.  
  2779.         -- save off command fragment
  2780.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  2781.     end
  2782.     else if @clause_type = 'upd rc'
  2783.     begin
  2784.         select @this_col = 1, @art_col = 1
  2785.  
  2786.         while @this_col <= @src_cols
  2787.         begin
  2788.             exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, @columns, 0, @colname output, @ccoltype output
  2789.             if @rc = 0
  2790.             begin
  2791.                 select @cmd = @cmd +  @spacer + '(' + @colname + N' = @c' + convert(varchar(4), @this_col) + N'_old or (' 
  2792.                 select @cmd = @cmd + @colname + ' is null and @c' + convert(varchar(4), @this_col) + N'_old is null)) '
  2793.                 select @spacer = N' and 
  2794.      '
  2795.                 exec dbo.sp_MSflush_command @cmd output, 0, @indent
  2796.             end
  2797.  
  2798.             exec dbo.sp_MSflush_command @cmd output, 1, @indent
  2799.  
  2800.             select @this_col = @this_col + 1
  2801.         end
  2802.  
  2803.         -- save off cmd fragment
  2804.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  2805.     end
  2806. go
  2807.  
  2808. grant execute on dbo.sp_MSscript_where_clause to public
  2809. go
  2810.  
  2811. --------------------------------------------------------------------------------
  2812. --. sp_MSscript_trigger_update_checks
  2813. --------------------------------------------------------------------------------
  2814. if exists (select * from sysobjects    where type = 'P'
  2815.     and name = 'sp_MSscript_trigger_update_checks')
  2816.     drop procedure sp_MSscript_trigger_update_checks
  2817. go
  2818.  
  2819. raiserror('Creating procedure sp_MSscript_trigger_update_checks', 0,1)
  2820. go
  2821.  
  2822. create procedure sp_MSscript_trigger_update_checks
  2823.     @objid int,
  2824.     @identity_col sysname,
  2825.     @ts_col       sysname,
  2826.     @op_type varchar(3) = 'ins', -- 'pk', 'ins', 'upd'
  2827.     @indent int = 0
  2828. as
  2829.     declare @cmd          nvarchar(4000)
  2830.     declare @colname      sysname
  2831.     declare @ccoltype     sysname
  2832.     declare @src_cols     int
  2833.     declare @this_col     int
  2834.     declare @rc           int
  2835.     declare @qualname     nvarchar(512)
  2836.     declare @indid        int
  2837.     declare @key          sysname
  2838.     declare @indkey       int
  2839.  
  2840.  
  2841.     if @op_type = 'pk'
  2842.     begin
  2843.         select @indkey = 1
  2844.         exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  2845.         exec @indid = dbo.sp_MStable_has_unique_index @objid
  2846.         if @indid > 0
  2847.           begin
  2848.             exec dbo.sp_MSpad_command @cmd output, @indent
  2849.             while @indkey < 16 and index_col(@qualname, @indid, @indkey) is not null
  2850.             begin
  2851.                 select @key = index_col(@qualname, @indid, @indkey)
  2852.                 select @cmd = N'if update(' + @key + N')
  2853. '
  2854.                 exec dbo.sp_MSflush_command @cmd output, 1, @indent
  2855.                 insert into #proctext(procedure_text) values(N'begin
  2856.      exec sp_MSreplraiserror 20517
  2857.      goto FAILURE
  2858.  end 
  2859.  
  2860. ')
  2861.                 select @indkey = @indkey + 1
  2862.             end
  2863.         end
  2864.     end
  2865.     else
  2866.     begin
  2867.         -- Image cols
  2868.         select @src_cols = count(*) from syscolumns where id = @objid
  2869.         select @this_col = 1
  2870.     exec dbo.sp_MSpad_command @cmd output, @indent
  2871.    
  2872.         while @this_col <= @src_cols
  2873.         begin
  2874.             exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, null, 1, @colname output, @ccoltype output
  2875.             if @rc = 0  and EXISTS (select name from syscolumns where id=@objid and @this_col=colid and iscomputed<>1)
  2876.             begin
  2877.                 if @ccoltype in ('text','ntext','image')
  2878.                 begin
  2879.                 if @op_type = 'ins'
  2880.                     begin
  2881.                         select @cmd = N'if update(' +  quotename(@colname) + ') 
  2882. '
  2883.                         exec dbo.sp_MSflush_command @cmd output, 1, 0
  2884.                         insert into #proctext(procedure_text) values(N'    exec sp_MSreplraiserror 20508
  2885. ')
  2886.                     end
  2887.                     else if @op_type = 'upd'
  2888.                     begin
  2889.                         select @cmd = N'if update(' +  quotename(@colname) + ') 
  2890.                         exec dbo.sp_MSflush_command @cmd output, 1, 0
  2891.                         insert into #proctext(procedure_text) values(N'begin
  2892.      exec sp_MSreplraiserror 20509
  2893.      goto FAILURE 
  2894.  end
  2895.  
  2896. ')
  2897.                     end
  2898.                 end
  2899.             end
  2900.             select @this_col = @this_col + 1
  2901.         end
  2902.     end
  2903.  
  2904.     -- identity col
  2905.     if @op_type = 'upd' and @identity_col is not null
  2906.     begin
  2907.         select @cmd = N'if update(' +  quotename(@identity_col) + N') 
  2908. '
  2909.         exec dbo.sp_MSflush_command @cmd, 1
  2910.         insert into #proctext(procedure_text) values(N'begin
  2911.      exec sp_MSreplraiserror 20510
  2912.      goto FAILURE
  2913.  end
  2914.  
  2915. ')
  2916.     end
  2917.  
  2918.     -- timestamp col
  2919.     if @op_type = 'upd' and @ts_col is not null
  2920.     begin
  2921.         select @cmd = N'if update(' +  quotename(@ts_col) + N') 
  2922. '
  2923.         exec dbo.sp_MSflush_command @cmd, 1
  2924.         insert into #proctext(procedure_text) values(N'begin
  2925.      exec sp_MSreplraiserror 20511
  2926.      goto FAILURE
  2927.  end
  2928.  
  2929. ')
  2930.     end
  2931.  
  2932. go    
  2933.  
  2934. grant execute on dbo.sp_MSscript_trigger_update_checks to public
  2935. go
  2936.  
  2937. --------------------------------------------------------------------------------
  2938. --. sp_MSget_synctran_column
  2939. --------------------------------------------------------------------------------
  2940. if exists (select * from sysobjects    where type = 'P'
  2941.     and name = 'sp_MSget_synctran_column')
  2942.     drop procedure sp_MSget_synctran_column
  2943. go
  2944.  
  2945. raiserror('Creating procedure sp_MSget_synctran_column', 0,1)
  2946. go
  2947. create procedure sp_MSget_synctran_column
  2948.     @ts_col sysname,
  2949.     @op_type char(3), -- 'ins, 'upd', 'del'
  2950.     @is_new    bit,
  2951.     @primary_key_bitmap varbinary(4000),
  2952.     @colname sysname,
  2953.     @this_col int, -- position in the table
  2954.     @column nvarchar(4000) output,
  2955.     @from_proc bit = 0,
  2956.     @coltype sysname = NULL,
  2957.     @type    varchar(10) = NULL,
  2958.     @art_col int = null -- position in the article partition.
  2959. as
  2960.     declare @bytestr      nvarchar(10)
  2961.     declare @bitstr       nvarchar(10)
  2962.     declare @typed_null      nvarchar(255)
  2963.  
  2964.     if @coltype is null
  2965.         select @typed_null = 'NULL'
  2966.     else
  2967.         select @typed_null = 'convert(' + @coltype + ', NULL)' 
  2968.  
  2969.     -- Optimization:
  2970.     -- If the column value is not needed, we set the corresponding
  2971.     -- param to null to reduce the network traffic. Here is the rule:
  2972.  
  2973.     -- For new values in update trigger,
  2974.     --    Set the param to column value or null depending on whether or
  2975.     --  or the column is updated.
  2976.     -- For old values 
  2977.     --    if ts col is replicated and the current column is not the ts col
  2978.     --    and the column is not in primary key, set the param to null
  2979.     -- For other cases
  2980.     --    set the param to column values.
  2981.  
  2982.     -- Called by proc
  2983.     if @type = 'pk_var'
  2984.     begin
  2985.         select @bytestr = convert( nvarchar, 1 + (@this_col-1) / 8 )
  2986.         select @bitstr =  convert( nvarchar, power(2, (@this_col-1) % 8 ) )
  2987.  
  2988.         select @column = N'case substring(@bitmap,' 
  2989.             + @bytestr + N',1) & ' + @bitstr +  
  2990.             N' when ' + @bitstr + N' then ' + N'@c'+ convert( nvarchar, @this_col ) + 
  2991.             N' else ' + N'@c'+ convert( nvarchar, @this_col )  + N'_old end'
  2992.     end
  2993.     else if (@from_proc = 1)
  2994.     begin
  2995.         select @bytestr = convert( nvarchar, 1 + (@art_col-1) / 8 )
  2996.         select @bitstr =  convert( nvarchar, power(2, (@art_col-1) % 8 ) )
  2997.  
  2998.         select @column = N'case substring(@bitmap,' 
  2999.             + @bytestr + N',1) & ' + @bitstr +  
  3000.             N' when ' + @bitstr + N' then ' + N'@c'+ convert( nvarchar, @this_col ) + 
  3001.             N' else [' + @colname + N'] end'
  3002.     end
  3003.     -- Called in trigger,
  3004.     else if (@is_new = 1) and (@op_type = 'upd')
  3005.     begin
  3006.         -- @bitmap is set using columns_updated() at the beginning
  3007.         -- of the trigger.
  3008.         select @bytestr = convert( nvarchar, 1 + (@this_col-1) / 8 )
  3009.         select @bitstr =  convert( nvarchar, power(2, (@this_col-1) % 8 ) )
  3010.         
  3011.         select @column = N'case substring(@bitmap,' + @bytestr + N',1) & ' + @bitstr +  
  3012.             N' when ' + @bitstr + N' then [' + @colname + N'] ' + 
  3013.             N' else ' + @typed_null 
  3014.             +' end'
  3015.     end
  3016.     else if @is_new = 0 and @ts_col is not null and @colname <> @ts_col and
  3017.         (substring(@primary_key_bitmap, 1 + (@this_col-1) / 8 , 1) &
  3018.             power(2, (@this_col-1) % 8 )) = 0
  3019.         select @column =  @typed_null
  3020.     else 
  3021.         select @column = N'[' + @colname  + N'] '
  3022.     
  3023.     -- Add a new line
  3024.     select @column = @column + N'
  3025.     '
  3026. go
  3027.  
  3028. --------------------------------------------------------------------------------
  3029. --. sp_addsynctriggers
  3030. --------------------------------------------------------------------------------
  3031. if exists (select * from sysobjects    where type = 'P'
  3032.     and name = 'sp_addsynctriggers')
  3033.     drop procedure sp_addsynctriggers
  3034. go
  3035.  
  3036. raiserror('Creating procedure sp_addsynctriggers', 0,1)
  3037. go
  3038.  
  3039. CREATE PROCEDURE sp_addsynctriggers 
  3040.     @sub_table       sysname,            -- table name 
  3041.     @sub_table_owner sysname,            -- table owner
  3042.     @publisher      sysname,            -- publishing server name
  3043.     @publisher_db   sysname,            -- publishing database name. If NULL then same as current db
  3044.     @publication    sysname,            -- publication name.
  3045.     @ins_proc       sysname,
  3046.     @upd_proc       sysname,
  3047.     @del_proc       sysname,
  3048.     @proc_owner        sysname,
  3049.     @identity_col   sysname = 'NULL', 
  3050.     @ts_col         sysname = 'NULL',
  3051.     @filter_clause  nvarchar(4000) = 'NULL',
  3052.     @primary_key_bitmap  varbinary(4000)
  3053. AS
  3054.     set nocount on
  3055.  
  3056.     declare @db                  sysname
  3057.     declare @trigname            sysname
  3058.     declare @ins_trig            sysname
  3059.     declare @upd_trig            sysname
  3060.     declare @del_trig            sysname
  3061.     declare @dbname              sysname
  3062.     declare @ccols               int
  3063.     declare @cnt                 int
  3064.     declare @retcode              int
  3065.     declare @cmd                 nvarchar(4000)
  3066.     declare @merge_pub_object_bit    int
  3067.     declare @synctran_bit        int
  3068.     declare @object_id            int
  3069.     declare @bitmap_str            varchar(8000)
  3070.     declare @constraint_name    sysname
  3071.     declare @quoted_name        nvarchar(500)
  3072.     declare @qualname            nvarchar(500)
  3073.  
  3074.     select @merge_pub_object_bit     = 128
  3075.     select @synctran_bit            = 256
  3076.  
  3077.     --  Security Check
  3078.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  3079.     IF @@ERROR <> 0 or @retcode <> 0
  3080.     RETURN(1)
  3081.  
  3082.     -- Dist Agent executes this sproc with 'implicit transasctions on'.
  3083.     -- We take care of our own transactions boundaries to get out of tran 
  3084.     while @@trancount > 0 commit tran
  3085.  
  3086.     -- check valid server and database setting
  3087.     -- 1. nested trigger have to be on
  3088.     if exists (select * from master..sysconfigures where config = 115 and value = 0)
  3089.     begin
  3090.         raiserror(21081, 16, 1)
  3091.         return (1)
  3092.     end
  3093.  
  3094.     -- 2. db option: recursive trigger have to be off
  3095.     if DATABASEPROPERTY(db_name(), N'IsRecursiveTriggersEnabled') <> 0
  3096.     begin
  3097.         raiserror(21082, 16, 1)
  3098.         return (1)
  3099.     end    
  3100.     
  3101.     -- 2. db compatibility level have to be 7.0
  3102.     if exists (select * from master..sysdatabases where dbid = db_id() and 
  3103.         cmptlevel < 70)
  3104.     begin
  3105.         raiserror(21083, 16, 1)
  3106.         return (1)
  3107.     end    
  3108.     
  3109.     if lower(@sub_table_owner) = N'null'
  3110.         select @qualname = QUOTENAME(@sub_table)        
  3111.     else
  3112.         select @qualname = QUOTENAME(@sub_table_owner) + N'.' + QUOTENAME(@sub_table)
  3113.  
  3114.     -- Verify that table exists 
  3115.     select @object_id = object_id (@qualname)
  3116.     if @object_id is null
  3117.     begin
  3118.         raiserror(20507, 16, 1, @qualname, 'sp_addsynctriggers')
  3119.         return (1)
  3120.     end
  3121.     
  3122.  
  3123.     -- Add default to timestamp and identity column
  3124.     select @constraint_name = 'MSrepl_synctran_ts_default_' + convert(nvarchar(10), @object_id)
  3125.     select @quoted_name = quotename(@ts_col)
  3126.     if @ts_col is not null and @ts_col not in ('null','NULL') and not exists
  3127.         (select * from sysobjects where name = @constraint_name)
  3128.     begin
  3129.         exec ('alter table ' + @qualname + 
  3130.             ' add constraint ' + @constraint_name + 
  3131.             ' default 0 for ' + @quoted_name )
  3132.         if @@ERROR<>0 return 1
  3133.     end
  3134.  
  3135.     select @constraint_name = 'MSrepl_synctran_identity_default_' + convert(nvarchar(10), @object_id)
  3136.     select @quoted_name = quotename(@identity_col)
  3137.     if @identity_col is not null and @identity_col not in ('null','NULL') and not exists
  3138.         (select * from sysobjects where name = @constraint_name)
  3139.     begin
  3140.         exec ('alter table ' + @qualname + 
  3141.             ' add constraint ' + @constraint_name + 
  3142.             ' default 0 for ' + @quoted_name )
  3143.         if @@ERROR<>0 return 1
  3144.     end
  3145.  
  3146.     -- If MSsubscription_properties table does not exists, create on.
  3147.     exec @retcode = dbo.sp_MScreate_sub_tables
  3148.     IF @@ERROR <> 0 or @retcode <> 0
  3149.         RETURN(1)
  3150.  
  3151.     -- If no entry in MSsubscription_properties for this publication, add one.
  3152.  
  3153.     IF NOT EXISTS (select * from MSsubscription_properties 
  3154.             where UPPER(publisher) = UPPER(@publisher)
  3155.                 and publisher_db =  @publisher_db
  3156.                 and publication = @publication) 
  3157.     BEGIN
  3158.         -- Use status rpc for local publisher, see bug 39385
  3159.         declare @security_mode int
  3160.         declare @login sysname
  3161.         if UPPER(@@servername) = UPPER(@publisher)
  3162.         begin
  3163.             select @security_mode = 2
  3164.         end
  3165.         else
  3166.         begin
  3167.             select @security_mode = 0
  3168.             select @login = 'sa'
  3169.         end
  3170.  
  3171.         exec @retcode = dbo.sp_link_publication
  3172.             @publisher = @publisher,
  3173.             @publisher_db = @publisher_db,
  3174.             @publication = @publication,
  3175.             @security_mode = @security_mode,
  3176.             @login = @login,
  3177.             @password = NULL
  3178.         IF @@ERROR <> 0 or @retcode <> 0
  3179.             RETURN(1)
  3180.     END
  3181.  
  3182.       
  3183.     if exists (select * from sysobjects where 
  3184.         replinfo & @merge_pub_object_bit <> 0 and
  3185.         id = @object_id)
  3186.     begin
  3187.         raiserror(21063, 16, 1, @qualname)
  3188.         return (1)
  3189.     end
  3190.  
  3191.     /*
  3192.     **    Create system table MSreplication_objects if it does not exist
  3193.     */
  3194.         IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  3195.             type = 'U' AND name = 'MSreplication_objects')
  3196.             BEGIN
  3197.                 CREATE TABLE dbo.MSreplication_objects
  3198.                 (
  3199.                 publisher sysname NULL,
  3200.                 publisher_db sysname NULL,
  3201.                    publication sysname NULL, 
  3202.                 object_name    sysname NOT NULL,
  3203.                 object_type    char(2) NOT NULL
  3204.                 )
  3205.                 IF @@ERROR <> 0
  3206.                     begin
  3207.                         rollback transaction 
  3208.                         return (1)
  3209.                     end
  3210.                 EXEC dbo.sp_MS_marksystemobject 'MSreplication_objects'
  3211.  
  3212.                 CREATE UNIQUE CLUSTERED INDEX ucMSreplication_objects ON dbo.MSreplication_objects(object_name)
  3213.  
  3214.                 IF @@ERROR <> 0
  3215.                     begin
  3216.                         rollback transaction 
  3217.                         return (1)
  3218.                     end
  3219.             END
  3220.  
  3221.  
  3222.     -- Drop all replication triggers on the source object
  3223.     -- We should drop all because we don't support updatable subscriptions to 
  3224.     -- multiple publications on same dest table.
  3225.     declare object_cursor CURSOR LOCAL FAST_FORWARD for 
  3226.         select o.object_name, so.id from MSreplication_objects o, sysobjects so where
  3227.             o.object_name = so.name and
  3228.             so.parent_obj = @object_id and
  3229.             o.object_type = 'T'
  3230.  
  3231.     declare @old_id int 
  3232.     declare @old_name sysname
  3233.  
  3234.     OPEN object_cursor
  3235.     FETCH object_cursor INTO @old_name, @old_id
  3236.      WHILE (@@fetch_status <> -1)
  3237.     BEGIN
  3238.         exec @retcode = dbo.sp_MSdrop_object 
  3239.             @object_id = @old_id
  3240.         if @retcode <> 0 or @@error <> 0
  3241.             goto UNDO
  3242.         delete from MSreplication_objects where object_name=@old_name
  3243.         FETCH object_cursor INTO @old_name, @old_id
  3244.     END
  3245.     CLOSE object_cursor
  3246.     DEALLOCATE object_cursor
  3247.  
  3248.     -- Generate trigger names
  3249.         select @trigname = RTRIM(SUBSTRING(@sub_table,1,110))
  3250.     select @ins_trig = N'trg_MSsync_ins_' + @trigname 
  3251.     select @upd_trig = N'trg_MSsync_upd_' + @trigname 
  3252.     select @del_trig = N'trg_MSsync_del_' + @trigname 
  3253.  
  3254.     -- check uniqueness of names and revert to ugly guid-based name if friendly name already exists
  3255.     if exists (select name from sysobjects where name in (@ins_trig, @upd_trig, @del_trig))
  3256.         begin
  3257.             declare @guid_name nvarchar(36)
  3258.             select @guid_name =  convert (nvarchar(36), newid())
  3259.         select @ins_trig = 'trg_MSsync_ins_' + @guid_name
  3260.         select @upd_trig = 'trg_MSsync_upd_' + @guid_name
  3261.         select @del_trig = 'trg_MSsync_del_' + @guid_name
  3262.         end
  3263.  
  3264.     exec @retcode = master..xp_varbintohexstr @primary_key_bitmap, @bitmap_str output
  3265.     if @retcode <> 0 or @@error <> 0
  3266.         return 1
  3267. /*
  3268.     exec ('if exists (select * from sysobjects where name = N''' + @ins_trig + N''' and xtype = N''TR'')
  3269.         drop trigger ' + @ins_trig)
  3270.     exec ('if exists (select * from sysobjects where name = N''' + @upd_trig + N''' and xtype = N''TR'')
  3271.         drop trigger ' + @upd_trig)
  3272.     exec ('if exists (select * from sysobjects where name = N''' + @del_trig + N''' and xtype = N''TR'')
  3273.         drop trigger ' + @del_trig)
  3274.  
  3275. */
  3276.     -- We are now going to create triggers, so start a transaction
  3277.     begin tran
  3278.  
  3279.         -- Call out to individual create trigger routines
  3280.         select @dbname = db_name()
  3281.         select @cmd = 'sp_MSscript_sync_ins_trig ' + 
  3282.             convert( nvarchar, @object_id )  + ', ' + 
  3283.             quotename(@publisher)     + ', ' + 
  3284.             quotename(@publisher_db)  + ', ' + 
  3285.             quotename(@ins_trig)      + ', ' + 
  3286.             quotename(@ins_proc)      + ', ' + 
  3287.             quotename(@proc_owner)      + ', ' + 
  3288.             quotename(@identity_col)  + ', ' + 
  3289.             quotename(@ts_col)        
  3290.         if @filter_clause in ('NULL', 'null')
  3291.             select @cmd = @cmd + ', null' 
  3292.         else 
  3293.             select @cmd = @cmd + ', N''' + replace (@filter_clause,'''','''''')  + ''''
  3294.  
  3295.  
  3296.         exec master..xp_execresultset @cmd, @dbname
  3297.         IF @@ERROR <> 0
  3298.             goto UNDO
  3299.  
  3300.         select @cmd = 'sp_MSscript_sync_upd_trig ' + 
  3301.             convert( nvarchar, @object_id )  + ', ' + 
  3302.             quotename(@publisher)     + ', ' + 
  3303.             quotename(@publisher_db)  + ', ' + 
  3304.             quotename(@upd_trig)      + ', ' + 
  3305.             quotename(@upd_proc)      + ', ' + 
  3306.             quotename(@proc_owner)       + ', ' + 
  3307.             quotename(@identity_col)  + ', ' + 
  3308.             quotename(@ts_col)        
  3309.         if @filter_clause in ('NULL', 'null')
  3310.             select @cmd = @cmd + ', null' 
  3311.         else 
  3312.             select @cmd = @cmd + ', N''' + replace (@filter_clause,'''','''''')  + ''''
  3313.                                     
  3314.         -- Update need primary key bitmap
  3315.          select @cmd = @cmd + ', ' + @bitmap_str
  3316.         
  3317.          exec master..xp_execresultset @cmd, @dbname
  3318.         IF @@ERROR <> 0
  3319.             goto UNDO
  3320.  
  3321.  
  3322.         select @cmd = 'sp_MSscript_sync_del_trig ' + 
  3323.             convert( nvarchar, @object_id )  + ', ' + 
  3324.             quotename(@publisher)     + ', ' + 
  3325.             quotename(@publisher_db)  + ', ' + 
  3326.             quotename(@del_trig)      + ', ' + 
  3327.             quotename(@del_proc)      + ', ' + 
  3328.             quotename(@proc_owner)       + ', ' + 
  3329.             quotename(@identity_col)  + ', ' + 
  3330.             quotename(@ts_col)        
  3331.         if @filter_clause in ('NULL', 'null')
  3332.             select @cmd = @cmd + ', null' 
  3333.         else 
  3334.             select @cmd = @cmd + ', N''' + replace (@filter_clause,'''','''''')  + ''''            
  3335.  
  3336.         -- Delete need primary key bitmap
  3337.          select @cmd = @cmd + ', ' + @bitmap_str
  3338.         exec master..xp_execresultset @cmd, @dbname
  3339.         IF @@ERROR <> 0
  3340.             goto UNDO
  3341.  
  3342.         -- Drop old entries before insert. The triggers with those names
  3343.         -- are created as above.
  3344.         delete MSreplication_objects where object_name = @ins_trig
  3345.         IF @@ERROR <> 0
  3346.             goto UNDO
  3347.         delete MSreplication_objects where object_name = @upd_trig
  3348.         IF @@ERROR <> 0
  3349.             goto UNDO
  3350.         delete MSreplication_objects where object_name = @del_trig
  3351.         IF @@ERROR <> 0
  3352.             goto UNDO
  3353.  
  3354.         -- Mark procedures as system procs so they don't show up in the UI
  3355.         select @cmd = 'exec dbo.sp_MS_marksystemobject ' + quotename(@ins_trig)
  3356.         exec (@cmd)
  3357.         IF @@ERROR <> 0
  3358.             goto UNDO
  3359.  
  3360.         insert into MSreplication_objects(publisher, publisher_db, publication, object_name, object_type)
  3361.                     values(@publisher, @publisher_db, @publication, @ins_trig, 'T')
  3362.         IF @@ERROR <> 0
  3363.             goto UNDO
  3364.  
  3365.         select @cmd = 'exec dbo.sp_MS_marksystemobject ' + quotename(@upd_trig)
  3366.         exec (@cmd)
  3367.         IF @@ERROR <> 0
  3368.             goto UNDO
  3369.  
  3370.         insert into MSreplication_objects(publisher, publisher_db, publication, object_name, object_type)
  3371.                     values(@publisher, @publisher_db, @publication, @upd_trig, 'T')
  3372.         IF @@ERROR <> 0
  3373.             goto UNDO
  3374.  
  3375.         select @cmd = 'exec dbo.sp_MS_marksystemobject ' + quotename(@del_trig)
  3376.         exec (@cmd)
  3377.         IF @@ERROR <> 0
  3378.             goto UNDO
  3379.  
  3380.         insert into MSreplication_objects(publisher, publisher_db, publication, object_name, object_type)
  3381.                     values(@publisher, @publisher_db, @publication, @del_trig, 'T')
  3382.         IF @@ERROR <> 0
  3383.             goto UNDO
  3384.  
  3385.         -- Mark the table for warnings in BCP
  3386.         update sysobjects set replinfo = replinfo | @synctran_bit where
  3387.             id = @object_id
  3388.     -- commit tran
  3389.     commit tran
  3390.     return (0)
  3391. UNDO:
  3392.     if @@trancount <> 0
  3393.         rollback tran
  3394.     return(1)
  3395. go
  3396.  
  3397. grant exec on dbo.sp_addsynctriggers to public
  3398. go
  3399.  
  3400. --------------------------------------------------------------------------------
  3401. --. sp_MScheck_agent_instance
  3402. --------------------------------------------------------------------------------
  3403. if exists (select * from sysobjects    where type = 'P'
  3404.     and name = 'sp_MScheck_agent_instance')
  3405.     drop procedure sp_MScheck_agent_instance
  3406. go
  3407.  
  3408. raiserror('Creating procedure sp_MScheck_agent_instance', 0,1)
  3409. GO
  3410. CREATE PROCEDURE sp_MScheck_agent_instance
  3411. @application_name sysname,
  3412. @agent_type int = NULL
  3413.  
  3414. as
  3415.     declare @count_pro int
  3416.     set nocount on
  3417.     select @count_pro = count(*) from master..sysprocesses where 
  3418.         program_name = @application_name
  3419.     if @agent_type = 3
  3420.     begin
  3421.         -- The distribution agent will before connecting to the publisher with unique 
  3422.         -- application name
  3423.         if @count_pro > 0
  3424.             raiserror (21036, 16, -1, 'distribution')
  3425.     end
  3426.     else if @agent_type = 4
  3427.     begin
  3428.         -- The merge agent will connect to the publisher with unique application name
  3429.         -- then call this procedure
  3430.         if @count_pro > 1 
  3431.             raiserror (21036, 16, -1, 'merge')
  3432.     end
  3433.     else if @agent_type = 1
  3434.     begin
  3435.         -- The snapshot agent will connect to the distributiondb with unique application name
  3436.         -- then call this procedure
  3437.         if @count_pro > 2 
  3438.             raiserror (21036, 16, -1, 'snapshot')
  3439.     end
  3440.     else if @agent_type = 2
  3441.     begin
  3442.         -- The logreader agent will connect to the distributiondb with unique application name
  3443.         -- then call this procedure
  3444.         if @count_pro > 1 
  3445.             raiserror (21036, 16, -1, 'logreader')
  3446.     end
  3447. go
  3448.  
  3449. grant exec on dbo.sp_MScheck_agent_instance to public
  3450. go
  3451.  
  3452. --------------------------------------------------------------------------------
  3453. --. sp_MSCleanupForPullReinit
  3454. --------------------------------------------------------------------------------
  3455. if exists (select * from sysobjects    where type = 'P'
  3456.     and name = 'sp_MSCleanupForPullReinit')
  3457.     drop procedure sp_MSCleanupForPullReinit
  3458. go
  3459.  
  3460. raiserror('Creating procedure sp_MSCleanupForPullReinit', 0,1)
  3461. GO
  3462.  
  3463. CREATE PROCEDURE sp_MSCleanupForPullReinit (
  3464.     @publication         sysname,
  3465.     @publisher_db        sysname,
  3466.     @publisher            sysname = @@servername
  3467.     ) AS
  3468.     declare @pubid         uniqueidentifier
  3469.     declare @parentid     uniqueidentifier
  3470.     declare @artid         uniqueidentifier
  3471.     declare @retcode    smallint
  3472.  
  3473.     /*
  3474.     ** Security Check
  3475.     */
  3476.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  3477.     IF @@ERROR <> 0 or @retcode <> 0
  3478.         return (1)
  3479.  
  3480.     /* This only gets called after database is enable to subscribe, so sysmergepublications should exist */
  3481.     select @pubid = pubid, @parentid = parentid FROM sysmergepublications 
  3482.         WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db = @publisher_db
  3483.  
  3484.     /* Normal case - nothing to cleanup, just return */
  3485.     if @pubid is null
  3486.         return (1)    
  3487.  
  3488.     delete from MSmerge_genhistory where pubid = @pubid
  3489.     delete from sysmergesubsetfilters where pubid=@pubid
  3490.     delete from sysmergeschemachange where pubid = @pubid
  3491.     delete from MSmerge_contents where tablenick in (select nickname from sysmergearticles where pubid=@pubid)
  3492.     delete from MSmerge_tombstone where tablenick in (select nickname from sysmergearticles where pubid=@pubid)
  3493. GO
  3494.  
  3495. grant execute on dbo.sp_MSCleanupForPullReinit to public
  3496. go
  3497.  
  3498. -- BUGBUG : sp_MSCleanupForPullReinit doesn't follow naming standard
  3499.  
  3500. --------------------------------------------------------------------------------
  3501. --. sp_MSpublicationcleanup
  3502. --------------------------------------------------------------------------------
  3503. if exists (select * from sysobjects    where type = 'P'
  3504.     and name = 'sp_MSpublicationcleanup')
  3505.     drop procedure sp_MSpublicationcleanup
  3506. go
  3507.  
  3508. raiserror('Creating procedure sp_MSpublicationcleanup', 0,1)
  3509. GO
  3510.  
  3511. CREATE PROCEDURE sp_MSpublicationcleanup (
  3512.     @publication         sysname,
  3513.     @publisher_db        sysname,
  3514.     @publisher            sysname = @@servername
  3515.     ) AS
  3516.     declare @pubid         uniqueidentifier
  3517.     declare @parentid     uniqueidentifier
  3518.     declare @artid         uniqueidentifier
  3519.     declare @retcode    smallint
  3520.  
  3521.     /*
  3522.     ** Security Check
  3523.     */
  3524.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  3525.     IF @@ERROR <> 0 or @retcode <> 0
  3526.         return (1)
  3527.  
  3528.     /* This only gets called after database is enable to subscribe, so sysmergepublications should exist */
  3529.     select @pubid = pubid, @parentid = parentid FROM sysmergepublications 
  3530.         WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db = @publisher_db
  3531.  
  3532.     /* Normal case - nothing to cleanup, just return */
  3533.     if @pubid is null
  3534.         return (1)
  3535.  
  3536.     /* Clean up the articles for this publication, and delete the row */
  3537.     select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  3538.     while @artid is not null
  3539.         begin
  3540.         if not exists (select * from sysmergearticles WHERE artid = @artid and pubid <> @pubid)
  3541.             begin
  3542.                 exec @retcode=sp_MSarticlecleanup @pubid, @artid
  3543.                 if @retcode<>0 or @@ERROR<>0 return (1)
  3544.             end
  3545.         delete from sysmergearticles where artid = @artid and pubid = @pubid
  3546.         set @artid = NULL
  3547.         select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  3548.         end
  3549.         
  3550.     /* Now clean up any traces in other system tables */
  3551.     
  3552.  
  3553.     delete from MSmerge_genhistory where pubid = @pubid
  3554.     delete from MSmerge_replinfo where repid in (select subid from sysmergesubscriptions where pubid = @pubid and status <> 2)
  3555.     delete from sysmergesubsetfilters where pubid=@pubid
  3556.     delete from sysmergesubscriptions where pubid = @pubid and status <> 2
  3557.     delete from sysmergepublications where pubid = @pubid
  3558.     delete from sysmergeschemachange where pubid = @pubid
  3559. GO
  3560.  
  3561. grant execute on dbo.sp_MSpublicationcleanup to public
  3562. go
  3563.  
  3564. --------------------------------------------------------------------------------
  3565. --. sp_MSarticlecleanup
  3566. --------------------------------------------------------------------------------
  3567. if exists (select * from sysobjects    where type = 'P'
  3568.     and name = 'sp_MSarticlecleanup')
  3569.     drop procedure sp_MSarticlecleanup
  3570. go
  3571.  
  3572. raiserror('Creating procedure sp_MSarticlecleanup', 0,1)
  3573. GO
  3574.  
  3575. create procedure sp_MSarticlecleanup
  3576.     (@pubid uniqueidentifier, @artid uniqueidentifier)
  3577. as
  3578.     set nocount on
  3579.     declare @source_table     nvarchar(258)
  3580.     declare @conflict_table nvarchar(258)
  3581.     declare @ownername         sysname
  3582.     declare @objectname     sysname
  3583.     declare @tablenick        int
  3584.     declare @objid             int
  3585.     declare @sync_objid     int
  3586.     declare @view_type        int
  3587.     declare @tsview            nvarchar(50)
  3588.     declare @guidstr        nvarchar(50)
  3589.     declare @csview            nvarchar(50)
  3590.     declare @viewname        nvarchar(258)
  3591.     declare @retcode        smallint
  3592.     declare @qualified_name    nvarchar(258)
  3593.     declare @bi_tablename    sysname
  3594.     declare    @bi_viewname    sysname
  3595.     declare @bi_procname    sysname
  3596.     
  3597.     -- to be called after article is set up in a subscriber
  3598.  
  3599.     /*
  3600.     ** Security Check
  3601.     */
  3602.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  3603.     IF @@ERROR <> 0 or @retcode <> 0
  3604.         return (1)
  3605.  
  3606.     select @objid = max(objid) from sysmergearticles where artid = @artid
  3607.  
  3608.     -- get owner name, and table name
  3609.     select @objectname = name, @ownername = user_name(uid)
  3610.         from sysobjects    where id = @objid
  3611.  
  3612.     -- construct the qualified table name
  3613.     select @source_table = @ownername + '.' + @objectname
  3614.  
  3615.     exec @retcode=sp_MSguidtostr @artid, @guidstr out
  3616.     if @retcode<>0 or @@ERROR<>0 return (1)
  3617.     
  3618.     -- get the insert, update and conflict proc names from sysmergearticles
  3619.     select     @sync_objid = sync_objid, 
  3620.             @view_type = view_type, 
  3621.             @tablenick = nickname,
  3622.             @bi_tablename = object_name(before_image_objid),
  3623.             @bi_viewname = object_name(before_view_objid),
  3624.             @conflict_table = conflict_table 
  3625.         from sysmergearticles where
  3626.             pubid = @pubid and artid = @artid
  3627.  
  3628.     /*
  3629.     ** We are not owner_qualifed this conflict table because it is created by snapshot agent
  3630.     */
  3631.     select @qualified_name = QUOTENAME(@conflict_table)
  3632.  
  3633.     /* Drop the conflict table */
  3634.     if (@conflict_table IS NOT NULL) and exists (select * from sysobjects where
  3635.             name = @conflict_table and type = 'U')
  3636.         begin
  3637.             exec ('drop table ' + @qualified_name)
  3638.             if @@ERROR<>0 return (1)
  3639.         end
  3640.  
  3641.     select @qualified_name = QUOTENAME(@ownername) + '.' + QUOTENAME(@conflict_table)
  3642.  
  3643.     /* If there is a before image table, drop it and its cleanup proc */
  3644.     if (@bi_tablename is not null)
  3645.         begin
  3646.         set @bi_procname = @bi_tablename + '_clean'
  3647.  
  3648.         if exists (select * from sysobjects where
  3649.             name = @bi_procname and type = 'P')
  3650.             begin
  3651.             exec ('drop proc ' + @bi_procname)
  3652.             if @@ERROR<>0 return (1)
  3653.             end
  3654.         exec ('drop table ' + @bi_tablename)
  3655.         if @@ERROR<>0 return (1)
  3656.         end
  3657.     /* If there is a before image view, drop it */
  3658.     if (@bi_viewname is not null)
  3659.         begin
  3660.         exec ('drop view ' + @bi_viewname)
  3661.         if @@ERROR<>0 return (1)
  3662.         end
  3663.  
  3664.     /* Drop the article procs */
  3665.     exec @retcode=sp_MSdroparticleprocs @pubid, @artid
  3666.     if @@ERROR<>0 or @retcode<>0 return (1)
  3667.  
  3668.     /* Drop the article triggers */
  3669.     exec @retcode=sp_MSdroparticletriggers @source_table
  3670.     if @@ERROR<>0 or @retcode<>0 return (1)
  3671.  
  3672.     exec @retcode=sp_MSunmarkreplinfo @objectname, @ownername
  3673.     if @@ERROR<>0 or @retcode<>0 return (1)
  3674.  
  3675.     /* If the article's has a temporary ( view type = 2) or a permanent view (view_type = 1 ) drop the sync object */
  3676.     if (@view_type = 1 OR @view_type = 2)
  3677.         begin
  3678.             select @viewname = sysobjects.name from sysobjects where 
  3679.                 ObjectProperty (sysobjects.id, 'IsView') = 1 
  3680.                 and ObjectProperty (sysobjects.id, 'IsMSShipped') = 1 
  3681.                 and sysobjects.id = @sync_objid
  3682.             if @viewname IS NOT NULL
  3683.                 begin
  3684.                     select @ownername = user_name(uid) from sysobjects where name=@viewname
  3685.                     set @viewname = QUOTENAME(@ownername) + '.' + QUOTENAME(@viewname)
  3686.                     exec ('drop view ' + @viewname)
  3687.                     if @@ERROR<>0 return (1)
  3688.                 end
  3689.         end
  3690.  
  3691.     /*
  3692.     ** Drop the views created for MSmerge_contents and MSmerge_tombstone before dropping these two tables
  3693.     */
  3694.     set @csview = 'ctsv_' + @guidstr
  3695.     set @tsview = 'tsvw_' + @guidstr
  3696.     if EXISTS (select * from sysobjects where name=@csview and type='V')
  3697.     BEGIN
  3698.         select @ownername = user_name(uid) from sysobjects where  name=@csview
  3699.         select @viewname = QUOTENAME(@ownername) + '.' + QUOTENAME(@csview)
  3700.         exec ('drop view ' + @viewname)
  3701.             if @@ERROR<>0 return (1)
  3702.     END
  3703.         
  3704.     if EXISTS (select * from sysobjects where name=@tsview and type='V')
  3705.     BEGIN
  3706.         select @ownername = user_name(uid) from sysobjects where  name=@tsview
  3707.         select @viewname = QUOTENAME(@ownername) + '.' + QUOTENAME(@tsview)
  3708.         exec ('drop view ' + @viewname)
  3709.             if @@ERROR<>0 return (1)
  3710.     END
  3711.  
  3712.     /* Delete from contents, tombstone, delete conflicts */
  3713.     delete from MSmerge_contents where tablenick = @tablenick
  3714.     delete from MSmerge_tombstone where tablenick = @tablenick
  3715.     delete from MSmerge_delete_conflicts where tablenick = @tablenick
  3716. GO
  3717.  
  3718. grant execute on dbo.sp_MSarticlecleanup to public
  3719. go
  3720.  
  3721. --------------------------------------------------------------------------------
  3722. --. sp_subscription_cleanup
  3723. --------------------------------------------------------------------------------
  3724. if exists (select * from sysobjects    where type = 'P'
  3725.     and name = 'sp_subscription_cleanup')
  3726.     drop procedure sp_subscription_cleanup
  3727. go
  3728.  
  3729. raiserror('Creating procedure sp_subscription_cleanup', 0,1)
  3730. GO
  3731. CREATE PROCEDURE sp_subscription_cleanup (
  3732.     @publisher        sysname,
  3733.     @publisher_db    sysname,
  3734.     @publication    sysname = NULL,
  3735.     @reserved        nvarchar(10) = NULL
  3736. )AS
  3737.  
  3738.     declare @object_name sysname
  3739.     declare @object_type char(2)
  3740.     declare @independent_agent bit
  3741.     declare @retcode int
  3742.     declare @synctran_bit int
  3743.     declare @parent_obj int
  3744.     declare @object_id int
  3745.  
  3746.     select @synctran_bit            = 256
  3747.  
  3748.     /*
  3749.     ** Security Check
  3750.     */
  3751.  
  3752.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  3753.     IF @@ERROR <> 0 or @retcode <> 0
  3754.         RETURN(1)
  3755.  
  3756.     if @publication = '' OR @publication is NULL
  3757.         select @independent_agent = 0
  3758.     else
  3759.         select @independent_agent = 1
  3760.  
  3761.     IF exists (select name from sysobjects where name = 'MSreplication_objects')
  3762.     BEGIN
  3763.         declare object_cursor CURSOR LOCAL FAST_FORWARD for 
  3764.             select DISTINCT object_name, object_type from MSreplication_objects o
  3765.                     where (UPPER(o.publisher) = UPPER(@publisher) and
  3766.                         o.publisher_db = @publisher_db and
  3767.                         o.publication = @publication) or
  3768.                         @reserved = 'drop_all'
  3769.  
  3770.         OPEN object_cursor
  3771.         FETCH object_cursor INTO @object_name, @object_type
  3772.          WHILE (@@fetch_status <> -1)
  3773.               BEGIN
  3774.                   IF @object_type = 'T' 
  3775.                   begin
  3776.                     select @parent_obj = NULL
  3777.                     select @parent_obj = parent_obj, @object_id = id from
  3778.                         sysobjects where name = @object_name 
  3779.                     if @parent_obj is not null
  3780.                     begin
  3781.                         -- Unmark synctran bit
  3782.                         update sysobjects set replinfo = replinfo & ~@synctran_bit where 
  3783.                             id = @parent_obj and
  3784.                             (replinfo & @synctran_bit) <> 0
  3785.                         IF @@ERROR <> 0 
  3786.                             GOTO UNDO
  3787.                         exec @retcode = dbo.sp_MSdrop_object 
  3788.                             @object_id = @object_id
  3789.                         if @retcode <> 0 or @@error <> 0
  3790.                             goto UNDO
  3791.                     end
  3792.                   end
  3793.                   delete from MSreplication_objects where object_name=@object_name
  3794.                   FETCH object_cursor INTO @object_name, @object_type
  3795.               END
  3796.         CLOSE object_cursor
  3797.         DEALLOCATE object_cursor
  3798.         
  3799.     if not exists (select * from MSreplication_objects) 
  3800.         drop table MSreplication_objects
  3801.         
  3802.     END
  3803.  
  3804.     IF exists (select name from sysobjects where name = 'MSreplication_subscriptions')
  3805.     BEGIN
  3806.     delete from MSreplication_subscriptions 
  3807.         where (UPPER(publisher) = UPPER(@publisher) AND
  3808.               publisher_db = @publisher_db AND
  3809.               (@independent_agent=0 or publication = @publication))
  3810.               or @reserved = 'drop_all'
  3811.  
  3812.     END
  3813.  
  3814.  
  3815.     IF EXISTS(select * from sysobjects where type='U' and name = 'MSsubscription_properties')
  3816.     BEGIN
  3817.         DELETE FROM MSsubscription_properties 
  3818.         WHERE (UPPER(publisher) = UPPER(@publisher)    AND
  3819.         publisher_db  = @publisher_db AND
  3820.         publication = @publication) 
  3821.         or @reserved = 'drop_all'
  3822.  
  3823.         IF @@ERROR <> 0 
  3824.             GOTO UNDO
  3825.  
  3826.         IF NOT EXISTS (SELECT * FROM MSsubscription_properties)
  3827.         BEGIN
  3828.             DROP TABLE MSsubscription_properties
  3829.             IF @@ERROR <> 0 
  3830.                 GOTO UNDO
  3831.         END
  3832.     END
  3833.     
  3834.     return (0)
  3835.             
  3836. UNDO:
  3837.     return(1)
  3838. GO
  3839.  
  3840. --------------------------------------------------------------------------------
  3841. --. sp_vupgrade_subscription_database
  3842. --------------------------------------------------------------------------------
  3843. if exists (select * from sysobjects    where type = 'P'
  3844.     and name = 'sp_vupgrade_subscription_databases')
  3845.     drop procedure sp_vupgrade_subscription_databases
  3846. go
  3847.  
  3848. raiserror('Creating procedure sp_vupgrade_subscription_databases', 0,1)
  3849. GO
  3850. create procedure sp_vupgrade_subscription_databases
  3851. as
  3852.     declare @dbname sysname
  3853.  
  3854.     declare current_db CURSOR LOCAL FAST_FORWARD for 
  3855.         select quotename(name) from master..sysdatabases 
  3856.         for read only
  3857.  
  3858.     -- Note: dbname is quoted!
  3859.     open current_db
  3860.     fetch current_db into @dbname
  3861.     while ( @@fetch_status <> -1 )
  3862.     begin
  3863.         exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_mergetables')
  3864.         if @@ERROR<>0
  3865.             begin
  3866.                 close DC
  3867.                 deallocate DC
  3868.                 return (1)
  3869.             end
  3870.         exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_subscription_tables')
  3871.         if @@ERROR<>0
  3872.             begin
  3873.                 close DC
  3874.                 deallocate DC
  3875.                 return (1)
  3876.             end
  3877.         fetch next from current_db into @dbname
  3878.     end
  3879.     close current_db
  3880.     deallocate current_db
  3881. go
  3882.  
  3883. --------------------------------------------------------------------------------
  3884. --. sp_vupgrade_subscription_tables
  3885. --------------------------------------------------------------------------------
  3886. if exists (select * from sysobjects    where type = 'P'
  3887.     and name = 'sp_vupgrade_subscription_tables')
  3888.     drop procedure sp_vupgrade_subscription_tables
  3889. go
  3890.  
  3891. raiserror('Creating procedure sp_vupgrade_subscription_tables', 0,1)
  3892. GO
  3893. create procedure sp_vupgrade_subscription_tables
  3894. as
  3895.  
  3896. -- this raiserror makes sp_vupgrade_replication.out file easier to read
  3897. raiserror('sp_vupgrade_subscription_tables', 0,1)
  3898.  
  3899. DECLARE @table_name sysname
  3900.  
  3901. --    Create unique index on tables that did not have one previously. The index is not created
  3902. --    if duplicates rows exist in the table. 
  3903.  
  3904. --    MSreplication_subscriptions
  3905.     SELECT @table_name = N'MSreplication_subscriptions'
  3906.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSreplication_subscriptions' ) 
  3907.     BEGIN
  3908.         IF EXISTS ( SELECT publication, publisher_db, publisher, subscription_type 
  3909.             FROM MSreplication_subscriptions
  3910.             GROUP BY publication, publisher_db, publisher, subscription_type
  3911.             HAVING COUNT(*) > 1 )
  3912.             RAISERROR (21144, 10, 1, @table_name)
  3913.         ELSE
  3914.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'uc1MSReplication_subscriptions' AND
  3915.                 id = OBJECT_ID('MSreplication_subscriptions') )
  3916.                 CREATE UNIQUE CLUSTERED INDEX uc1MSReplication_subscriptions ON
  3917.                 MSreplication_subscriptions(publication, publisher_db, publisher, subscription_type)
  3918.     END
  3919.  
  3920.     
  3921. --    MSsubscription_properties
  3922.     SELECT @table_name = N'MSsubscription_properties'
  3923.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSsubscription_properties' ) 
  3924.     BEGIN
  3925.         IF EXISTS ( SELECT publication, publisher_db, publisher
  3926.             FROM MSsubscription_properties
  3927.             GROUP BY publication, publisher_db, publisher
  3928.             HAVING COUNT(*) > 1 )
  3929.             RAISERROR (21144, 10, 2, @table_name)
  3930.         ELSE
  3931.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'uc1MSsubscription_properties' AND
  3932.                 id = OBJECT_ID('MSsubscription_properties') )
  3933.                 CREATE UNIQUE CLUSTERED INDEX uc1MSsubscription_properties ON
  3934.                 MSsubscription_properties(publication, publisher_db, publisher)
  3935.     END
  3936.     
  3937. --    MSreplication_objects
  3938.     SELECT @table_name = N'MSreplication_objects'
  3939.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSreplication_objects' ) 
  3940.     BEGIN
  3941.         IF EXISTS ( SELECT object_name
  3942.             FROM MSreplication_objects
  3943.             GROUP BY object_name
  3944.             HAVING COUNT(*) > 1 )
  3945.             RAISERROR (21144, 10, 3, @table_name)
  3946.         ELSE    
  3947.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSreplication_objects' AND
  3948.                 id = OBJECT_ID('MSreplication_objects') )
  3949.                 CREATE UNIQUE CLUSTERED INDEX ucMSreplication_objects ON dbo.MSreplication_objects(object_name)
  3950.     END
  3951. go
  3952.  
  3953. --------------------------------------------------------------------------------
  3954. --. sp_vupgrade_mergetables
  3955. --------------------------------------------------------------------------------
  3956. if exists (select * from sysobjects    where type = 'P'
  3957.     and name = 'sp_vupgrade_mergetables')
  3958.     drop procedure sp_vupgrade_mergetables
  3959. go
  3960.  
  3961. raiserror('Creating procedure sp_vupgrade_mergetables', 0,1)
  3962. GO
  3963. create procedure sp_vupgrade_mergetables
  3964. as
  3965.  
  3966. -- this raiserror makes sp_vupgrade_replication.out file easier to read
  3967. raiserror('sp_vupgrade_mergetables', 0,1)
  3968.  
  3969.  
  3970. DECLARE @table_name sysname
  3971.  
  3972.  
  3973.     if (exists (select * from sysobjects where name = 'sysmergearticles'))
  3974.         begin
  3975.         -- Columns have been added to the sysmergearticles table
  3976.         if not exists (select * from syscolumns where id = object_id('sysmergearticles') and
  3977.                         name = 'gen_cur')
  3978.             begin
  3979.             alter table sysmergearticles add gen_cur int null
  3980.             if @@ERROR <> 0
  3981.                 return 1
  3982.             end
  3983.         if not exists (select * from syscolumns where id = object_id('sysmergearticles') and
  3984.                             name = 'before_image_objid')
  3985.             begin
  3986.             alter table sysmergearticles add before_image_objid    int    NULL
  3987.             if @@ERROR <> 0
  3988.                 return 1
  3989.             end
  3990.         if not exists (select * from syscolumns where id = object_id('sysmergearticles') and
  3991.                             name = 'before_view_objid')
  3992.             begin
  3993.             alter table sysmergearticles add before_view_objid    int    NULL
  3994.             if @@ERROR <> 0
  3995.                 return 1
  3996.             end
  3997.         end
  3998. --  MSmerge_contents    
  3999.     SELECT @table_name = N'MSmerge_contents'
  4000.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSmerge_contents' )
  4001.     BEGIN
  4002.         IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'nc3MSmerge_contents' AND
  4003.         id = OBJECT_ID('MSmerge_contents') )
  4004.                 create index nc3MSmerge_contents on MSmerge_contents(tablenick, partchangegen) 
  4005.         IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'nc4MSmerge_contents' AND
  4006.         id = OBJECT_ID('MSmerge_contents') )
  4007.                 create index nc4MSmerge_contents on MSmerge_contents(generation, partchangegen) 
  4008.     END
  4009.  
  4010. --    sysmergepublications
  4011.     SELECT @table_name = N'sysmergepublications'
  4012.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'sysmergepublications' )
  4013.     BEGIN 
  4014.         if not exists (select * from syscolumns where id = object_id('sysmergepublications')
  4015.             and name = 'keep_before_values')
  4016.         begin
  4017.         alter table sysmergepublications add keep_before_values int null
  4018.         if @@ERROR <> 0
  4019.             return 1
  4020.         end
  4021.  
  4022.         IF EXISTS ( SELECT pubid
  4023.             FROM sysmergepublications
  4024.             GROUP BY pubid
  4025.             HAVING COUNT(*) > 1 )
  4026.             RAISERROR (21144, 10, 4, @table_name)
  4027.         ELSE    
  4028.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'nc1sysmergepublications' AND
  4029.                 id = OBJECT_ID('sysmergepublications') )
  4030.             CREATE UNIQUE NONCLUSTERED INDEX nc1sysmergepublications
  4031.                 ON sysmergepublications(pubid)
  4032.     END
  4033.  
  4034. --    MSmerge_genhistory    
  4035.     SELECT @table_name = N'MSmerge_genhistory'
  4036.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSmerge_genhistory' )
  4037.     BEGIN
  4038.     -- Only create the index index if guidsrc values are unique. Before SP1 it was possible
  4039.     -- for this table to contain dup guidsrc. This happened when the genhistory table was empty to start 
  4040.     -- and we insert an initial row (for no article) and then try to insert a row for the first 
  4041.     -- article without generating a new guid.  
  4042.     
  4043.         IF EXISTS ( SELECT guidsrc, pubid 
  4044.             FROM MSmerge_genhistory 
  4045.             GROUP BY guidsrc, pubid 
  4046.             HAVING COUNT(*) > 1 )
  4047.             RAISERROR (21144, 10, 5, @table_name)
  4048.         ELSE            
  4049.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'nc3MSmerge_genhistory' AND
  4050.                 id = OBJECT_ID('MSmerge_genhistory') )
  4051.             CREATE UNIQUE NONCLUSTERED INDEX nc3MSmerge_genhistory ON MSmerge_genhistory(guidsrc, pubid)        
  4052.  
  4053.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'nc4MSmerge_genhistory' AND
  4054.                 id = OBJECT_ID('MSmerge_genhistory') )
  4055.             create  index nc4MSmerge_genhistory on MSmerge_genhistory(coldate) 
  4056.             
  4057.     END
  4058.     
  4059.  
  4060. --    MSmerge_delete_conflicts
  4061.     SELECT @table_name = N'MSmerge_delete_conflicts'
  4062.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSmerge_delete_conflicts' )
  4063.     BEGIN
  4064.         IF EXISTS ( SELECT tablenick, rowguid, origin_datasource
  4065.             FROM MSmerge_delete_conflicts
  4066.             GROUP BY tablenick, rowguid, origin_datasource
  4067.             HAVING COUNT(*) > 1 )
  4068.             RAISERROR (21144, 10, 6, @table_name)
  4069.         ELSE    
  4070.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'nc1MSmerge_delete_conflicts' AND
  4071.                 id = OBJECT_ID('MSmerge_delete_conflicts') )
  4072.                 CREATE UNIQUE NONCLUSTERED INDEX nc1MSmerge_delete_conflicts 
  4073.                     ON MSmerge_delete_conflicts(tablenick, rowguid, origin_datasource)
  4074.     END
  4075.     
  4076. --    sysmergeschemachange
  4077.     SELECT @table_name = N'sysmergeschemachange'
  4078.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'sysmergeschemachange' )
  4079.     BEGIN
  4080.         IF EXISTS ( SELECT schemaversion, pubid
  4081.             FROM sysmergeschemachange
  4082.             GROUP BY schemaversion, pubid
  4083.             HAVING COUNT(*) > 1 )
  4084.             RAISERROR (21144, 10, 7, @table_name)
  4085.         ELSE    
  4086.             BEGIN
  4087.                 IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'schemachangeversion' AND
  4088.                     id = OBJECT_ID('sysmergeschemachange') )            
  4089.                     DROP INDEX sysmergeschemachange.schemachangeversion
  4090.             
  4091.                 -- Recreate this index as unique clustered with one more field in index key.
  4092.                 CREATE UNIQUE CLUSTERED INDEX schemachangeversion ON sysmergeschemachange(schemaversion, pubid) 
  4093.             END
  4094.     END
  4095.     
  4096.  
  4097. --    sysmergesubsetfilters    
  4098.     SELECT @table_name = N'sysmergesubsetfilters'
  4099.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'sysmergesubsetfilters' )
  4100.     BEGIN
  4101.         IF EXISTS ( SELECT join_filterid
  4102.             FROM sysmergesubsetfilters
  4103.             GROUP BY join_filterid
  4104.             HAVING COUNT(*) > 1 )
  4105.             RAISERROR (21144, 10, 8, @table_name)
  4106.         ELSE    
  4107.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'nc1sysmergesubsetfilters' AND
  4108.                 id = OBJECT_ID('sysmergesubsetfilters') )
  4109.             CREATE UNIQUE NONCLUSTERED INDEX nc1sysmergesubsetfilters ON sysmergesubsetfilters(join_filterid, pubid)
  4110.     END    
  4111.  
  4112.  
  4113.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'sysmergepublications' )
  4114.     BEGIN 
  4115.     declare @artname sysname
  4116.     declare @pubname sysname
  4117.     declare @retcode int
  4118.  
  4119.     -- Must recreate the article procs for all articles that already have a select proc
  4120.     declare cur_articles CURSOR LOCAL FAST_FORWARD for 
  4121.         select a.name, p.name from sysmergearticles a, sysmergepublications p
  4122.             where a.select_proc is not null and a.pubid = p.pubid 
  4123.                 for read only
  4124.  
  4125.     open cur_articles 
  4126.     fetch cur_articles into @artname, @pubname
  4127.     while ( @@fetch_status <> -1 )
  4128.         begin
  4129.         exec @retcode = sp_MSsetartprocs @publication = @pubname,     @article = @artname, @force_flag = 1
  4130.         if @@ERROR <>0 OR @retcode <>0 return (1)
  4131.         fetch cur_articles into @artname, @pubname
  4132.         end
  4133.     close cur_articles 
  4134.     deallocate cur_articles 
  4135.     END
  4136. GO
  4137.  
  4138. --------------------------------------------------------------------------------
  4139. --. sp_vupgrade_replication
  4140. --------------------------------------------------------------------------------
  4141. if exists (select * from sysobjects    where type = 'P'
  4142.     and name = 'sp_vupgrade_replication')
  4143.     drop procedure sp_vupgrade_replication
  4144. go
  4145.  
  4146. raiserror('Creating procedure sp_vupgrade_replication', 0,1)
  4147. GO
  4148.  
  4149. create procedure sp_vupgrade_replication ( @login sysname = N'sa', @password sysname = N'', @ver_old int = 623, @security_mode bit = 0 )
  4150. as
  4151.  
  4152. -- this raiserror makes sp_vupgrade_replication.out file easier to read
  4153. raiserror('sp_vupgrade_replication', 0,1)
  4154.  
  4155. begin
  4156. /* 
  4157.  * Stub to handle possible need to modify or supplement replication metadata during setup 
  4158.  * initiated version upgrade from RTM to SP1. Any schema changes
  4159.  * to replication system tables may require modifications here to maintain upgrade path.
  4160.  * 
  4161.  * If server is a distributor, run new instdist.sql against all distribution dbs.
  4162.  * If version upgraded from is pre-Beta 3 OR @force_remove is true, do hard strip of replication.
  4163.  *
  4164.  * This proc gets called by setup at the end of an install over an existing version. 
  4165. */
  4166.  
  4167.     set nocount on 
  4168.  
  4169.     declare @dbname sysname
  4170.     declare @install_path nvarchar(255)
  4171.     declare @osql_cmd nvarchar(512)
  4172.     declare @osql_for_nt int
  4173.     declare @retcode int
  4174.     declare @platform_nt binary
  4175.     
  4176.     -- db bits
  4177.     declare @db_distbit int
  4178.  
  4179.     select @db_distbit = 16
  4180.  
  4181.     -- version check
  4182.     declare @ver_min             int
  4183.     
  4184.  
  4185.     select @platform_nt = 0x1
  4186.     select @ver_min= 623
  4187.     
  4188.  
  4189.     
  4190.         -- check for @ver_old < @ver_min and bailout if true. Should not even get 
  4191.         -- here since setup should have detected this earlier
  4192.     if ( @ver_old < @ver_min ) 
  4193.         return(1)
  4194.         
  4195.     else
  4196.     begin
  4197.  
  4198.         -- always need to run instdist.sql to update distribution databases on a distributor
  4199.         -- setup must restart in non-single user mode so we can shell out to run instdist.sql scripts
  4200.  
  4201.         if exists( select * from master..sysdatabases where category & @db_distbit = @db_distbit )
  4202.         begin
  4203.  
  4204.             -- get install_path
  4205.             exec @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
  4206.                       'SOFTWARE\Microsoft\MSSQLServer\Setup',
  4207.                       'SQLPath',
  4208.                     @param = @install_path OUTPUT
  4209.  
  4210.             if ( @retcode <> 0 ) or ( @install_path is null ) or ( @install_path = N'' )
  4211.             begin
  4212.                 return(1)
  4213.             end
  4214.             
  4215.             -- Set the flag for platform
  4216.             if (( platform() & @platform_nt = @platform_nt ))
  4217.                 select @osql_for_nt = 1
  4218.             else
  4219.                 select @osql_for_nt = 0
  4220.  
  4221.             declare cur_distdb CURSOR LOCAL FAST_FORWARD for 
  4222.                 select name from master..sysdatabases 
  4223.                     where category & @db_distbit = @db_distbit
  4224.                 for read only
  4225.             
  4226.             open cur_distdb
  4227.             fetch cur_distdb into @dbname
  4228.             while ( @@fetch_status <> -1 )
  4229.             begin
  4230.  
  4231.                 /*
  4232.                  * Format osql cmd line appropriate for security mode and OS to run instdist.sql against
  4233.                  * each distribution database. Instdist.sql will recompile procs and will also do some
  4234.                  * schema and metadata upgrade of changed replication tables. Query timeout increased to
  4235.                  * make enough time for alter tables in instdist.sql run for upgrade to complete.
  4236.                 */
  4237.                 if (@osql_for_nt = 1)
  4238.                     select @osql_cmd = '" "'
  4239.                 else
  4240.                     select @osql_cmd = ' "'
  4241.                      
  4242.                 -- Cannot specify -S w/ -E for local execution, SID does not map (nofix)
  4243.                 if ( @security_mode = 1 and @osql_for_nt = 1 )
  4244.                     select @osql_cmd = @osql_cmd + @install_path + '\binn\osql" -E '
  4245.                 else
  4246.                     select @osql_cmd = @osql_cmd + @install_path + '\binn\osql" -U' + isnull(@login, N'sa') + ' -P' + isnull(@password, N'') + ' -S' + @@SERVERNAME
  4247.  
  4248.                 select @osql_cmd = @osql_cmd + ' -l30 -t30 '
  4249.                 select @osql_cmd = @osql_cmd + ' -b ' + ' -d' + @dbname
  4250.                 select @osql_cmd = @osql_cmd +    ' -i' + '"' + @install_path + '\install\instdist.sql"' + 
  4251.                                                 ' -o' + '"' + @install_path + '\install\instdist.out"'            
  4252.  
  4253.                 if (@osql_for_nt = 1)
  4254.                     select @osql_cmd = @osql_cmd + ' "'
  4255.  
  4256.                  exec @retcode = master..xp_cmdshell @osql_cmd
  4257.                 if @retcode <> 0 or @@error <> 0
  4258.                 begin
  4259.                     raiserror (14113, 16, -1, @osql_cmd, 'instdist.out')
  4260.                 end
  4261.                 
  4262.                 -- now add unique indexes in this distribution database
  4263.                 exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_distdb')
  4264.                 if @@error <> 0
  4265.                     return(1)
  4266.  
  4267.                 fetch next from cur_distdb into @dbname
  4268.             end
  4269.             close cur_distdb
  4270.             deallocate cur_distdb
  4271.  
  4272.             -- Upgrade replication settings/tables in MSDB database
  4273.             -- ONLY FOR DISTRIBUTORS
  4274.             exec @retcode = msdb.dbo.sp_vupgrade_replmsdb
  4275.             if @retcode <> 0 or @@error <> 0
  4276.                     return (1)
  4277.  
  4278.         end
  4279.  
  4280.         -- Note: place calls to procs for any schema or metadata changes required in else block here
  4281.     
  4282.         -- Update subscription database schema. This will upgrade tran subscriber changes as well as ALL merge system tables 
  4283.         -- As of 1/26/99 there are no changes needed for tran publisher tables
  4284.  
  4285.         exec @retcode = dbo.sp_vupgrade_subscription_databases
  4286.         if @retcode <> 0 or @@error <> 0
  4287.             return (1)
  4288.         
  4289.     end
  4290.  
  4291.     return (0)
  4292.  
  4293. end
  4294. go
  4295.  
  4296. --------------------------------------------------------------------------------
  4297. --. sp_vupgrade_distdb
  4298. --------------------------------------------------------------------------------
  4299. if exists (select * from sysobjects    where type = 'P'
  4300.     and name = 'sp_vupgrade_distdb')
  4301.     drop procedure sp_vupgrade_distdb
  4302. go
  4303.  
  4304. raiserror('Creating procedure sp_vupgrade_distdb', 0,1)
  4305. go
  4306. create procedure sp_vupgrade_distdb 
  4307. as
  4308. /*
  4309. ** used to upgrade replication settings/tables in each distribution database
  4310. */
  4311.  
  4312. -- this raiserror makes sp_vupgrade_replication.out file easier to read
  4313. raiserror('sp_vupgrade_distdb', 0,1)
  4314.  
  4315.  
  4316. DECLARE @table_name sysname
  4317.  
  4318. --    MSrepl_version
  4319.     SELECT @table_name = N'MSrepl_version'
  4320.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSrepl_version' )
  4321.     BEGIN
  4322.         IF EXISTS ( SELECT major_version, minor_version, revision
  4323.             FROM MSrepl_version
  4324.             GROUP BY major_version, minor_version, revision
  4325.             HAVING COUNT(*) > 1 )
  4326.             RAISERROR (21144, 10, 9, @table_name)
  4327.         ELSE    
  4328.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSrepl_version' AND
  4329.                 id = OBJECT_ID('MSrepl_version') )
  4330.                 CREATE UNIQUE CLUSTERED INDEX ucMSrepl_version ON dbo.MSrepl_version
  4331.                     (major_version, minor_version, revision)
  4332.     END    
  4333.  
  4334.  
  4335. --    MSsnapshot_history
  4336.     SELECT @table_name = N'MSsnapshot_history'
  4337.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSsnapshot_history' )
  4338.     BEGIN
  4339.         IF EXISTS ( SELECT agent_id, timestamp, start_time, time
  4340.             FROM MSsnapshot_history
  4341.             GROUP BY agent_id, timestamp, start_time, time
  4342.             HAVING COUNT(*) > 1 )
  4343.             RAISERROR (21144, 10, 10, @table_name)
  4344.         ELSE        
  4345.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSsnapshot_history' AND 
  4346.                 id = OBJECT_ID('MSsnapshot_history'))
  4347.             BEGIN 
  4348.                 DROP INDEX dbo.MSsnapshot_history.ucMSsnapshot_history
  4349.                 CREATE UNIQUE CLUSTERED INDEX ucMSsnapshot_history ON dbo.MSsnapshot_history
  4350.                        (agent_id, timestamp, start_time, time)
  4351.             END
  4352.     END
  4353.  
  4354.  
  4355. --    MSlogreader_history
  4356.     SELECT @table_name = N'MSlogreader_history'
  4357.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSlogreader_history' )
  4358.     BEGIN
  4359.         IF EXISTS ( SELECT agent_id, timestamp, runstatus, start_time, time
  4360.             FROM MSlogreader_history
  4361.             GROUP BY agent_id, timestamp, runstatus, start_time, time
  4362.             HAVING COUNT(*) > 1 )
  4363.             RAISERROR (21144, 10, 11, @table_name)
  4364.         ELSE
  4365.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSlogreader_history' AND 
  4366.                 id = OBJECT_ID('MSlogreader_history'))
  4367.             BEGIN 
  4368.                 DROP INDEX dbo.MSlogreader_history.ucMSlogreader_history
  4369.                 CREATE UNIQUE CLUSTERED INDEX ucMSlogreader_history ON dbo.MSlogreader_history
  4370.                       (agent_id, timestamp, runstatus, start_time, time)
  4371.             END
  4372.     END
  4373.     
  4374.  
  4375. --    MSdistribution_history
  4376.     SELECT @table_name = N'MSdistribution_history'
  4377.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSdistribution_history' )
  4378.     BEGIN
  4379.         IF EXISTS ( SELECT agent_id, timestamp, runstatus, start_time, time
  4380.             FROM MSdistribution_history
  4381.             GROUP BY agent_id, timestamp, runstatus, start_time, time
  4382.             HAVING COUNT(*) > 1 )
  4383.             RAISERROR (21144, 10, 12, @table_name)
  4384.         ELSE
  4385.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSdistribution_history' AND 
  4386.                 id = OBJECT_ID('MSdistribution_history'))
  4387.             BEGIN 
  4388.                 DROP INDEX dbo.MSdistribution_history.ucMSdistribution_history
  4389.                 CREATE UNIQUE CLUSTERED INDEX ucMSdistribution_history ON dbo.MSdistribution_history
  4390.                  (agent_id, timestamp, runstatus, start_time, time)
  4391.             END
  4392.     END
  4393.     
  4394. --    MSmerge_history
  4395.     SELECT @table_name = N'MSmerge_history'
  4396.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSmerge_history' )
  4397.     BEGIN
  4398.         IF EXISTS ( SELECT agent_id, timestamp, runstatus, start_time, time
  4399.             FROM MSmerge_history
  4400.             GROUP BY agent_id, timestamp, runstatus, start_time, time
  4401.             HAVING COUNT(*) > 1 )
  4402.             RAISERROR (21144, 10, 13, @table_name)
  4403.         ELSE
  4404.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSmerge_history' AND 
  4405.                 id = OBJECT_ID('MSmerge_history'))
  4406.             BEGIN
  4407.                 DROP INDEX dbo.MSmerge_history.ucMSmerge_history
  4408.                 CREATE UNIQUE CLUSTERED INDEX ucMSmerge_history ON dbo.MSmerge_history
  4409.                   (agent_id, timestamp, runstatus, start_time, time)
  4410.             END
  4411.     END
  4412.     
  4413.  
  4414. --    MSsnapshot_agents
  4415.     SELECT @table_name = N'MSsnapshot_agents'
  4416.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSsnapshot_agents' )
  4417.     BEGIN
  4418.         IF EXISTS ( SELECT id
  4419.             FROM MSsnapshot_agents
  4420.             GROUP BY id
  4421.             HAVING COUNT(*) > 1 )
  4422.             RAISERROR (21144, 10, 14, @table_name)
  4423.         ELSE
  4424.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'iMSsnapshot_agents' AND 
  4425.                 id = OBJECT_ID('MSsnapshot_agents'))
  4426.             BEGIN
  4427.                 DROP INDEX dbo.MSsnapshot_agents.iMSsnapshot_agents
  4428.                 CREATE UNIQUE INDEX iMSsnapshot_agents ON dbo.MSsnapshot_agents    (id)
  4429.             END
  4430.     END
  4431.  
  4432. --    MSlogreader_agents
  4433.     SELECT @table_name = N'MSlogreader_agents'
  4434.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSlogreader_agents' )
  4435.     BEGIN
  4436.         IF EXISTS ( SELECT id
  4437.             FROM MSlogreader_agents
  4438.             GROUP BY id
  4439.             HAVING COUNT(*) > 1 )
  4440.             RAISERROR (21144, 10, 15, @table_name)
  4441.         ELSE
  4442.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'iMSlogreader_agents' AND 
  4443.                 id = OBJECT_ID('MSlogreader_agents'))
  4444.             BEGIN
  4445.                 DROP INDEX dbo.MSlogreader_agents.iMSlogreader_agents
  4446.                 CREATE UNIQUE INDEX iMSlogreader_agents ON dbo.MSlogreader_agents (id)
  4447.             END
  4448.     END
  4449.     
  4450. --    MSdistribution_agents
  4451.     SELECT @table_name = N'MSdistribution_agents'
  4452.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSdistribution_agents' )
  4453.     BEGIN
  4454.         IF EXISTS ( SELECT id
  4455.             FROM MSdistribution_agents
  4456.             GROUP BY id
  4457.             HAVING COUNT(*) > 1 )
  4458.             RAISERROR (21144, 10, 16, @table_name)
  4459.         ELSE
  4460.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSdistribution_agents' AND 
  4461.                 id = OBJECT_ID('MSdistribution_agents'))
  4462.             BEGIN
  4463.                 DROP INDEX dbo.MSdistribution_agents.ucMSdistribution_agents
  4464.                 CREATE UNIQUE CLUSTERED INDEX ucMSdistribution_agents ON dbo.MSdistribution_agents (id)
  4465.             END
  4466.     END
  4467.  
  4468.  
  4469. --    MSmerge_agents
  4470.     SELECT @table_name = N'MSmerge_agents'
  4471.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSmerge_agents' )
  4472.     BEGIN
  4473.         IF EXISTS ( SELECT id
  4474.             FROM MSmerge_agents
  4475.             GROUP BY id
  4476.             HAVING COUNT(*) > 1 )
  4477.             RAISERROR (21144, 10, 17, @table_name)
  4478.         ELSE
  4479.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'iMSmerge_agents' AND 
  4480.                 id = OBJECT_ID('MSmerge_agents'))
  4481.             BEGIN
  4482.                 DROP INDEX dbo.MSmerge_agents.iMSmerge_agents
  4483.                 CREATE UNIQUE INDEX iMSmerge_agents ON dbo.MSmerge_agents (id)
  4484.             END
  4485.     END
  4486.     
  4487.  
  4488. --    MSpublication_access
  4489.     SELECT @table_name = N'MSpublication_access'
  4490.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSpublication_access' )
  4491.     BEGIN
  4492.         IF EXISTS ( SELECT publication_id, login
  4493.             FROM MSpublication_access
  4494.             GROUP BY publication_id, login
  4495.             HAVING COUNT(*) > 1 )
  4496.             RAISERROR (21144, 10, 18, @table_name)
  4497.         ELSE
  4498.             IF EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSpublication_access' AND 
  4499.                 id = OBJECT_ID('MSpublication_access'))
  4500.             BEGIN
  4501.                 DROP INDEX dbo.MSpublication_access.ucMSpublication_access
  4502.                 CREATE UNIQUE CLUSTERED INDEX ucMSpublication_access ON dbo.MSpublication_access
  4503.                     (publication_id, login)
  4504.             END
  4505.     END
  4506. go
  4507.  
  4508. --------------------------------------------------------------------------------
  4509. --. sp_vupgrade_replmsdb
  4510. --------------------------------------------------------------------------------
  4511. if exists (select * from sysobjects    where type = 'P'
  4512.     and name = 'sp_vupgrade_replmsdb')
  4513.     drop procedure sp_vupgrade_replmsdb
  4514. go
  4515.  
  4516. raiserror('Creating procedure sp_vupgrade_replmsdb', 0,1)
  4517. go
  4518. create procedure sp_vupgrade_replmsdb 
  4519. as
  4520. /*
  4521. ** used to upgrade replication settings/tables in MSDB database
  4522. */
  4523.  
  4524. -- this raiserror makes sp_vupgrade_replication.out file easier to read
  4525. raiserror('sp_vupgrade_replmsdb', 0,1)
  4526.  
  4527.  
  4528.     DECLARE @table_name sysname
  4529.  
  4530.  
  4531. --    MSdistpublishers
  4532.     SELECT @table_name = N'MSdistpublishers'
  4533.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSdistpublishers' ) 
  4534.     BEGIN
  4535.         IF EXISTS ( SELECT name
  4536.             FROM MSdistpublishers
  4537.             GROUP BY name 
  4538.             HAVING COUNT(*) > 1 )
  4539.             RAISERROR (21144, 10, 19, @table_name)
  4540.         ELSE
  4541.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'uc1MSdistpublishers' AND
  4542.                 id = OBJECT_ID('MSdistpublishers') )
  4543.                 CREATE UNIQUE CLUSTERED INDEX uc1MSdistpublishers ON msdb.dbo.MSdistpublishers(name)
  4544.     END
  4545.     
  4546. --    MSdistributiondbs
  4547.     SELECT @table_name = N'MSdistributiondbs'
  4548.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSdistributiondbs' )
  4549.     BEGIN
  4550.         IF EXISTS ( SELECT name
  4551.             FROM MSdistributiondbs
  4552.             GROUP BY name 
  4553.             HAVING COUNT(*) > 1 )
  4554.             RAISERROR (21144, 10, 20, @table_name)            
  4555.         ELSE                
  4556.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'uc1MSdistributiondbs' AND
  4557.                 id = OBJECT_ID('MSdistributiondbs') )
  4558.                 CREATE UNIQUE CLUSTERED INDEX uc1MSdistributiondbs ON msdb.dbo.MSdistributiondbs(name)
  4559.     END
  4560.     
  4561. --    MSdistributor
  4562.     SELECT @table_name = N'MSdistributor'
  4563.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSdistributor' )
  4564.     BEGIN
  4565.         IF EXISTS ( SELECT property
  4566.             FROM MSdistributor
  4567.             GROUP BY property 
  4568.             HAVING COUNT(*) > 1 )
  4569.             RAISERROR (21144, 10, 21, @table_name)            
  4570.         ELSE                    
  4571.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'uc1MSdistributor' AND
  4572.                 id = OBJECT_ID('MSdistributor') )
  4573.                 CREATE UNIQUE CLUSTERED INDEX uc1MSdistributor ON msdb.dbo.MSdistributor(property)
  4574.     END    
  4575. go
  4576.  
  4577. --------------------------------------------------------------------------------
  4578. --. sp_restoredbreplication
  4579. --------------------------------------------------------------------------------
  4580. if exists (select * from sysobjects    where type = 'P'
  4581.     and name = 'sp_restoredbreplication')
  4582.     drop procedure sp_restoredbreplication
  4583. go
  4584.  
  4585. raiserror('Creating procedure sp_restoredbreplication', 0,1)
  4586. go
  4587.  
  4588. create procedure sp_restoredbreplication ( @srv_orig sysname, @db_orig sysname )
  4589. as 
  4590. /*
  4591.  * used by restore process to strip out replication settings if restoring to non-originating
  4592.  * server/db or system otherwise not capable of keeping replication working
  4593.  * WARNING : procs called here run internal to server and must be owner qualified
  4594. */
  4595. begin
  4596.  
  4597.     set nocount on
  4598.  
  4599.     -- db bits
  4600.     declare @db_tranbit int
  4601.     declare @db_mergbit int
  4602.     declare @db_distbit int
  4603.     select @db_tranbit = 1, @db_mergbit = 4, @db_distbit = 16
  4604.  
  4605.     declare @repl_installed bit -- repl procs installed flag
  4606.     declare @remove_repl bit    -- remove replication flag ; remove on true (1)
  4607.     declare @restoreoverride int
  4608.     declare @db_curr sysname
  4609.     DECLARE @retcode int
  4610.     DECLARE @proc nvarchar(255)
  4611.  
  4612.     -- Support override of replication remove on attach and restore
  4613.     select @proc = 'master.dbo.xp_regread '
  4614.     execute @retcode = @proc    'HKEY_LOCAL_MACHINE', 
  4615.                                 'SOFTWARE\Microsoft\MSSQLServer\Replication',
  4616.                                 'RestoreOverride',
  4617.                                 @param = @restoreoverride output,
  4618.                                 @no_output = 'no_output'
  4619.  
  4620.     if ( @@error = 0 ) and ( @retcode = 0 )
  4621.     begin
  4622.         -- ReplRestoreOverride = 1 = user elects to take no cleanup on restore or attach
  4623.         if ( isnull( @restoreoverride, 0 ) = 1 )
  4624.             return(0)
  4625.     end
  4626.     
  4627.         
  4628.     select @remove_repl = 0, @repl_installed = 1 
  4629.  
  4630.     select @db_curr = db_name() 
  4631.  
  4632.     -- check server has replication installed; if not, we cannot remove replication; this should be benign
  4633.     if not exists ( select * from master..MSreplication_options 
  4634.                         where optname = 'transactional' 
  4635.                            or optname = 'merge' )
  4636.         select @repl_installed = 0
  4637.  
  4638.     -- check restore to same server/db backed up
  4639.     if ( UPPER(@srv_orig) <> UPPER(@@SERVERNAME) ) or ( @db_orig <> @db_curr ) 
  4640.         select @remove_repl = 1
  4641.  
  4642.     -- subscribing dbs are assumed ok
  4643.     -- distribution dbs are assumed ok
  4644.  
  4645.     -- publishing db check : transactional : requires coordinated restore of dist db - no way to check
  4646.     if ( 
  4647.             exists( select * from sysobjects where name = 'syspublications' )
  4648.             -- exists( select * from syspublications ) 
  4649.             and not exists( select * from master..sysdatabases 
  4650.                 where name = @db_orig and category & @db_tranbit = @db_tranbit )
  4651.         )
  4652.     begin
  4653.         -- publications exist in db, but db on server is not published; 
  4654.         -- unpublish the db, ignoring distributor cleanup
  4655.  
  4656.         update master.dbo.sysdatabases set category = category | @db_tranbit where name = @db_curr
  4657.         exec dbo.sp_MSpublishdb 'false', 1
  4658.         update master.dbo.sysdatabases set category = category & ~@db_tranbit where name = @db_curr
  4659.  
  4660.         -- we've already brute force stripped replication from the db, 
  4661.         -- don't call sp_removedbreplication at proc exit
  4662.  
  4663.     end
  4664.  
  4665.     if ( @repl_installed = 1 ) and ( @remove_repl = 1 ) 
  4666.         exec dbo.sp_removedbreplication @db_curr
  4667.  
  4668.  
  4669. end
  4670. go
  4671.  
  4672. --------------------------------------------------------------------------------
  4673. --. sp_MScreate_sub_tables
  4674. --------------------------------------------------------------------------------
  4675. if exists (select * from sysobjects    where type = 'P'
  4676.     and name = 'sp_MScreate_sub_tables')
  4677.     drop procedure sp_MScreate_sub_tables
  4678. go
  4679.  
  4680. raiserror('Creating procedure sp_MScreate_sub_tables', 0,1)
  4681. GO
  4682.  
  4683. CREATE PROCEDURE sp_MScreate_sub_tables (
  4684. @tran_sub_table bit = 0,
  4685. @property_table bit = 1
  4686. )
  4687. as
  4688.     set nocount on
  4689.     declare @retcode int
  4690.  
  4691.     IF @tran_sub_table = 1 and
  4692.         (NOT EXISTS (SELECT * FROM sysobjects WHERE 
  4693.         type = 'U' AND name = 'MSreplication_subscriptions')) 
  4694.     BEGIN
  4695.         CREATE TABLE dbo.MSreplication_subscriptions
  4696.         (
  4697.         publisher sysname NOT NULL,
  4698.         publisher_db sysname NOT NULL, 
  4699.         publication sysname NULL, 
  4700.         independent_agent bit NOT NULL,
  4701.         subscription_type int NOT NULL,
  4702.         distribution_agent nvarchar (100) NULL, 
  4703.         time smalldatetime NOT NULL,
  4704.         description nvarchar(255) NULL,
  4705.         transaction_timestamp varbinary(16) NOT NULL,
  4706.         -- SyncTran
  4707.         update_mode tinyint NOT NULL,
  4708.         agent_id binary(16) NULL,
  4709.         subscription_guid binary(16) NULL,
  4710.         subid binary(16) NULL,
  4711.         immediate_sync bit NOT NULL default 1 -- sync_mode with a default of 1
  4712.         )
  4713.         IF @@ERROR <> 0
  4714.             GOTO UNDO
  4715.  
  4716.         CREATE UNIQUE CLUSTERED INDEX uc1MSReplication_subscriptions ON
  4717.                         MSreplication_subscriptions(publication, publisher_db, publisher, subscription_type)
  4718.         IF @@ERROR <> 0
  4719.             GOTO UNDO
  4720.  
  4721.          EXEC dbo.sp_MS_marksystemobject 'MSreplication_subscriptions'
  4722.          IF @@ERROR <> 0
  4723.             GOTO UNDO
  4724.     END    
  4725.  
  4726.     IF @property_table = 1 and
  4727.         NOT EXISTS (SELECT * FROM sysobjects WHERE 
  4728.         type = 'U' AND
  4729.         name = 'MSsubscription_properties')
  4730.     BEGIN
  4731.         BEGIN TRAN
  4732.  
  4733.         CREATE TABLE dbo.MSsubscription_properties
  4734.         (
  4735.         publisher                        sysname        NOT NULL,
  4736.         publisher_db                    sysname        NOT NULL,
  4737.         publication                        sysname        NOT NULL,
  4738.         publication_type                int            NOT NULL,
  4739.         publisher_login                    sysname        NULL,
  4740.         publisher_password                sysname        NULL,
  4741.         publisher_security_mode            int            NOT NULL,
  4742.         distributor                        sysname        NULL,
  4743.         distributor_login                sysname        NULL,
  4744.         distributor_password            sysname        NULL,
  4745.         distributor_security_mode        int            NOT NULL,
  4746.         ftp_address                        sysname        NULL,
  4747.         ftp_port                        int            NULL,
  4748.         ftp_login                        sysname        NULL,
  4749.         ftp_password                    sysname        NULL,
  4750.         )
  4751.         IF @@ERROR <> 0
  4752.             GOTO UNDO
  4753.  
  4754.         CREATE UNIQUE CLUSTERED INDEX uc1MSsubscription_properties ON
  4755.                         MSsubscription_properties(publication, publisher_db, publisher)
  4756.         IF @@ERROR <> 0
  4757.             GOTO UNDO
  4758.         
  4759.         EXEC @retcode = dbo.sp_MS_marksystemobject 'MSsubscription_properties'
  4760.         if @retcode <> 0 or @@error <> 0
  4761.             GOTO UNDO
  4762.  
  4763.         COMMIT TRAN
  4764.     end
  4765.  
  4766.     return(0)
  4767.     
  4768. UNDO:
  4769.     IF @@TRANCOUNT = 1
  4770.         ROLLBACK TRAN
  4771.     ELSE
  4772.         COMMIT TRAN  
  4773.     return(1) 
  4774. go
  4775. grant execute on sp_MScreate_sub_tables to public
  4776. go
  4777.  
  4778. --------------------------------------------------------------------------------
  4779. --. sp_MSregistersubscription
  4780. --------------------------------------------------------------------------------
  4781. if exists (select * from sysobjects    where type = 'P'
  4782.     and name = 'sp_MSregistersubscription')
  4783.     drop procedure sp_MSregistersubscription
  4784. go
  4785.  
  4786. raiserror('Creating procedure sp_MSregistersubscription', 0,1)
  4787. go
  4788.  
  4789. CREATE PROCEDURE sp_MSregistersubscription (
  4790.     @replication_type            int, /* Transactional = 1, Merge = 2 */
  4791.     @publisher                     sysname,
  4792.     @publisher_db                 sysname,
  4793.     @publisher_security_mode    int = NULL,                        /* 0 standard; 1 integrated */
  4794.     @publisher_login            sysname = NULL,
  4795.     @publisher_password    sysname = NULL,
  4796.     @publication                 sysname,         
  4797.     @subscriber                 sysname,
  4798.     @subscriber_db                 sysname,
  4799.     @subscriber_security_mode    int = NULL,                        /* 0 standard; 1 integrated */
  4800.     @subscriber_login            sysname = NULL,
  4801.     @subscriber_password    sysname = NULL,
  4802.     @distributor                 sysname,
  4803.     @distributor_security_mode     int = NULL,
  4804.     @distributor_login             sysname = NULL,
  4805.     @distributor_password    sysname = NULL,
  4806.     @subscription_id            uniqueidentifier ,
  4807.     @independent_agent            int = NULL,
  4808.     @subscription_type            int
  4809.     ) AS
  4810.  
  4811.     SET NOCOUNT ON
  4812.  
  4813.     /* MobileSync Support */
  4814.     declare @subscription_name                nvarchar(1000)
  4815.     declare @regkey                            nvarchar(1000)
  4816.     declare @subidstr                        nvarchar(38)
  4817.     declare @profile_name                     nvarchar(100)
  4818.     declare @retcode                        int
  4819.     declare @publisher_encrypted_password    sysname
  4820.     declare @subscriber_encrypted_password    sysname
  4821.     declare @distributor_encrypted_password    sysname
  4822.     declare @temp_binary_password            varbinary(256)
  4823.  
  4824.     set @subscription_name = @publisher + ':' + @publisher_db + ':' + @publication + ':' + @subscriber + ':' + @subscriber_db
  4825.     /* Replace back slash with forward slash so that the key name is a valid REGISTRY key name */
  4826.     set @subscription_name = REPLACE(@subscription_name,'\','/')
  4827.     set @regkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\' + @subscription_name
  4828.     set @subidstr = '{' + convert ( nchar(36), @subscription_id) + '}'
  4829.     set @profile_name = formatmessage(20550) -- SyncMgr Profile
  4830.  
  4831.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4832.                                @regkey,
  4833.                                'ProfileName',
  4834.                                'REG_SZ',
  4835.                                 @profile_name    
  4836.     if @retcode <> 0 OR @@ERROR <> 0
  4837.         return 1
  4838.  
  4839.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4840.                                @regkey,
  4841.                                'ReplicationType',
  4842.                                'REG_DWORD',
  4843.                                 @replication_type    
  4844.     if @retcode <> 0 OR @@ERROR <> 0
  4845.         return 1
  4846.  
  4847.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4848.                                @regkey,
  4849.                                'SubscriptionType',
  4850.                                'REG_DWORD',
  4851.                                 @subscription_type    
  4852.     if @retcode <> 0 OR @@ERROR <> 0
  4853.         return 1
  4854.  
  4855.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4856.                                @regkey,
  4857.                                'Subid',
  4858.                                'REG_SZ',
  4859.                                 @subidstr    
  4860.     if @retcode <> 0 OR @@ERROR <> 0
  4861.         return 1
  4862.  
  4863.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4864.                                @regkey,
  4865.                                'Publisher',
  4866.                                'REG_SZ',
  4867.                                 @publisher                                        
  4868.     if @retcode <> 0 OR @@ERROR <> 0
  4869.         return 1
  4870.  
  4871.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4872.                                @regkey,
  4873.                                'PublisherDb',
  4874.                                'REG_SZ',
  4875.                                 @publisher_db
  4876.     if @retcode <> 0 OR @@ERROR <> 0
  4877.         return 1
  4878.  
  4879.     /* If Publisher security mode is NOT NULL, write out the entries */
  4880.     if @publisher_security_mode IS NOT NULL
  4881.         begin
  4882.                EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4883.                                        @regkey,
  4884.                                        'PublisherSecurityMode',
  4885.                                        'REG_DWORD',
  4886.                                         @publisher_security_mode
  4887.             if @retcode <> 0 OR @@ERROR <> 0
  4888.                 return 1
  4889.  
  4890.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4891.                                        @regkey,
  4892.                                        'PublisherLogin',
  4893.                                        'REG_SZ',
  4894.                                         @publisher_login                                    
  4895.             if @retcode <> 0 OR @@ERROR <> 0
  4896.                 return 1
  4897.  
  4898.             /* Encrypt the password before writing to the registry */
  4899.             set @publisher_encrypted_password = @publisher_password
  4900.             exec @retcode = master.dbo.xp_repl_encrypt @publisher_encrypted_password OUTPUT
  4901.             if @retcode <> 0 OR @@ERROR <> 0
  4902.                 return 1
  4903.  
  4904.             select @temp_binary_password = convert(varbinary(256), @publisher_encrypted_password)
  4905.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4906.                                        @regkey,
  4907.                                        'PublisherEncryptedPasswordBinary',
  4908.                                        'REG_BINARY',
  4909.                                         @temp_binary_password
  4910.             if @retcode <> 0 OR @@ERROR <> 0
  4911.                 return 1
  4912.  
  4913.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4914.                                        @regkey,
  4915.                                        'PublisherEncryptedPassword',
  4916.                                        'REG_SZ',
  4917.                                         @publisher_encrypted_password
  4918.             if @retcode <> 0 OR @@ERROR <> 0
  4919.                 return 1
  4920.         end
  4921.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4922.                                @regkey,
  4923.                                'Publication',
  4924.                                'REG_SZ',
  4925.                                 @publication
  4926.     if @retcode <> 0 OR @@ERROR <> 0
  4927.         return 1
  4928.  
  4929.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4930.                                @regkey,
  4931.                                'Subscriber',
  4932.                                'REG_SZ',
  4933.                                 @subscriber
  4934.     if @retcode <> 0 OR @@ERROR <> 0
  4935.         return 1
  4936.  
  4937.     /* If Subscriber security mode is NOT NULL, write out the entries */
  4938.     if @subscriber_security_mode IS NOT NULL
  4939.         begin
  4940.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4941.                                @regkey,
  4942.                                'SubscriberSecurityMode',
  4943.                                'REG_DWORD',
  4944.                                 @subscriber_security_mode
  4945.             if @retcode <> 0 OR @@ERROR <> 0
  4946.                 return 1
  4947.  
  4948.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4949.                                @regkey,
  4950.                                'SubscriberLogin',
  4951.                                'REG_SZ',
  4952.                                 @subscriber_login                                    
  4953.             if @retcode <> 0 OR @@ERROR <> 0
  4954.                 return 1
  4955.  
  4956.             /* Encrypt the password before writing to the registry */
  4957.             set @subscriber_encrypted_password = @subscriber_password
  4958.             exec @retcode = master.dbo.xp_repl_encrypt @subscriber_encrypted_password OUTPUT
  4959.             if @retcode <> 0 OR @@ERROR <> 0
  4960.                 return 1
  4961.  
  4962.             select @temp_binary_password = convert(varbinary(256), @subscriber_encrypted_password)
  4963.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4964.                                @regkey,
  4965.                                'SubscriberEncryptedPasswordBinary',
  4966.                                'REG_BINARY',
  4967.                                 @temp_binary_password
  4968.             if @retcode <> 0 OR @@ERROR <> 0
  4969.                 return 1
  4970.  
  4971.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4972.                                @regkey,
  4973.                                'SubscriberEncryptedPassword',
  4974.                                'REG_SZ',
  4975.                                 @subscriber_encrypted_password
  4976.             if @retcode <> 0 OR @@ERROR <> 0
  4977.                 return 1
  4978.         end
  4979.  
  4980.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4981.                                @regkey,
  4982.                                'SubscriberDb',
  4983.                                'REG_SZ',
  4984.                                 @subscriber_db                                    
  4985.     if @retcode <> 0 OR @@ERROR <> 0
  4986.         return 1
  4987.                 
  4988.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  4989.                                @regkey,
  4990.                                'Distributor',
  4991.                                'REG_SZ',
  4992.                                 @distributor
  4993.     if @retcode <> 0 OR @@ERROR <> 0
  4994.         return 1
  4995.  
  4996.     /* If Distributor security mode is NOT NULL, write out the entries */
  4997.     if @distributor_security_mode IS NOT NULL
  4998.         begin
  4999.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  5000.                                @regkey,
  5001.                                'DistributorSecurityMode',
  5002.                                'REG_DWORD',
  5003.                                 @distributor_security_mode
  5004.             if @retcode <> 0 OR @@ERROR <> 0
  5005.                 return 1
  5006.  
  5007.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  5008.                                @regkey,
  5009.                                'DistributorLogin',
  5010.                                'REG_SZ',
  5011.                                 @distributor_login                                    
  5012.             if @retcode <> 0 OR @@ERROR <> 0
  5013.                 return 1
  5014.  
  5015.             /* Encrypt the password before writing to the registry */
  5016.             set @distributor_encrypted_password = @distributor_password
  5017.             exec @retcode = master.dbo.xp_repl_encrypt @distributor_encrypted_password OUTPUT
  5018.             if @retcode <> 0 OR @@ERROR <> 0
  5019.                 return 1
  5020.  
  5021.             select @temp_binary_password = convert(varbinary(256), @distributor_encrypted_password)
  5022.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  5023.                                @regkey,
  5024.                                'DistributorEncryptedPasswordBinary',
  5025.                                'REG_BINARY',
  5026.                                 @temp_binary_password
  5027.             if @retcode <> 0 OR @@ERROR <> 0
  5028.                 return 1
  5029.  
  5030.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  5031.                                @regkey,
  5032.                                'DistributorEncryptedPassword',
  5033.                                'REG_SZ',
  5034.                                 @distributor_encrypted_password
  5035.             if @retcode <> 0 OR @@ERROR <> 0
  5036.                 return 1
  5037.         end
  5038.     if @independent_agent IS NOT NULL
  5039.         begin
  5040.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  5041.                                @regkey,
  5042.                                'IndependentAgent',
  5043.                                'REG_DWORD',
  5044.                                 @independent_agent    
  5045.             if @retcode <> 0 OR @@ERROR <> 0
  5046.                 return 1
  5047.         end                
  5048.     return 0
  5049. GO
  5050.  
  5051. --------------------------------------------------------------------------------
  5052. --.    Common repl objects (replcom.sql)
  5053. --------------------------------------------------------------------------------
  5054. dump tran master with no_log
  5055. go
  5056.  
  5057. --------------------------------------------------------------------------------
  5058. --. sp_MScreate_distributor_tables
  5059. --------------------------------------------------------------------------------
  5060. if exists (select * from sysobjects    where type = 'P'
  5061.     and name = 'sp_MScreate_distributor_tables')
  5062.     drop procedure sp_MScreate_distributor_tables
  5063. go
  5064.  
  5065. raiserror('Creating procedure sp_MScreate_distributor_tables', 0,1)
  5066. GO
  5067.  
  5068. create procedure sp_MScreate_distributor_tables
  5069. as
  5070.     declare @profile_id     int
  5071.     declare @retcode    int
  5072.     declare @profile_name nvarchar(100)
  5073.     declare @profile_desc nvarchar(100)
  5074.  
  5075.     /* Create MSpublishers table */
  5076.     IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSdistpublishers'
  5077.         and xtype = 'U')
  5078.     begin
  5079.         DROP TABLE msdb..MSdistpublishers
  5080.         if @@error<> 0 goto FAILURE
  5081.     end
  5082.  
  5083.     /* Create MSdistributiondbs table */
  5084.     IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSdistributiondbs'
  5085.         and xtype = 'U')
  5086.     begin
  5087.         DROP TABLE msdb..MSdistributiondbs
  5088.         if @@error<> 0 goto FAILURE
  5089.     end
  5090.  
  5091.     /* create MSdistributor table */
  5092.     IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSdistributor'
  5093.         and xtype = 'U')
  5094.     begin
  5095.         DROP TABLE msdb..MSdistributor
  5096.         if @@error<> 0 goto FAILURE
  5097.     end
  5098.  
  5099.     /* create sysreplicationalerts table */
  5100.     IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'sysreplicationalerts'
  5101.         and xtype = 'U')
  5102.     begin
  5103.         DROP TABLE msdb..sysreplicationalerts
  5104.         if @@error<> 0 goto FAILURE
  5105.     end
  5106.     
  5107.     /* create MSagent_profiles table */
  5108.     IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSagent_profiles'
  5109.         and xtype = 'U')
  5110.     begin
  5111.         DROP TABLE msdb..MSagent_profiles
  5112.         if @@error<> 0 goto FAILURE
  5113.     end
  5114.  
  5115.     /* create MSagent_parameters table */
  5116.     IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSagent_parameters' 
  5117.         and xtype = 'U')
  5118.     begin
  5119.         DROP TABLE msdb..MSagent_parameters
  5120.         if @@error<> 0 goto FAILURE
  5121.     end
  5122.  
  5123.     /* create MSdatatype_mappings table */
  5124.     IF EXISTS (SELECT * FROM msdb..sysobjects WHERE name = 'MSdatatype_mappings' 
  5125.         and xtype = 'U')
  5126.     begin
  5127.         DROP TABLE msdb..MSdatatype_mappings
  5128.         if @@error<> 0 goto FAILURE
  5129.     end
  5130.  
  5131.     
  5132.     CREATE TABLE msdb.dbo.MSdistpublishers
  5133.     (
  5134.         name                sysname     NOT NULL,
  5135.         distribution_db     sysname     NOT NULL,
  5136.         working_directory   nvarchar(255) NOT NULL,
  5137.         security_mode       int         NOT NULL,
  5138.         login               sysname     NOT NULL,
  5139.         password            sysname     NULL,
  5140.         active              bit         NOT NULL,
  5141.         trusted             bit         NOT NULL,
  5142.         thirdparty_flag     bit         NOT NULL
  5143.     )
  5144.     if @@error<> 0 goto FAILURE
  5145.  
  5146.     CREATE UNIQUE CLUSTERED INDEX uc1MSdistpublishers ON msdb.dbo.MSdistpublishers(name)
  5147.     if @@error<> 0 goto FAILURE
  5148.  
  5149.     CREATE TABLE msdb.dbo.MSdistributiondbs
  5150.     (
  5151.         name                sysname NOT NULL,
  5152.         min_distretention   int     NOT NULL,
  5153.         max_distretention   int     NOT NULL,
  5154.         history_retention   int     NOT NULL
  5155.     )
  5156.     if @@error<> 0 goto FAILURE
  5157.  
  5158.     CREATE UNIQUE CLUSTERED INDEX uc1MSdistributiondbs ON msdb.dbo.MSdistributiondbs(name)
  5159.     if @@error<> 0 goto FAILURE
  5160.  
  5161.     CREATE TABLE msdb.dbo.MSdistributor 
  5162.     ( 
  5163.         property        sysname     NOT NULL, 
  5164.         value           nvarchar(3000)  NULL
  5165.     )
  5166.     if @@error<> 0 goto FAILURE
  5167.  
  5168.     CREATE UNIQUE CLUSTERED INDEX uc1MSdistributor ON msdb.dbo.MSdistributor(property)
  5169.     if @@error<> 0 goto FAILURE
  5170.  
  5171.     CREATE TABLE msdb.dbo.sysreplicationalerts
  5172.     (
  5173.         alert_id            int identity(1,1) NOT NULL,
  5174.         status              int NOT NULL,
  5175.         agent_type          int NULL,
  5176.         agent_id            int NULL,
  5177.         error_id            int NULL,
  5178.         alert_error_code    int NULL,
  5179.         time                datetime NOT NULL,
  5180.         publisher           sysname NULL,
  5181.         publisher_db        sysname NULL,
  5182.         publication         sysname NULL,
  5183.         publication_type    int NULL,
  5184.         subscriber          sysname NULL,
  5185.         subscriber_db       sysname NULL,
  5186.         article             sysname NULL,
  5187.         destination_object  sysname NULL,
  5188.         source_object       sysname NULL,
  5189.         alert_error_text    ntext NULL
  5190.     )
  5191.     if @@error<> 0 goto FAILURE
  5192.  
  5193.     CREATE UNIQUE CLUSTERED INDEX ucsysreplicationalerts ON msdb.dbo.sysreplicationalerts(alert_id)
  5194.     if @@error<> 0 goto FAILURE
  5195.  
  5196.     CREATE TABLE msdb.dbo.MSagent_profiles
  5197.     (
  5198.         profile_id    int           NOT NULL IDENTITY,
  5199.         profile_name  sysname       NOT NULL,
  5200.         agent_type          int             NOT NULL, -- 1-Snapshot, 2-Logreader,
  5201.                                                       -- 3-Distribution, 4-Merge
  5202.         type                int             NOT NULL, -- 0-System, 1-Custom
  5203.         description         nvarchar(3000)  NULL,
  5204.         def_profile   bit               NOT NULL
  5205.     )
  5206.     if @@error<> 0 goto FAILURE
  5207.  
  5208.  
  5209.     CREATE UNIQUE CLUSTERED INDEX ucMSagent_profiles ON msdb.dbo.MSagent_profiles
  5210.         (profile_name, profile_id, agent_type)
  5211.     if @@error<> 0 goto FAILURE
  5212.  
  5213.     CREATE TABLE msdb.dbo.MSagent_parameters
  5214.     (
  5215.         profile_id     int          NOT NULL,
  5216.         parameter_name       sysname        NOT NULL,
  5217.         value                nvarchar(255)  NOT NULL
  5218.     )
  5219.     if @@error<> 0 goto FAILURE
  5220.  
  5221.     CREATE UNIQUE CLUSTERED INDEX ucMSagent_parameters ON msdb.dbo.MSagent_parameters
  5222.         (parameter_name, profile_id)
  5223.     if @@error<> 0 goto FAILURE
  5224.  
  5225.     /* 
  5226.     ** Create default / non default profiles 
  5227.     ** for all the agents 
  5228.     */
  5229.  
  5230.     /* 
  5231.     ** Snapshot agent 
  5232.     */
  5233.     set @profile_id = NULL
  5234.     set @profile_name = formatmessage(20545) -- Default Snapshot Profile
  5235.     set @profile_desc = NULL
  5236.  
  5237.     exec @retcode = dbo.sp_add_agent_profile
  5238.             @profile_id = @profile_id OUT,
  5239.             @profile_name = @profile_name,
  5240.             @agent_type = 1,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  5241.             @profile_type = 0,   -- 0-System, 1-Custom 
  5242.             @description = @profile_desc,
  5243.             @default = 1
  5244.     if (@retcode = 1 or @@ERROR <> 0)
  5245.         goto FAILURE
  5246.  
  5247.     exec @retcode = dbo.sp_generate_agent_parameter @profile_id
  5248.     if (@retcode = 1 or @@ERROR <> 0)
  5249.         goto FAILURE
  5250.  
  5251.     /* 
  5252.     ** Logreader agent 
  5253.     */
  5254.     set @profile_id = NULL
  5255.     set @profile_name = formatmessage(20545) -- Default LogReader Profile
  5256.     set @profile_desc = NULL
  5257.  
  5258.     exec @retcode = dbo.sp_add_agent_profile
  5259.             @profile_id = @profile_id OUT,
  5260.             @profile_name = @profile_name,
  5261.             @agent_type = 2,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  5262.             @profile_type = 0,   -- 0-System, 1-Custom 
  5263.             @description = @profile_desc,
  5264.             @default = 1
  5265.     if (@retcode = 1 or @@ERROR <> 0)
  5266.         goto FAILURE
  5267.  
  5268.     exec @retcode = dbo.sp_generate_agent_parameter @profile_id
  5269.     if (@retcode = 1 or @@ERROR <> 0)
  5270.         goto FAILURE
  5271.  
  5272.     /* 
  5273.     ** Logreader agent - Verbose History Profile
  5274.     */
  5275.     set @profile_id = NULL
  5276.     set @profile_name = formatmessage(20546) -- LogReader Verbose History Profile
  5277.     set @profile_desc = formatmessage(20547)
  5278.  
  5279.     exec @retcode = dbo.sp_add_agent_profile
  5280.             @profile_id = @profile_id OUT,
  5281.             @profile_name = @profile_name,
  5282.             @agent_type = 2,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  5283.             @profile_type = 0,   -- 0-System, 1-Custom 
  5284.             @description = @profile_desc,
  5285.             @default = 0
  5286.     if (@retcode = 1 or @@ERROR <> 0)
  5287.         goto FAILURE
  5288.  
  5289.     exec @retcode = dbo.sp_generate_agent_parameter @profile_id
  5290.     if (@retcode = 1 or @@ERROR <> 0)
  5291.         goto FAILURE
  5292.  
  5293.     /* 
  5294.     ** Distribution agent 
  5295.     */
  5296.     set @profile_id = NULL
  5297.     set @profile_name = formatmessage(20545) -- Default Distribution Profile
  5298.     set @profile_desc = NULL
  5299.  
  5300.     exec @retcode = dbo.sp_add_agent_profile
  5301.             @profile_id = @profile_id OUT,
  5302.             @profile_name = @profile_name,
  5303.             @agent_type = 3,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  5304.             @profile_type = 0,   -- 0-System, 1-Custom 
  5305.             @description = @profile_desc,
  5306.             @default = 1
  5307.     if (@retcode = 1 or @@ERROR <> 0)
  5308.         goto FAILURE
  5309.  
  5310.     exec @retcode = dbo.sp_generate_agent_parameter @profile_id
  5311.     if (@retcode = 1 or @@ERROR <> 0)
  5312.         goto FAILURE
  5313.  
  5314.     /*
  5315.     ** Distribution Agent Verbose History Profile
  5316.     */
  5317.     set @profile_id = NULL
  5318.     set @profile_name = formatmessage(20546) -- Distribution Verbose History Profile
  5319.     set @profile_desc = formatmessage(20547)
  5320.  
  5321.     exec @retcode = dbo.sp_add_agent_profile
  5322.             @profile_id = @profile_id OUT,
  5323.             @profile_name = @profile_name,
  5324.             @agent_type = 3,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  5325.             @profile_type = 0,   -- 0-System, 1-Custom 
  5326.             @description = @profile_desc,
  5327.             @default = 0
  5328.     if (@retcode = 1 or @@ERROR <> 0)
  5329.         goto FAILURE
  5330.  
  5331.     exec @retcode = dbo.sp_generate_agent_parameter @profile_id
  5332.     if (@retcode = 1 or @@ERROR <> 0)
  5333.         goto FAILURE
  5334.  
  5335.     /* 
  5336.     ** Merge agent : Default profile for well connected scenarios 
  5337.     */
  5338.     set @profile_id = NULL
  5339.     set @profile_name = formatmessage(20545) -- Default Merge Profile
  5340.     set @profile_desc = NULL
  5341.  
  5342.     exec @retcode = dbo.sp_add_agent_profile
  5343.             @profile_id = @profile_id OUT,
  5344.             @profile_name = @profile_name,
  5345.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  5346.             @profile_type = 0,   -- 0-System, 1-Custom 
  5347.             @description = @profile_desc,
  5348.             @default = 1
  5349.  
  5350.     if (@retcode = 1 or @@ERROR <> 0)
  5351.         goto FAILURE
  5352.  
  5353.     exec @retcode = dbo.sp_generate_agent_parameter @profile_id
  5354.     if (@retcode = 1 or @@ERROR <> 0)
  5355.         goto FAILURE
  5356.  
  5357.     /* 
  5358.     ** Merge agent : Non default profile for disconnected scenarios ( unreliable link ) 
  5359.     */
  5360.     set @profile_id = NULL
  5361.     set @profile_name = formatmessage(20548) -- Non-Default Merge Profile
  5362.     set @profile_desc = formatmessage(20549)
  5363.  
  5364.     exec @retcode = dbo.sp_add_agent_profile
  5365.             @profile_id = @profile_id OUT,
  5366.             @profile_name = @profile_name,
  5367.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  5368.             @profile_type = 0,   -- 0-System, 1-Custom 
  5369.             @description = @profile_desc,
  5370.             @default = 0
  5371.  
  5372.     if (@retcode = 1 or @@ERROR <> 0)
  5373.         goto FAILURE
  5374.  
  5375.     exec @retcode = dbo.sp_generate_agent_parameter @profile_id
  5376.     if (@retcode = 1 or @@ERROR <> 0)
  5377.         goto FAILURE
  5378.  
  5379.     /* 
  5380.     ** Merge agent : Non default profile for verbose histroy
  5381.     */
  5382.     set @profile_id = NULL
  5383.     set @profile_name = formatmessage(20546) -- Verbose Merge Profile
  5384.     set @profile_desc = formatmessage(20547)
  5385.  
  5386.     exec @retcode = dbo.sp_add_agent_profile
  5387.             @profile_id = @profile_id OUT,
  5388.             @profile_name = @profile_name,
  5389.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  5390.             @profile_type = 0,   -- 0-System, 1-Custom 
  5391.             @description = @profile_desc,
  5392.             @default = 0
  5393.  
  5394.     if (@retcode = 1 or @@ERROR <> 0)
  5395.         goto FAILURE
  5396.  
  5397.     exec @retcode = dbo.sp_generate_agent_parameter @profile_id
  5398.     if (@retcode = 1 or @@ERROR <> 0)
  5399.         goto FAILURE
  5400.  
  5401.     /* 
  5402.     ** Merge agent : Synchronization Manager Profile
  5403.     */
  5404.     set @profile_id = NULL
  5405.     set @profile_name = formatmessage(20550) -- SyncMgr Profile
  5406.     set @profile_desc = formatmessage(20551)
  5407.  
  5408.     exec @retcode = dbo.sp_add_agent_profile
  5409.             @profile_id = @profile_id OUT,
  5410.             @profile_name = @profile_name,
  5411.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  5412.             @profile_type = 0,   -- 0-System, 1-Custom 
  5413.             @description = @profile_desc,
  5414.             @default = 0
  5415.  
  5416.     if (@retcode = 1 or @@ERROR <> 0)
  5417.         goto FAILURE
  5418.  
  5419.     exec @retcode = dbo.sp_generate_agent_parameter @profile_id
  5420.     if (@retcode = 1 or @@ERROR <> 0)
  5421.         goto FAILURE
  5422.  
  5423.     /* 
  5424.     ** Distribution agent : Synchronization Manager Profile
  5425.     */
  5426.     set @profile_id = NULL
  5427.     set @profile_name = formatmessage(20550) -- SyncMgr Profile
  5428.     set @profile_desc = formatmessage(20551)
  5429.  
  5430.     exec @retcode = dbo.sp_add_agent_profile
  5431.             @profile_id = @profile_id OUT,
  5432.             @profile_name = @profile_name,
  5433.             @agent_type = 3,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  5434.             @profile_type = 0,   -- 0-System, 1-Custom 
  5435.             @description = @profile_desc,
  5436.             @default = 0
  5437.  
  5438.     if (@retcode = 1 or @@ERROR <> 0)
  5439.         goto FAILURE
  5440.  
  5441.     exec @retcode = dbo.sp_generate_agent_parameter @profile_id
  5442.     if (@retcode = 1 or @@ERROR <> 0)
  5443.         goto FAILURE
  5444.  
  5445.  
  5446.     create table msdb.dbo.MSdatatype_mappings 
  5447.     (
  5448.     dbms_name           sysname NOT NULL,
  5449.     sql_type            sysname NOT NULL,
  5450.     dest_type           sysname NOT NULL,
  5451.     dest_prec           int     NOT NULL,
  5452.     dest_create_params  int     NOT NULL,
  5453.     dest_nullable       bit     NOT NULL
  5454.     )
  5455.  
  5456.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'binary' , 'binary', 255, 4, 1
  5457.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'varbinary' , 'varbinary', 255, 4, 1
  5458.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'binary' , 'image', 1073741824, 0, 1
  5459.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'varbinary' , 'image', 1073741824, 0, 1
  5460.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'varchar' , 'varchar', 255, 4, 1
  5461.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'varchar' , 'longtext', 1073741824, 0, 1
  5462.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'nchar' , 'nchar', 255, 4, 1
  5463.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'nchar' , 'longtext', 1073741824, 0, 1
  5464.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'char' , 'char', 255, 4, 1
  5465.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'char' , 'longtext', 1073741824, 0, 1
  5466.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'nvarchar' , 'nchar varying', 255, 4, 1
  5467.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'nvarchar' , 'longtext', 1073741824, 0, 1
  5468.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'datetime' , 'datetime', 255, 0, 1
  5469.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'smalldatetime' , 'datetime', 255, 0, 1
  5470.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'decimal' , 'decimal', 255, 3, 1
  5471.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'numeric' , 'decimal', 255, 3, 1
  5472.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'float' , 'float', 255, 0, 1
  5473.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'real' , 'real', 255, 0, 1
  5474.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'int' , 'int', 255, 0, 1
  5475.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'smallint' , 'smallint', 255, 0, 1
  5476.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'tinyint' , 'byte', 255, 0, 1
  5477.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'money' , 'currency', 255, 0, 1
  5478.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'smallmoney' , 'currency', 255, 0, 1
  5479.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'bit' , 'bit', 255, 0, 1
  5480.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'sysname' , 'nchar varying', 255, 4, 1
  5481.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'timestamp' , 'binary', 255, 4, 1
  5482.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'uniqueidentifier' , 'guid', 255, 0, 1
  5483.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'text' , 'longtext', 1073741824, 0, 1
  5484.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'ntext' , 'longtext', 1073741824, 0, 1
  5485.     exec dbo.sp_add_datatype_mapping 'MS Jet', 'image' , 'image', 1073741824, 0, 1
  5486.  
  5487.     exec dbo.sp_add_datatype_mapping 'Oracle', 'binary' , 'raw', 255, 4, 1
  5488.     exec dbo.sp_add_datatype_mapping 'Oracle', 'varbinary' , 'raw', 255, 4, 1
  5489.     exec dbo.sp_add_datatype_mapping 'Oracle', 'binary' , 'long raw', 2147483647, 0, 1
  5490.     exec dbo.sp_add_datatype_mapping 'Oracle', 'varbinary' , 'long raw', 2147483647, 0, 1
  5491.     exec dbo.sp_add_datatype_mapping 'Oracle', 'varchar' , 'char', 255, 4, 1
  5492.     exec dbo.sp_add_datatype_mapping 'Oracle', 'varchar' , 'varchar2', 2000, 4, 1
  5493.     exec dbo.sp_add_datatype_mapping 'Oracle', 'varchar' , 'long', 2147483647, 0, 1
  5494.     exec dbo.sp_add_datatype_mapping 'Oracle', 'nchar' , 'char', 255, 4, 1
  5495.     exec dbo.sp_add_datatype_mapping 'Oracle', 'nchar' , 'varchar2', 2000, 4, 1
  5496.     exec dbo.sp_add_datatype_mapping 'Oracle', 'nchar' , 'long', 2147483647, 0, 1
  5497.     exec dbo.sp_add_datatype_mapping 'Oracle', 'char' , 'char', 255, 4, 1
  5498.     exec dbo.sp_add_datatype_mapping 'Oracle', 'char' , 'varchar2', 2000, 4, 1
  5499.     exec dbo.sp_add_datatype_mapping 'Oracle', 'char' , 'long', 2147483647, 0, 1
  5500.     exec dbo.sp_add_datatype_mapping 'Oracle', 'nvarchar' , 'char', 255, 4, 1
  5501.     exec dbo.sp_add_datatype_mapping 'Oracle', 'nvarchar' , 'varchar2', 2000, 4, 1
  5502.     exec dbo.sp_add_datatype_mapping 'Oracle', 'nvarchar' , 'long', 2147483647, 0, 1
  5503.     exec dbo.sp_add_datatype_mapping 'Oracle', 'datetime' , 'char', 255, 4, 1
  5504.     exec dbo.sp_add_datatype_mapping 'Oracle', 'smalldatetime' , 'date', 255, 0, 1
  5505.     exec dbo.sp_add_datatype_mapping 'Oracle', 'decimal' , 'number', 255, 3, 1
  5506.     exec dbo.sp_add_datatype_mapping 'Oracle', 'numeric' , 'number', 255, 3, 1
  5507.     exec dbo.sp_add_datatype_mapping 'Oracle', 'float' , 'float', 255, 0, 1
  5508.     exec dbo.sp_add_datatype_mapping 'Oracle', 'real' , 'float', 255, 0, 1
  5509.     exec dbo.sp_add_datatype_mapping 'Oracle', 'int' , 'number', 255, 3, 1
  5510.     exec dbo.sp_add_datatype_mapping 'Oracle', 'smallint' , 'number', 255, 3, 1
  5511.     exec dbo.sp_add_datatype_mapping 'Oracle', 'tinyint' , 'number', 255, 3, 1
  5512.     exec dbo.sp_add_datatype_mapping 'Oracle', 'money' , 'number', 255, 3, 1
  5513.     exec dbo.sp_add_datatype_mapping 'Oracle', 'smallmoney' , 'number', 255, 3, 1
  5514.     exec dbo.sp_add_datatype_mapping 'Oracle', 'bit' , 'number', 255, 3, 1
  5515.     exec dbo.sp_add_datatype_mapping 'Oracle', 'sysname' , 'char', 255, 4, 1
  5516.     exec dbo.sp_add_datatype_mapping 'Oracle', 'timestamp' , 'raw', 255, 4, 1
  5517.     exec dbo.sp_add_datatype_mapping 'Oracle', 'uniqueidentifier' , 'char', 255, 4, 1
  5518.     exec dbo.sp_add_datatype_mapping 'Oracle', 'text' , 'long', 2147483647, 0, 1
  5519.     exec dbo.sp_add_datatype_mapping 'Oracle', 'ntext' , 'long', 2147483647, 0, 1
  5520.     exec dbo.sp_add_datatype_mapping 'Oracle', 'image' , 'long raw', 2147483647, 0, 1
  5521.  
  5522.     return 0
  5523. FAILURE:
  5524.     return 1
  5525. go
  5526.  
  5527. --------------------------------------------------------------------------------
  5528. --. sp_addsubscriber
  5529. --------------------------------------------------------------------------------
  5530. if exists (select * from sysobjects    where type = 'P'
  5531.     and name = 'sp_addsubscriber')
  5532.     drop procedure sp_addsubscriber 
  5533. go
  5534.  
  5535. raiserror('Creating procedure sp_addsubscriber', 0,1)
  5536. GO
  5537.  
  5538. CREATE PROCEDURE sp_addsubscriber (
  5539.     @subscriber sysname,
  5540.     @type tinyint = 0,
  5541.     @login sysname = 'sa',
  5542.     @password sysname = NULL,
  5543.     @commit_batch_size int = 100,
  5544.     @status_batch_size int = 100,
  5545.     @flush_frequency int = 0,
  5546.     @frequency_type int = 64,
  5547.     @frequency_interval int = 1,
  5548.     @frequency_relative_interval int = 1,
  5549.     @frequency_recurrence_factor int = 0,
  5550.     @frequency_subday int = 4,
  5551.     @frequency_subday_interval int = 5,
  5552.     @active_start_time_of_day int = 0,
  5553.     @active_end_time_of_day int = 235959,
  5554.     @active_start_date int = 0,
  5555.     @active_end_date int = 99991231,
  5556.     @description nvarchar (255) = NULL,
  5557.     @security_mode int = 1,  /* backward compatible */ /* 0 standard; 1 integrated */
  5558.     @encrypted_password bit = 0
  5559.         ) AS
  5560.  
  5561.     DECLARE @distributor sysname
  5562.     DECLARE @distribdb sysname
  5563.     DECLARE @distproc nvarchar (255)
  5564.     DECLARE @retcode int
  5565.     DECLARE @dsn_subscriber tinyint
  5566.     DECLARE @jet_subscriber tinyint
  5567.     DECLARE @oledb_subscriber tinyint
  5568.     DECLARE @dist_rpcname sysname
  5569.     DECLARE @platform_nt binary
  5570.  
  5571.     -- Defined in sqlrepl.h
  5572.     select @dsn_subscriber = 1    /* Const: subscriber type 'dsn' */ 
  5573.     select @jet_subscriber = 2   
  5574.     select @oledb_subscriber = 3  
  5575.     
  5576.     select @platform_nt = 0x1
  5577.  
  5578.     /* 
  5579.     ** Check if replication components are installed on this server
  5580.     */
  5581.     exec @retcode = dbo.sp_MS_replication_installed
  5582.     if (@retcode <> 1)
  5583.     begin
  5584.         return (1)
  5585.     end
  5586.     
  5587.     /*
  5588.     ** Parameter Check:  @subscriber.
  5589.     ** Check to make sure that the subscriber doesn't already exist, and
  5590.     ** that the name is a valid non-null identifier.
  5591.     */
  5592.  
  5593.     IF @subscriber IS NULL
  5594.         BEGIN
  5595.             RAISERROR (14043, 16, -1, '@subscriber')
  5596.             RETURN (1)
  5597.         END
  5598.  
  5599.     EXECUTE @retcode = dbo.sp_validname @subscriber
  5600.  
  5601.     IF @@ERROR <> 0 OR @retcode <> 0
  5602.     RETURN (1)
  5603.  
  5604.     if LOWER(@subscriber) = 'all'
  5605.         BEGIN
  5606.             RAISERROR (14032, 16, -1, '@subscriber')
  5607.             RETURN (1)
  5608.         END
  5609.  
  5610.     /* 
  5611.     ** Check for invalid security mode
  5612.     */
  5613.     IF @security_mode < 0 OR @security_mode > 1
  5614.         BEGIN
  5615.             RAISERROR(14109, 16, -1)
  5616.             RETURN (1)
  5617.         END
  5618.  
  5619.     IF (UPPER(@subscriber) = UPPER(@@SERVERNAME) and @platform_nt != ( platform() & @platform_nt ) and @security_mode = 1)
  5620.         BEGIN
  5621.             RAISERROR(21038, 16, -1)
  5622.             RETURN (1)
  5623.         END
  5624.  
  5625.     -- Clear the password if the security mode is 1
  5626.     if @security_mode = 1
  5627.         select @password = ''
  5628.  
  5629.     IF EXISTS (SELECT *
  5630.                  FROM master..sysservers
  5631.                 WHERE UPPER(srvname) = UPPER(@subscriber)
  5632.                   AND srvstatus & 4 <> 0)
  5633.  
  5634.         BEGIN
  5635.             RAISERROR (14040, 16, -1, @subscriber)
  5636.             RETURN (1)
  5637.         END
  5638.  
  5639.     IF @password = N''
  5640.         select @password = NULL
  5641.  
  5642.     
  5643.     /*
  5644.     **  If no MSsubscriber_info parameters skip RPC code.
  5645.     */
  5646.  
  5647.     IF @frequency_type = -1
  5648.         GOTO ADDSUB
  5649.  
  5650.     /*
  5651.     ** Get distribution server information for remote RPC
  5652.     ** subscription calls.
  5653.     */
  5654.  
  5655.  /*   BEGIN TRAN addsubscriber */
  5656.  
  5657.     EXEC @retcode = dbo.sp_helpdistributor  @distributor = @distributor OUTPUT,
  5658.                                         @rpcsrvname = @dist_rpcname OUTPUT,
  5659.                                         @distribdb   = @distribdb   OUTPUT
  5660.  
  5661.     IF @@error <> 0
  5662.         BEGIN
  5663.          RAISERROR (14071, 16, -1)
  5664.          goto undo
  5665.      END
  5666.  
  5667.     IF @retcode <> 0 OR @distribdb IS NULL OR @distributor IS NULL
  5668.         BEGIN
  5669.             RAISERROR (14071, 16, -1)
  5670.             goto undo
  5671.         END
  5672.  
  5673.  
  5674.     DECLARE @zeroint int
  5675.     SELECT @zeroint = 0
  5676.     /*
  5677.     ** Insert information into MSsubscriber_info
  5678.     */
  5679.     SELECT @distproc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSadd_subscriber_info'
  5680.     EXEC @retcode = @distproc
  5681.          @@SERVERNAME,
  5682.          @subscriber,
  5683.      @type,
  5684.      @login,
  5685.      @password,
  5686.      @commit_batch_size,
  5687.      @status_batch_size,
  5688.      @flush_frequency,
  5689.      @frequency_type,
  5690.      @frequency_interval,
  5691.      @frequency_relative_interval,
  5692.      @frequency_recurrence_factor,
  5693.      @frequency_subday,
  5694.      @frequency_subday_interval,
  5695.      @active_start_time_of_day,
  5696.      @active_end_time_of_day,
  5697.      @active_start_date,
  5698.      @active_end_date,
  5699.      /* Work around of server RPC  named parameter problem */
  5700.      @retryattempts = @zeroint,
  5701.      @retrydelay  = @zeroint,
  5702.      @description = @description,
  5703.      @security_mode = @security_mode,
  5704.      @encrypted_password = @encrypted_password
  5705.  
  5706.     IF @@error <> 0 OR @retcode <> 0
  5707.         BEGIN
  5708.         RAISERROR (14042, 16, -1)
  5709.         goto undo
  5710.     END
  5711.  
  5712.     /*
  5713.     ** add schedule information into MSsubscriber_schedule for merge agent
  5714.     */
  5715.     -- NOTE: We may need better default schedule for merge agent
  5716.     
  5717.     SELECT @distproc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSadd_subscriber_schedule'
  5718.     EXEC @retcode = @distproc
  5719.          @@SERVERNAME,
  5720.          @subscriber,
  5721.          0, -- agent_type = 0 means distribution agent
  5722.          @frequency_type,
  5723.          @frequency_interval,
  5724.          @frequency_relative_interval,
  5725.          @frequency_recurrence_factor,
  5726.          @frequency_subday,
  5727.          @frequency_subday_interval,
  5728.          @active_start_time_of_day,
  5729.          @active_end_time_of_day,
  5730.          @active_start_date,
  5731.          @active_end_date
  5732.     
  5733.     IF @@error <> 0 OR @retcode <> 0
  5734.         BEGIN
  5735.             RAISERROR (14042, 16, -1)
  5736.             goto undo
  5737.         END
  5738.  
  5739.     EXEC @retcode = @distproc
  5740.          @@SERVERNAME,
  5741.          @subscriber,
  5742.          1,             --agent_type = 0 means merge agent
  5743.          4,             --frequency_type,
  5744.          1,             --frequency_interval,
  5745.          1,             --frequency_relative_interval,
  5746.          0,             --frequency_recurrence_factor,
  5747.          8,             --frequency_subday,
  5748.          1,             --frequency_subday_interval,
  5749.          0,             --active_start_time_of_day,
  5750.          235959,        --active_end_time_of_day,
  5751.          0,             --active_start_date,
  5752.          99991231       --active_end_date
  5753.     
  5754.     IF @@error <> 0 OR @retcode <> 0
  5755.         BEGIN
  5756.             RAISERROR (14042, 16, -1)
  5757.             goto undo
  5758.         END
  5759.  
  5760. /*    Commit Transaction addsubscriber */
  5761.  
  5762. ADDSUB:
  5763.  
  5764.     /*
  5765.     ** The server may already be listed in master..sysservers, but might
  5766.     ** not be marked as a subscriber yet.  If it's not in
  5767.     ** master..sysservers, let's add it first.
  5768.     */
  5769.  
  5770.     IF NOT EXISTS (SELECT *
  5771.                          FROM master..sysservers
  5772.                         WHERE LOWER(srvname) = LOWER(@subscriber))
  5773.     begin
  5774.  
  5775.         EXECUTE @retcode = dbo.sp_addserver @subscriber
  5776.  
  5777.             IF @@error <> 0 OR @retcode <> 0
  5778.                 BEGIN
  5779.                 RAISERROR (14042, 16, -1)
  5780.                     RETURN (1)
  5781.                 END
  5782.     end
  5783.     /*
  5784.     ** Set the server option to indicate this is a subscriber.
  5785.     */
  5786.  
  5787.     EXECUTE @retcode = dbo.sp_serveroption @subscriber, 'sub', true
  5788.  
  5789.     IF @@error <> 0 OR @retcode <> 0
  5790.         BEGIN
  5791.            RAISERROR (14042, 16, -1)
  5792.            RETURN (1)
  5793.         END
  5794.  
  5795.     /*
  5796.     ** Set the server option to indicate this is a DSN subscriber.
  5797.     */
  5798.     if @type = @dsn_subscriber OR @type = @jet_subscriber OR @type = @oledb_subscriber
  5799.        BEGIN
  5800.           update master..sysservers set srvproduct = 'MSREPL-NONSQL' where
  5801.             UPPER(srvname) = UPPER(@subscriber)
  5802.           IF @@error <> 0 
  5803.             return(1)
  5804.        END
  5805.     
  5806.         RETURN (0) 
  5807. undo:
  5808.  
  5809.     RETURN (1) 
  5810. GO
  5811.  
  5812. --------------------------------------------------------------------------------
  5813. --. sp_changesubscriber
  5814. --------------------------------------------------------------------------------
  5815. if exists (select * from sysobjects    where type = 'P'
  5816.     and name = 'sp_changesubscriber')
  5817.     drop procedure sp_changesubscriber
  5818. go
  5819.  
  5820. raiserror('Creating procedure sp_changesubscriber', 0,1)
  5821. GO
  5822.  
  5823. CREATE PROCEDURE sp_changesubscriber (
  5824.     @subscriber sysname,
  5825.     @type tinyint = NULL,
  5826.     @login sysname = NULL,
  5827.     @password sysname = '%',
  5828.     @commit_batch_size int = NULL,
  5829.     @status_batch_size int = NULL,
  5830.     @flush_frequency int = NULL,
  5831.     @frequency_type int = NULL,
  5832.     @frequency_interval int = NULL,
  5833.     @frequency_relative_interval int = NULL,
  5834.     @frequency_recurrence_factor int = NULL,
  5835.     @frequency_subday int = NULL,
  5836.     @frequency_subday_interval int = NULL,
  5837.     @active_start_time_of_day int = NULL,
  5838.     @active_end_time_of_day int = NULL,
  5839.     @active_start_date int = NULL,
  5840.     @active_end_date int = NULL,
  5841.     @description nvarchar (255) = NULL,
  5842.     @security_mode int = NULL /* 0 standard; 1 integrated */
  5843.  
  5844.         ) AS
  5845.  
  5846.     DECLARE @distributor sysname
  5847.     DECLARE @distribdb sysname
  5848.     DECLARE @distproc nvarchar (255)
  5849.     DECLARE @msg nvarchar(255)
  5850.     DECLARE @retcode int
  5851.     DECLARE @platform_nt binary
  5852.  
  5853.     select @platform_nt = 0x1
  5854.  
  5855.     IF (UPPER(@subscriber) = UPPER(@@SERVERNAME) and @platform_nt != ( platform() & @platform_nt ) and @security_mode = 1)
  5856.         BEGIN
  5857.             RAISERROR(21038, 16, -1)
  5858.             RETURN (1)
  5859.         END
  5860.  
  5861.     -- Clear the password if the security mode is 1
  5862.     if @security_mode = 1
  5863.         select @password = ''
  5864.  
  5865.     /*
  5866.     ** Check to make sure that the subscriber exists.
  5867.     */
  5868.     IF NOT EXISTS (SELECT *
  5869.                  FROM master..sysservers
  5870.                 WHERE UPPER(srvname) = UPPER(@subscriber))
  5871.         BEGIN
  5872.             RAISERROR(14048, 16, 1, @subscriber)
  5873.             RETURN (1)
  5874.         END
  5875.  
  5876.     /*
  5877.     ** Get distribution server information for remote RPC
  5878.     ** subscription calls.
  5879.     */
  5880.     EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  5881.         @distribdb = @distribdb OUTPUT
  5882.     IF @@ERROR <> 0 OR @retcode <> 0
  5883.         BEGIN
  5884.             RAISERROR (14071, 16, -1)
  5885.             RETURN (1)
  5886.         END
  5887.  
  5888.     DECLARE @intnull int
  5889.     /*
  5890.     ** Update MSsubscriber_info
  5891.     */
  5892.     SELECT @distproc = RTRIM(@distributor) + '.' +
  5893.         RTRIM(@distribdb) + '.dbo.sp_MSupdate_subscriber_info'
  5894.     EXEC @retcode = @distproc
  5895.         @@SERVERNAME,
  5896.         @subscriber,
  5897.     @type,
  5898.     @login,
  5899.     @password,
  5900.     @commit_batch_size,
  5901.     @status_batch_size,
  5902.     @flush_frequency,
  5903.     @frequency_type,
  5904.     @frequency_interval,
  5905.     @frequency_relative_interval,
  5906.     @frequency_recurrence_factor,
  5907.     @frequency_subday,
  5908.     @frequency_subday_interval,
  5909.     @active_start_time_of_day,
  5910.     @active_end_time_of_day,
  5911.     @active_start_date,
  5912.     @active_end_date,
  5913.     @retryattempts = @intnull,
  5914.     @retrydelay  = @intnull,
  5915.     @description = @description,
  5916.     @security_mode = @security_mode
  5917.     IF @@ERROR <> 0 OR @retcode <> 0
  5918.         BEGIN
  5919.             RAISERROR (14048, 16, -1, @subscriber)
  5920.             RETURN (1)
  5921.     END
  5922. go
  5923.  
  5924. --------------------------------------------------------------------------------
  5925. --. sp_MScreate_dist_tables
  5926. --------------------------------------------------------------------------------
  5927. if exists (select * from sysobjects    where type = 'P'
  5928.     and name = 'sp_MScreate_dist_tables')
  5929.     drop procedure sp_MScreate_dist_tables
  5930. go
  5931.  
  5932. raiserror('Creating procedure sp_MScreate_dist_tables', 0,1)
  5933. GO
  5934.  
  5935. CREATE PROCEDURE sp_MScreate_dist_tables
  5936. AS
  5937.  
  5938.    /*
  5939.    ** Important:  
  5940.    ** We use varbinary(16) for xact_id and xact_seqno, we don't want ending nulls
  5941.    ** to be truncated by the server
  5942.    **
  5943.    ** Also, in MSrepl_commands, we don't want ending space to be truncated.  
  5944.    */
  5945.    SET ANSI_PADDING ON
  5946.  
  5947.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSrepl_version' and type = 'U')
  5948.    BEGIN
  5949.       /****************************************************************************/
  5950.       raiserror('Creating table MSrepl_version', 0,1)
  5951.       /****************************************************************************/
  5952.       CREATE TABLE dbo.MSrepl_version
  5953.       (
  5954.       major_version int NOT NULL,
  5955.       minor_version int NOT NULL,
  5956.       revision int NOT NULL,
  5957.       db_existed bit NULL
  5958.       )
  5959.     
  5960.       EXEC dbo.sp_MS_marksystemobject 'MSrepl_version'
  5961.       
  5962.       raiserror('Creating clustered index ucMSrepl_version', 0,1)    
  5963.       CREATE UNIQUE CLUSTERED INDEX ucMSrepl_version ON dbo.MSrepl_version
  5964.             (major_version, minor_version, revision)
  5965.  
  5966.       INSERT INTO MSrepl_version VALUES (7,0,0,0)
  5967.    END
  5968.  
  5969.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSpublisher_databases' and type = 'U')
  5970.    BEGIN
  5971.       /****************************************************************************/
  5972.       raiserror('Creating table MSpublisher_databases', 0,1)
  5973.       /****************************************************************************/
  5974.       CREATE TABLE dbo.MSpublisher_databases(
  5975.         publisher_id smallint NOT NULL,
  5976.         publisher_db sysname NULL,
  5977.         id int identity NOT NULL,                   
  5978.     )
  5979.       EXEC dbo.sp_MS_marksystemobject 'MSpublisher_databases'
  5980.  
  5981.       raiserror('Creating clustered index ucMSpublisher_databases', 0,1)
  5982.       CREATE UNIQUE CLUSTERED INDEX ucMSpublisher_databases ON dbo.MSpublisher_databases
  5983.      (publisher_id, publisher_db, id)
  5984.    END
  5985.  
  5986.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSpublications' and type = 'U')
  5987.    BEGIN
  5988.       /****************************************************************************/
  5989.       raiserror('Creating table MSpublications', 0,1)
  5990.       /****************************************************************************/
  5991.       CREATE TABLE dbo.MSpublications (
  5992.         publisher_id smallint NOT NULL,
  5993.         publisher_db sysname NULL,
  5994.         publication sysname NOT NULL,
  5995.         publication_id int identity NOT NULL,   -- This id IS NOT the same as the SQL Server publisher's
  5996.         publication_type int NOT NULL,          -- 0 = Snapshot 1 = Transactional
  5997.         thirdparty_flag bit NOT NULL,           -- 0 = SQL Server 1 = Third Party
  5998.         independent_agent bit NOT NULL,
  5999.         immediate_sync bit NOT NULL,
  6000.         allow_push bit NOT NULL,
  6001.         allow_pull bit NOT NULL,
  6002.         allow_anonymous bit NOT NULL,
  6003.         description nvarchar(255) NULL,
  6004.         vendor_name nvarchar(100) NULL,
  6005.         retention    int NULL
  6006.     )
  6007.       EXEC dbo.sp_MS_marksystemobject 'MSpublications'
  6008.  
  6009.      -- publication_id needs to be the first columns in the index. It
  6010.      -- is used in sp_MSmaximum_cleanup_seqno.
  6011.       raiserror('Creating clustered index ucMSpublications', 0,1)
  6012.       CREATE UNIQUE CLUSTERED INDEX ucMSpublications ON dbo.MSpublications
  6013.      (publication_id,  publication, publisher_db, publisher_id)
  6014.  
  6015.    END
  6016.  
  6017.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSarticles' and type = 'U')
  6018.    BEGIN
  6019.       /****************************************************************************/
  6020.       raiserror('Creating table MSarticles', 0,1)
  6021.       /****************************************************************************/
  6022.     CREATE TABLE dbo.MSarticles (
  6023.         publisher_id smallint NOT NULL,
  6024.         publisher_db sysname NULL,
  6025.         publication_id int NOT NULL,
  6026.         article sysname NOT NULL,
  6027.         article_id int NOT NULL,                            -- This id is the same as a SQL Server Publisher's
  6028.         destination_object sysname NULL,
  6029.         source_owner    sysname NULL,
  6030.         source_object sysname NULL,
  6031.         description nvarchar(255) NULL  
  6032.     )   
  6033.  
  6034.       EXEC dbo.sp_MS_marksystemobject 'MSarticles'
  6035.  
  6036.       raiserror('Creating clustered index ucMSarticles', 0,1)
  6037.       CREATE UNIQUE CLUSTERED INDEX ucMSarticles ON dbo.MSarticles
  6038.      (publisher_db, publisher_id, article_id, article, publication_id)
  6039.    END
  6040.  
  6041.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSsubscriptions' and type = 'U')
  6042.    BEGIN
  6043.       /****************************************************************************/
  6044.       raiserror('Creating table MSsubscriptions', 0,1)
  6045.       /****************************************************************************/
  6046.        CREATE TABLE dbo.MSsubscriptions
  6047.       (
  6048.         publisher_database_id int NOT NULL,         -- Used to reference MSrepl_transactions and MSrepl_commands
  6049.         publisher_id smallint NOT NULL,
  6050.         publisher_db sysname NOT NULL,
  6051.         publication_id int NOT NULL,
  6052.         article_id int NOT NULL,
  6053.         subscriber_id smallint NOT NULL,
  6054.         subscriber_db sysname NOT NULL,
  6055.         subscription_type int NOT NULL,         -- 0 = push, 1 = pull, 2 = anonymous 
  6056.         sync_type tinyint NOT NULL,                 -- 1 = automatic 2 = no sync
  6057.         status tinyint NOT NULL,                        -- 0 = inactive, 1 = subscribed, 2 = active 
  6058.         subscription_seqno varbinary(16) NOT NULL,  -- publisher's database sequence number 
  6059.         snapshot_seqno_flag bit NOT NULL,               -- 1 if subscription_seqno is the snapshot seqno
  6060.         independent_agent bit NOT NULL,             -- Value carried over from MSpublications
  6061.         subscription_time datetime NOT NULL, 
  6062.         loopback_detection bit NOT NULL,  
  6063.         agent_id int NOT NULL,
  6064.         update_mode tinyint NOT NULL,
  6065.         publisher_seqno varbinary(16) NOT NULL
  6066.       )
  6067.  
  6068.       EXEC dbo.sp_MS_marksystemobject 'MSsubscriptions'
  6069.  
  6070.       raiserror('Creating clustered index ucMSsubscirptions', 0,1)
  6071.       CREATE UNIQUE CLUSTERED INDEX ucMSsubscriptions ON dbo.MSsubscriptions
  6072.       (agent_id, article_id)
  6073.  
  6074.       -- Index used by sp_MSdelete_publisherdb_trans
  6075.       raiserror('Creating index iMSsubscriptions', 0,1)
  6076.       CREATE INDEX iMSsubscriptions ON dbo.MSsubscriptions
  6077.       (publisher_database_id, article_id, subscriber_id, subscriber_db, publication_id, publisher_db, publisher_id)
  6078.    END
  6079.    
  6080.    -- For beta 3 upgrade, we need to create new index here.
  6081.    if not exists (select * from sysindexes where name = 'iMSsubscriptions2')
  6082.    begin
  6083.       -- Index used by sp_MSdelete_publisherdb_trans
  6084.       raiserror('Creating index iMSsubscriptions2', 0,1)
  6085.       CREATE INDEX iMSsubscriptions2 ON dbo.MSsubscriptions
  6086.       (publisher_database_id, subscription_seqno)
  6087.    end
  6088.  
  6089.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSmerge_subscriptions' and type = 'U')
  6090.    BEGIN
  6091.       /****************************************************************************/
  6092.       raiserror('Creating table MSmerge_subscriptions', 0,1)
  6093.       /****************************************************************************/
  6094.        CREATE TABLE dbo.MSmerge_subscriptions
  6095.       (
  6096.         publisher_id smallint NOT NULL,
  6097.         publisher_db sysname NULL,
  6098.         publication_id int NOT NULL,
  6099.         subscriber_id smallint NOT NULL,
  6100.         subscriber_db sysname NULL,
  6101.         subscription_type int NULL,         -- 0 = push, 1 = pull, 2 = anonymous 
  6102.         sync_type tinyint NOT NULL,                 -- 1 = automatic 2 = no sync
  6103.         status tinyint NOT NULL,                        -- 0 = inactive, 1 = subscribed, 2 = active 
  6104.         subscription_time datetime NOT NULL
  6105.       )
  6106.  
  6107.       EXEC dbo.sp_MS_marksystemobject 'MSmerge_subscriptions'
  6108.  
  6109.       raiserror('Creating clustered index ucMSmerge_subscriptions', 0,1)
  6110.       CREATE UNIQUE CLUSTERED INDEX ucMSmerge_subscriptions ON dbo.MSmerge_subscriptions
  6111.      (publisher_id, publisher_db, publication_id, subscriber_id, subscriber_db)
  6112.    END
  6113.  
  6114.  
  6115.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSrepl_transactions' and type = 'U')
  6116.    BEGIN
  6117.       /****************************************************************************/
  6118.       raiserror('Creating table MSrepl_transactions', 0,1)
  6119.       /****************************************************************************/
  6120.       CREATE TABLE dbo.MSrepl_transactions
  6121.       (
  6122.       publisher_database_id int NOT NULL,
  6123.       xact_id varbinary(16) NULL,
  6124.       xact_seqno varbinary (16 )  NOT NULL,
  6125.       entry_time datetime  NOT NULL
  6126.       )
  6127.  
  6128.       EXEC dbo.sp_MS_marksystemobject 'MSrepl_transactions'
  6129.  
  6130.       raiserror('Creating clustered index usMSrepl_transactions', 0,1)
  6131.       CREATE UNIQUE CLUSTERED INDEX ucMSrepl_transactions ON dbo.MSrepl_transactions
  6132.          (publisher_database_id, xact_seqno)
  6133.    END
  6134.  
  6135.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSrepl_commands' and type = 'U')
  6136.    BEGIN
  6137.  
  6138.       /****************************************************************************/
  6139.       raiserror('Creating table MSrepl_commands', 0,1)
  6140.       /****************************************************************************/
  6141.  
  6142.  
  6143.       CREATE TABLE dbo.MSrepl_commands (
  6144.       publisher_database_id int not null,
  6145.       xact_seqno varbinary(16) not null,
  6146.       type int not null, 
  6147.       article_id int not null,
  6148.       originator_id int not null,
  6149.       command_id int not null,
  6150.       partial_command bit not null,
  6151.       command varbinary(1024) NULL
  6152.       )
  6153.  
  6154.       EXEC dbo.sp_MS_marksystemobject 'MSrepl_commands'
  6155.  
  6156.       raiserror('Creating clusterd index ucMSrepl_commands', 0,1)
  6157.       CREATE UNIQUE CLUSTERED INDEX ucMSrepl_commands ON dbo.MSrepl_commands
  6158.          (publisher_database_id, xact_seqno, command_id)
  6159.    END
  6160.  
  6161.  
  6162.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSrepl_originators' and type = 'U')
  6163.    BEGIN
  6164.       /****************************************************************************/
  6165.       raiserror('Creating table MSrepl_orginators', 0,1)
  6166.       /****************************************************************************/
  6167.       CREATE TABLE dbo.MSrepl_originators
  6168.       (
  6169.       id int identity not null,
  6170.       publisher_database_id int not null,
  6171.       srvname   sysname not null,
  6172.       dbname    sysname not null
  6173.       )
  6174.  
  6175.       EXEC dbo.sp_MS_marksystemobject 'MSrepl_originators'
  6176.  
  6177.       raiserror('Creating clustered index usMSrepl_originators', 0,1)
  6178.       CREATE UNIQUE CLUSTERED INDEX ucMSrepl_originators ON dbo.MSrepl_originators
  6179.          (publisher_database_id, srvname, dbname)
  6180.    END
  6181.  
  6182.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSsubscriber_info' and type = 'U')
  6183.    BEGIN
  6184.       /****************************************************************************/
  6185.       raiserror('Creating table MSsubscriber_info', 0,1)
  6186.       /****************************************************************************/
  6187.       CREATE TABLE dbo.MSsubscriber_info
  6188.       (
  6189.       publisher  sysname NOT NULL,
  6190.       subscriber  sysname NOT NULL,
  6191.       type tinyint NOT NULL,           /* 0: MS SQL Server 1: ODBC Data Source */
  6192.       login sysname NULL,
  6193.       password sysname NULL,
  6194.       description nvarchar(255) NULL,
  6195.       security_mode int NOT NULL
  6196.       )
  6197.  
  6198.       EXEC dbo.sp_MS_marksystemobject 'MSsubscriber_info'
  6199.  
  6200.       raiserror('Creating clustered index ucMSsubscriber_info', 0,1)
  6201.       CREATE UNIQUE CLUSTERED INDEX ucMSsubscriber_info ON dbo.MSsubscriber_info
  6202.      (publisher, subscriber)
  6203.    END
  6204.    ELSE
  6205.    BEGIN
  6206.       IF NOT EXISTS (select * from syscolumns
  6207.         where name = 'description'
  6208.         and id=object_id('MSsubscriber_info'))
  6209.       BEGIN
  6210.          
  6211.          ALTER TABLE MSsubscriber_info ADD description nvarchar (255) NULL
  6212.          UPDATE MSsubscriber_info SET description = 'SQL Server 6.0'
  6213.       END
  6214.    END
  6215.  
  6216.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSsubscriber_schedule' and type = 'U')
  6217.    BEGIN
  6218.          raiserror('Creating table MSsubscriber_schedule', 0,1)
  6219.          
  6220.         CREATE TABLE dbo.MSsubscriber_schedule
  6221.         (
  6222.             publisher  sysname NOT NULL,
  6223.             subscriber  sysname NOT NULL,
  6224.             agent_type      smallint NOT NULL,   -- 0 for distribution agent, 1 for merge agent
  6225.             frequency_type int NOT NULL,
  6226.             frequency_interval int NOT NULL,
  6227.             frequency_relative_interval int NOT NULL,
  6228.             frequency_recurrence_factor int NOT NULL,
  6229.             frequency_subday int NOT NULL,
  6230.             frequency_subday_interval int NOT NULL,
  6231.             active_start_time_of_day int NOT NULL,
  6232.             active_end_time_of_day int NOT NULL,
  6233.             active_start_date int NOT NULL,
  6234.             active_end_date int NOT NULL
  6235.         )
  6236.       EXEC dbo.sp_MS_marksystemobject 'MSsubscriber_schedule'
  6237.  
  6238.         CREATE UNIQUE CLUSTERED INDEX ucMSsubscriber_schedule ON dbo.MSsubscriber_schedule
  6239.      (publisher, subscriber, agent_type)
  6240.      
  6241.     END
  6242.  
  6243.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSsnapshot_history' and type = 'U')
  6244.    BEGIN
  6245.         /****************************************************************************/
  6246.          raiserror('Creating table MSsnapshot_history', 0,1)
  6247.         /****************************************************************************/
  6248.         CREATE TABLE dbo.MSsnapshot_history 
  6249.         (
  6250.         agent_id int NOT NULL,
  6251.         runstatus int NOT NULL,
  6252.         start_time datetime NOT NULL,        
  6253.         time datetime NOT NULL,    
  6254.         duration int NOT NULL,            
  6255.         comments nvarchar(255) NOT NULL,
  6256.  
  6257.         -- Session summary statistics
  6258.         delivered_transactions int NOT NULL,
  6259.         delivered_commands int NOT NULL,
  6260.         delivery_rate float NOT NULL,
  6261.  
  6262.         error_id int NOT NULL,
  6263.         timestamp NOT NULL
  6264.     )
  6265.  
  6266.       EXEC dbo.sp_MS_marksystemobject 'MSsnapshot_history'
  6267.  
  6268.      raiserror('Creating clustered index ucMSsnapshot_history', 0,1)
  6269.     CREATE UNIQUE CLUSTERED INDEX ucMSsnapshot_history ON dbo.MSsnapshot_history
  6270.         (agent_id, timestamp, start_time, time)
  6271.  
  6272.     if not exists (select * from sysindexes where name = 'nc1MSsnapshot_history')
  6273.     begin
  6274.          raiserror('Creating clustered index nc1MSsnapshot_history', 0,1)
  6275.         create nonclustered index nc1MSsnapshot_history on MSsnapshot_history(agent_id, start_time) 
  6276.     end    
  6277.  
  6278.    END
  6279.        
  6280.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSlogreader_history' and type = 'U')
  6281.    BEGIN
  6282.         /****************************************************************************/
  6283.         raiserror('Creating table MSlogreader_history', 0,1)
  6284.         /****************************************************************************/    
  6285.         CREATE TABLE dbo.MSlogreader_history
  6286.         (
  6287.         agent_id int NOT NULL,
  6288.         runstatus int NOT NULL,
  6289.         start_time datetime NOT NULL,
  6290.         time datetime NOT NULL,
  6291.         duration int NOT NULL,
  6292.         comments nvarchar(255) NOT NULL,
  6293.         xact_seqno varbinary(16) NULL,
  6294.  
  6295.         -- Session summary statistics
  6296.         delivery_time int NOT NULL,
  6297.         delivered_transactions int NOT NULL,
  6298.         delivered_commands int NOT NULL,
  6299.         average_commands int NOT NULL,
  6300.         delivery_rate float NOT NULL,
  6301.         delivery_latency int NOT NULL,
  6302.  
  6303.         error_id int NOT NULL,
  6304.         timestamp NOT NULL
  6305.         )
  6306.  
  6307.       EXEC dbo.sp_MS_marksystemobject 'MSlogreader_history'
  6308.  
  6309.     raiserror('Creating clustered index ucMSlogreader_history', 0,1)
  6310.     CREATE UNIQUE CLUSTERED INDEX ucMSlogreader_history ON dbo.MSlogreader_history
  6311.         (agent_id, timestamp, runstatus, start_time, time) 
  6312.  
  6313.     if not exists (select * from sysindexes where name = 'nc1MSlogreader_history')
  6314.     begin
  6315.         raiserror('Creating nonclustered index nc1MSlogreader_history', 0,1)
  6316.         create nonclustered index nc1MSlogreader_history on MSlogreader_history(agent_id, start_time) 
  6317.     end            
  6318.    END
  6319.  
  6320.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSdistribution_history' and type = 'U')
  6321.    BEGIN
  6322.         /****************************************************************************/
  6323.           raiserror('Creating table MSdistribution_history', 0,1)
  6324.         /****************************************************************************/    
  6325.  
  6326.         CREATE TABLE dbo.MSdistribution_history
  6327.         (
  6328.         agent_id int NOT NULL,
  6329.         runstatus int NOT NULL,
  6330.         start_time datetime NOT NULL,
  6331.         time datetime NOT NULL,
  6332.         duration int NOT NULL,
  6333.         comments nvarchar(255) NOT NULL,
  6334.         xact_seqno varbinary(16) NULL,
  6335.  
  6336.         -- Current statistics
  6337.         current_delivery_rate float NOT NULL,
  6338.         current_delivery_latency int NOT NULL,
  6339.  
  6340.         -- Session summary statistics
  6341.         delivered_transactions int NOT NULL,
  6342.         delivered_commands int NOT NULL,
  6343.         average_commands int NOT NULL,
  6344.         delivery_rate float NOT NULL,       
  6345.         delivery_latency int NOT NULL, 
  6346.  
  6347.         -- Summary statistics across all sessions
  6348.         total_delivered_commands int NOT NULL, 
  6349.  
  6350.         error_id int NOT NULL,
  6351.         updateable_row bit NOT NULL,
  6352.         timestamp NOT NULL
  6353.         )
  6354.  
  6355.     EXEC dbo.sp_MS_marksystemobject 'MSdistribution_history'
  6356.  
  6357.     raiserror('Creating clustered index ucMSdistribution_history', 0,1)
  6358.     CREATE UNIQUE CLUSTERED INDEX ucMSdistribution_history ON dbo.MSdistribution_history
  6359.         (agent_id, timestamp, runstatus, start_time, time) 
  6360.  
  6361.     if not exists (select * from sysindexes where name = 'nc1MSdistribution_history')
  6362.     begin
  6363.         raiserror('Creating clustered index nc1MSdistribution_history', 0,1)
  6364.         create nonclustered index nc1MSdistribution_history on MSdistribution_history(agent_id, start_time) 
  6365.     end    
  6366.  
  6367.    END
  6368.  
  6369.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSmerge_history' and type = 'U')
  6370.    BEGIN
  6371.         /****************************************************************************/
  6372.       raiserror('Creating table MSmerge_history', 0,1)
  6373.         /****************************************************************************/    
  6374.  
  6375.         CREATE TABLE dbo.MSmerge_history
  6376.         (
  6377.         agent_id                    int             NOT NULL,
  6378.         runstatus               int             NOT NULL,
  6379.         start_time              datetime        NOT NULL,
  6380.         time                    datetime        NOT NULL,
  6381.         duration                int             NOT NULL,
  6382.         comments                nvarchar(255)   NOT NULL,
  6383.         delivery_time               int         NOT NULL,
  6384.         delivery_rate               float       NOT NULL,
  6385.         publisher_insertcount       int         NULL,
  6386.         publisher_updatecount       int         NULL,
  6387.         publisher_deletecount       int         NULL,
  6388.         publisher_conflictcount     int         NULL,
  6389.         subscriber_insertcount      int         NULL,
  6390.         subscriber_updatecount      int         NULL,
  6391.         subscriber_deletecount      int         NULL,
  6392.         subscriber_conflictcount    int         NULL,
  6393.         error_id                    int         NOT NULL,
  6394.         timestamp                               NOT NULL,
  6395.         updateable_row                bit            NOT NULL
  6396.         )        
  6397.  
  6398.     EXEC dbo.sp_MS_marksystemobject 'MSmerge_history'
  6399.  
  6400.     raiserror('Creating clustered index ucMSmerge_history', 0,1)
  6401.     CREATE UNIQUE CLUSTERED INDEX ucMSmerge_history ON dbo.MSmerge_history
  6402.         (agent_id, timestamp, runstatus, start_time, time) 
  6403.  
  6404.     if not exists (select * from sysindexes where name = 'nc1MSmerge_history')
  6405.         begin
  6406.             raiserror('Creating nonclustered index nc1MSmerge_history', 0,1)
  6407.             create nonclustered index nc1MSmerge_history on MSmerge_history(agent_id, start_time) 
  6408.         end
  6409.    END
  6410.    ELSE
  6411.    BEGIN
  6412.       IF NOT EXISTS (select * from syscolumns
  6413.         where name = 'updateable_row'
  6414.         and id=object_id('MSmerge_history'))
  6415.       BEGIN
  6416.          
  6417.         ALTER TABLE MSmerge_history ADD updateable_row bit default 1 NOT NULL
  6418.         if not exists (select * from sysindexes where name = 'nc1MSmerge_history')
  6419.         begin
  6420.             raiserror('Creating nonclustered index nc1MSmerge_history', 0,1)
  6421.             create nonclustered index nc1MSmerge_history on MSmerge_history(agent_id, start_time) 
  6422.         end
  6423.       END
  6424.    END
  6425.  
  6426.  
  6427.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSrepl_errors' and type = 'U')
  6428.    BEGIN
  6429.         /****************************************************************************/
  6430.         raiserror('Creating table MSrepl_errors', 0,1)
  6431.         /****************************************************************************/    
  6432.  
  6433.         CREATE TABLE dbo.MSrepl_errors
  6434.         (
  6435.         id                  int NOT NULL,
  6436.         time                datetime NOT NULL,
  6437.         error_type_id       int NULL,
  6438.         source_type_id      int NULL,
  6439.         source_name         nvarchar(100) NULL,
  6440.         error_code          sysname NULL,
  6441.         error_text          ntext NULL
  6442.         )
  6443.  
  6444.       EXEC dbo.sp_MS_marksystemobject 'MSrepl_errors'
  6445.  
  6446.     raiserror('Creating clustered index ucMSrepl_errors', 0,1)
  6447.     CREATE CLUSTERED INDEX ucMSrepl_errors ON dbo.MSrepl_errors
  6448.         (id, time) -- WITH ALLOW_DUP_ROW
  6449.    END
  6450.  
  6451.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSsnapshot_agents' and type = 'U')
  6452.    BEGIN
  6453.         /****************************************************************************/
  6454.         raiserror('Creating table MSsnapshot_agents', 0,1)
  6455.         /****************************************************************************/    
  6456.  
  6457.         CREATE TABLE dbo.MSsnapshot_agents
  6458.         (
  6459.         id                  int IDENTITY NOT NULL,
  6460.         name                nvarchar(100) NOT NULL,
  6461.         publisher_id        smallint NOT NULL,
  6462.         publisher_db        sysname NOT NULL,
  6463.         publication         sysname NOT NULL,
  6464.         publication_type    int NOT NULL,       -- 0 transactional 1 snapshot 2 merge
  6465.         local_job           bit NOT NULL,
  6466.         job_id              binary(16) NULL,
  6467.         profile_id  int     NOT NULL
  6468.         )
  6469.  
  6470.       EXEC dbo.sp_MS_marksystemobject 'MSsnapshot_agents'
  6471.  
  6472.     raiserror('Creating clustered index ucMSsnapshot_agents', 0,1)
  6473.     CREATE CLUSTERED INDEX ucMSsnapshot_agents ON dbo.MSsnapshot_agents
  6474.         (publication, publisher_db, publisher_id) 
  6475.  
  6476.     raiserror('Creatingindex iMSsnapshot_agents', 0,1)
  6477.     CREATE UNIQUE INDEX iMSsnapshot_agents ON dbo.MSsnapshot_agents
  6478.         (id)
  6479.    END
  6480.  
  6481.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSlogreader_agents' and type = 'U')
  6482.    BEGIN
  6483.         /****************************************************************************/
  6484.         raiserror('Creating table MSlogreader_agents', 0,1)
  6485.         /****************************************************************************/    
  6486.  
  6487.         CREATE TABLE dbo.MSlogreader_agents
  6488.         (
  6489.         id                  int IDENTITY NOT NULL,
  6490.         name                nvarchar(100) NOT NULL,
  6491.         publisher_id        smallint NOT NULL,
  6492.         publisher_db        sysname NOT NULL,
  6493.         publication         sysname NOT NULL,-- Not used for SQL Server publisher
  6494.         local_job           bit NOT NULL,
  6495.         job_id              binary(16) NULL,
  6496.         profile_id  int     NOT NULL
  6497.         )
  6498.  
  6499.       EXEC dbo.sp_MS_marksystemobject 'MSlogreader_agents'
  6500.  
  6501.     raiserror('Creating clustered index ucMSlogreader_agents', 0,1)
  6502.     CREATE CLUSTERED INDEX ucMSlogreader_agents ON dbo.MSlogreader_agents
  6503.         (publisher_db, publisher_id) 
  6504.  
  6505.     raiserror('Creatingindex iMSlogreader_agents', 0,1)
  6506.     CREATE UNIQUE INDEX iMSlogreader_agents ON dbo.MSlogreader_agents
  6507.         (id)
  6508.    END
  6509.  
  6510.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSdistribution_agents' and type = 'U')
  6511.    BEGIN
  6512.         /****************************************************************************/
  6513.         raiserror('Creating table MSdistribution_agents', 0,1)
  6514.         /****************************************************************************/    
  6515.  
  6516.         CREATE TABLE dbo.MSdistribution_agents
  6517.         (
  6518.         id                  int IDENTITY NOT NULL,
  6519.         name                nvarchar(100) NOT NULL,
  6520.         publisher_database_id int NOT NULL,
  6521.         publisher_id        smallint NOT NULL,
  6522.         publisher_db        sysname NOT NULL,
  6523.         publication         sysname NOT NULL,
  6524.         subscriber_id       smallint NULL, 
  6525.         subscriber_db       sysname NULL,
  6526.         subscription_type   int NOT NULL,
  6527.         local_job           bit NULL,
  6528.         job_id              binary(16) NULL,
  6529.         subscription_guid   binary(16) NOT NULL,
  6530.         profile_id  int     NOT NULL,
  6531.         anonymous_subid     uniqueidentifier NULL,
  6532.         subscriber_name     sysname NULL,
  6533.         virtual_agent_id    int NULL,
  6534.         anonymous_agent_id  int NULL,
  6535.         creation_date        datetime default (getdate()) not NULL
  6536.         )
  6537.  
  6538.         EXEC dbo.sp_MS_marksystemobject 'MSdistribution_agents'
  6539.  
  6540.         raiserror('Creating clustered index ucMSdistribution_agents', 0,1)
  6541.         CREATE UNIQUE CLUSTERED INDEX ucMSdistribution_agents ON dbo.MSdistribution_agents
  6542.             (id)
  6543.  
  6544.         raiserror('Creatingindex iMSdistribution_agents', 0,1)
  6545.         CREATE INDEX iMSdistribution_agents ON dbo.MSdistribution_agents
  6546.             (publication, publisher_db, publisher_id, subscriber_id, subscriber_db, anonymous_subid) 
  6547.    END
  6548.  
  6549.     if not exists (select * from syscolumns where 
  6550.         id = object_id('MSdistribution_agents') and
  6551.         name = 'creation_date')
  6552.     begin
  6553.         alter table MSdistribution_agents add creation_date datetime default (getdate()) not null
  6554.     end 
  6555.  
  6556.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSmerge_agents' and type = 'U')
  6557.    BEGIN
  6558.         /****************************************************************************/
  6559.         raiserror('Creating table MSmerge_agents', 0,1)
  6560.         /****************************************************************************/    
  6561.  
  6562.         CREATE TABLE dbo.MSmerge_agents
  6563.         (
  6564.         id                  int IDENTITY NOT NULL,
  6565.         name                nvarchar(100) NOT NULL,
  6566.         publisher_id        smallint NOT NULL,
  6567.         publisher_db        sysname NOT NULL,
  6568.         publication         sysname NOT NULL,
  6569.         subscriber_id       smallint NULL,
  6570.         subscriber_db       sysname NULL,
  6571.         local_job           bit NULL,
  6572.         job_id              binary(16) NULL,
  6573.         profile_id          int NULL,
  6574.         anonymous_subid     uniqueidentifier NULL,
  6575.         subscriber_name     sysname NULL,
  6576.         creation_date        datetime default (getdate()) not NULL
  6577.         )
  6578.  
  6579.       EXEC dbo.sp_MS_marksystemobject 'MSmerge_agents'
  6580.  
  6581.     raiserror('Creating clustered index ucMSmerge_agents', 0,1)
  6582.     CREATE CLUSTERED INDEX ucMSmerge_agents ON dbo.MSmerge_agents
  6583.         (publication, publisher_db, publisher_id, subscriber_id, subscriber_db, anonymous_subid) 
  6584.     
  6585.     raiserror('Creatingindex iMSmerge_agents', 0,1)
  6586.     CREATE UNIQUE INDEX iMSmerge_agents ON dbo.MSmerge_agents
  6587.         (id)
  6588.     END
  6589.  
  6590.     if not exists (select * from syscolumns where 
  6591.         id = object_id('MSmerge_agents') and
  6592.         name = 'creation_date')
  6593.     begin
  6594.         alter table MSmerge_agents add creation_date datetime default (getdate()) not null
  6595.     end 
  6596.  
  6597.     IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSpublication_access' and type = 'U')
  6598.     BEGIN
  6599.         /****************************************************************************/
  6600.         raiserror('Creating table MSpublication_access', 0,1)
  6601.         /****************************************************************************/    
  6602.  
  6603.         CREATE TABLE dbo.MSpublication_access
  6604.         (
  6605.         publication_id      int NULL,       -- Publication_id is unique in distribution database.
  6606.         login               sysname NOT NULL
  6607.                                             -- Logins in the publication access list, they nust
  6608.                                             -- exist at both publisher and distributor side.            
  6609.         )
  6610.  
  6611.         EXEC dbo.sp_MS_marksystemobject 'MSpublication_access'
  6612.  
  6613.         raiserror('Creating clustered index ucMSpublication_access', 0,1)
  6614.         CREATE UNIQUE CLUSTERED INDEX ucMSpublication_access ON dbo.MSpublication_access
  6615.             (publication_id, login) 
  6616.     END
  6617.  
  6618.     -- For b3 upgrade
  6619.     if NOT EXISTS (select * from syscolumns where name='retention' and id=object_id('MSpublications'))
  6620.     begin
  6621.         alter table MSpublications add retention int NULL 
  6622.         UPDATE msdb..MSdistributiondbs set max_distretention=72 where
  6623.             name = db_name()
  6624.     end
  6625.  
  6626.     -- drop default_access column
  6627.     if exists (select * from syscolumns where id = object_id('MSpublications') and
  6628.         name = 'default_access')
  6629.     begin
  6630.         alter table MSpublications drop column default_access
  6631.     end 
  6632.  
  6633.     -- Drop publisher_id column
  6634.     if EXISTS (select * from syscolumns where name='publisher_id' and id=object_id('MSpublication_access'))
  6635.     begin
  6636.         drop index MSpublication_access.ucMSpublication_access
  6637.  
  6638.         alter table MSpublication_access drop column publisher_id
  6639.  
  6640.         raiserror('Creating clustered index ucMSpublication_access', 0,1)
  6641.         CREATE UNIQUE CLUSTERED INDEX ucMSpublication_access ON dbo.MSpublication_access
  6642.         (publication_id, login) 
  6643.     end
  6644.  
  6645.  
  6646. GO
  6647.  
  6648. --------------------------------------------------------------------------------
  6649. --. sp_adddistributor
  6650. --------------------------------------------------------------------------------
  6651. if exists (select * from sysobjects    where type = 'P'
  6652.     and name = 'sp_adddistributor')
  6653.     drop procedure sp_adddistributor
  6654. go
  6655.  
  6656. raiserror('Creating procedure sp_adddistributor', 0,1)
  6657. go
  6658.  
  6659. CREATE PROCEDURE sp_adddistributor (
  6660.     @distributor sysname,            /* distributor server name */
  6661.     @heartbeat_interval int = 10,    -- minutes
  6662.     @password sysname = NULL
  6663.  
  6664. ) AS
  6665.  
  6666.     SET NOCOUNT ON
  6667.  
  6668.     /*
  6669.     ** Declarations.
  6670.     */
  6671.     DECLARE @retcode int
  6672.     DECLARE @agentname nvarchar(100)
  6673.     DECLARE @command nvarchar(255)
  6674.     DECLARE @distribution_db sysname
  6675.     DECLARE @distproc nvarchar(255)
  6676.     DECLARE @dist_rpcname sysname
  6677.     DECLARE @server_added bit
  6678.     declare @login sysname
  6679.  
  6680.     select @server_added = 0 
  6681.     select @login = 'distributor_admin'
  6682.  
  6683.     /* 
  6684.     ** Check if replication components are installed on this server
  6685.     */
  6686.     exec @retcode = dbo.sp_MS_replication_installed
  6687.     if (@retcode <> 1)
  6688.     begin
  6689.         return (1)
  6690.     end
  6691.  
  6692.     -- Must be at master db.
  6693.     IF db_name() <> 'master'
  6694.     BEGIN
  6695.         RAISERROR(5001, 16,-1)
  6696.         return (1)
  6697.     END
  6698.     /*
  6699.     ** Parameter Check:  @distributor.
  6700.     ** Check to make sure that the distributor is not NULL and that it
  6701.     ** conforms to the rules for identifiers.
  6702.     */
  6703.     IF @distributor IS NULL
  6704.         BEGIN
  6705.             RAISERROR (14043, 16, -1, '@distributor')
  6706.             RETURN (1)
  6707.         END
  6708.  
  6709.     EXECUTE @retcode = dbo.sp_validname @distributor
  6710.  
  6711.     IF @@ERROR <> 0 OR @retcode <> 0
  6712.        RETURN (1)
  6713.  
  6714.     IF @password = N''
  6715.         select @password = NULL
  6716.     
  6717.     -- Seed default password with random value only for a local distributor.
  6718.     IF (@password is null) AND (UPPER(@@SERVERNAME) = UPPER(@distributor))
  6719.         select @password = convert(sysname, newid())
  6720.     /*
  6721.     ** Check to make sure that the distributor doesn't already exist.
  6722.     */
  6723.     SELECT @dist_rpcname = NULL
  6724.     SELECT @dist_rpcname = srvname FROM master..sysservers
  6725.               WHERE  srvstatus & 8 <> 0
  6726.     IF @dist_rpcname IS NOT NULL
  6727.     BEGIN
  6728.         RAISERROR (14099, 16, -1, @dist_rpcname)
  6729.         RETURN(1)
  6730.     END
  6731.  
  6732.     -- drop repl_distributor if it exists.
  6733.     if exists (select * from master..sysservers where lower(srvname) = 
  6734.         'repl_distributor')
  6735.     begin
  6736.         exec @retcode = dbo.sp_dropserver 'repl_distributor', 'droplogins'
  6737.         IF @@error <> 0 OR @retcode <> 0
  6738.         BEGIN
  6739.             RETURN(1)
  6740.         END
  6741.     end
  6742.  
  6743.     -- Add the linked server entry for the distributor
  6744.     -- Note we do this even for local server for consistancy
  6745.     EXECUTE @retcode = dbo.sp_addserver  'repl_distributor'
  6746.     IF @@error <> 0 OR @retcode <> 0
  6747.     BEGIN
  6748.         RETURN (1)
  6749.     END
  6750.  
  6751.     select @server_added = 1
  6752.  
  6753.     -- Mark system link
  6754.     EXECUTE @retcode = dbo.sp_serveroption  'repl_distributor', 'system','true'
  6755.     IF @@error <> 0 OR @retcode <> 0
  6756.     BEGIN
  6757.         RETURN (1)
  6758.     END
  6759.  
  6760.     EXECUTE @retcode = dbo.sp_setnetname  'repl_distributor', @distributor
  6761.     IF @@error <> 0 OR @retcode <> 0
  6762.     BEGIN
  6763.         goto UNDO
  6764.     END
  6765.         
  6766.     exec @retcode = dbo.sp_addlinkedsrvlogin 
  6767.         @rmtsrvname= 'repl_distributor',
  6768.         @useself = 'false',
  6769.         @locallogin = NULL,
  6770.         @rmtuser = @login,
  6771.         @rmtpassword = @password
  6772.     IF @@error <> 0 OR @retcode <> 0
  6773.     BEGIN
  6774.         goto UNDO
  6775.     END
  6776.  
  6777.  
  6778.     /*
  6779.     ** If this is not the local server, remote distributor must be set up first
  6780.     */
  6781.     IF UPPER(@distributor) <> UPPER(@@SERVERNAME)
  6782.     BEGIN
  6783.         /*
  6784.         ** Test to see if the local server is defined as publisher
  6785.         ** at the remove distributor.
  6786.         ** Note: cannot call sp_helpdistributor locally since the server is not
  6787.         ** marked for distribution.
  6788.         ** We can not move the serveroption call before this RPC because RPC failure
  6789.         ** may cause the SP to terminate. Thus, we can not UNDO the server option.
  6790.         ** give all parameters to work around SQL SERVER 7.0 rpc named param bug.
  6791.         */
  6792.         SELECT @distproc = 'repl_distributor.master.dbo.sp_helpdistributor'
  6793.     
  6794.         DECLARE @loc_directory             nvarchar(255)
  6795.         DECLARE @loc_account             nvarchar(255)
  6796.         DECLARE @loc_mindistretention     int
  6797.         DECLARE @loc_maxdistretention     int
  6798.         DECLARE @loc_historyretention   int  
  6799.         DECLARE @loc_historycleanupagent nvarchar(100)
  6800.         DECLARE @loc_distribcleanupagent nvarchar(100)
  6801.         DECLARE @alert_name nvarchar(100)
  6802.         DECLARE @alert_id int
  6803.  
  6804.         EXECUTE @distproc
  6805.             @distributor OUTPUT,
  6806.             @distribution_db OUTPUT,
  6807.             @loc_directory OUTPUT,
  6808.             @loc_account OUTPUT,
  6809.             @loc_mindistretention OUTPUT,
  6810.             @loc_maxdistretention OUTPUT,
  6811.             @loc_historyretention OUTPUT,
  6812.             @loc_historycleanupagent OUTPUT,
  6813.             @loc_distribcleanupagent OUTPUT,
  6814.             @@SERVERNAME,
  6815.             @local = 'local'
  6816.  
  6817.         IF @@error <> 0 OR @retcode <> 0 OR @distribution_db is NULL
  6818.         BEGIN
  6819.             RAISERROR (21007,16,-1)
  6820.             GOTO UNDO
  6821.         END
  6822.  
  6823.         /* Activate the dist publisher at the remote distributor */
  6824.         SELECT @distproc = 'repl_distributor.master.dbo.sp_changedistpublisher'
  6825.             EXECUTE @retcode = @distproc @@SERVERNAME, 'active','true'
  6826.         IF @@error <> 0 OR @retcode <> 0
  6827.         BEGIN
  6828.             GOTO UNDO
  6829.         END
  6830.     END
  6831.     ELSE
  6832.     /* set the registry */
  6833.     BEGIN
  6834.         EXEC @retcode = dbo.sp_MScreate_distributor_tables 
  6835.         if @@error <> 0 or @retcode <> 0
  6836.             goto UNDO
  6837.  
  6838.         declare @distributor_login sysname
  6839.         select @distributor_login = 'distributor_admin'
  6840.  
  6841.         -- Add publisher rpc login
  6842.         if not exists (select * from master..syslogins where loginname = @distributor_login)
  6843.         begin
  6844.             EXEC @retcode = dbo.sp_addlogin @loginame = @distributor_login,
  6845.                 @passwd = @password
  6846.             if @@error <> 0 or @retcode <> 0
  6847.                 goto UNDO
  6848.         end
  6849.         else
  6850.         begin
  6851.             -- Change the password if the distributor is local
  6852.             EXEC @retcode = dbo.sp_password NULL, @password, 'distributor_admin'
  6853.             if @@error <> 0 or @retcode <> 0
  6854.                 goto UNDO
  6855.         end
  6856.  
  6857.         -- Add the login to sysadmin
  6858.         -- Refer to sp_MSpublication_access in distribution db
  6859.         if is_srvrolemember('sysadmin', @distributor_login) <> 1
  6860.         begin
  6861.             exec @retcode = dbo.sp_addsrvrolemember @distributor_login, 'sysadmin'
  6862.             IF @@error <> 0 OR @retcode <> 0
  6863.                 GOTO UNDO
  6864.         end
  6865.  
  6866.         -- Add Replication Agent Checkup Agent
  6867.         exec @retcode = dbo.sp_MScreate_replication_checkup_agent @heartbeat_interval = @heartbeat_interval
  6868.         if @@error <> 0 or @retcode <> 0
  6869.             goto UNDO
  6870.         
  6871.         delete msdb..MSdistributor where property = 'heartbeat_interval'
  6872.         if @@error <> 0
  6873.             goto UNDO
  6874.         insert into msdb..MSdistributor (property, value) values ('heartbeat_interval',
  6875.             convert(nvarchar(10), @heartbeat_interval))
  6876.         if @@error <> 0 
  6877.             goto UNDO
  6878.  
  6879.         -- Add Replication Alerts and Response Jobs
  6880.         exec @retcode = dbo.sp_MSadd_distributor_alerts_and_responses
  6881.         if @@error <> 0 or @retcode <> 0
  6882.             goto UNDO
  6883.     
  6884.     END
  6885.  
  6886.  
  6887.     /*
  6888.     ** Set the server option to indicate that this is a distributor.
  6889.     ** 
  6890.     */
  6891.     EXECUTE @retcode = dbo.sp_serveroption 'repl_distributor', 'dist', true
  6892.     IF @@error <> 0 OR @retcode <> 0
  6893.     BEGIN
  6894.         GOTO UNDO
  6895.     END
  6896.  
  6897.     -- Set sp_MSrepl_startup to be a startup stored procedure
  6898.     -- Note: This needs to be after the marking the distribution server
  6899.     exec @retcode = dbo.sp_procoption 'sp_MSrepl_startup', 'startup', 'true' 
  6900.     if @@error <> 0 or @retcode <> 0
  6901.         goto UNDO1
  6902.  
  6903.     exec @retcode = dbo.sp_MSrepl_startup
  6904.     if @@error <> 0 or @retcode <> 0
  6905.         goto UNDO1
  6906.  
  6907.     RETURN (0)
  6908.  
  6909. UNDO1:
  6910.     exec dbo.sp_serveroption 'repl_distributor', 'dist', false
  6911.  
  6912. UNDO:
  6913.     IF @server_added = 1
  6914.     begin
  6915.         -- Drop the remote logins, otherwise, sp_dropserver will fail.
  6916.         EXECUTE dbo.sp_dropserver 'repl_distributor', 'droplogins'
  6917.     end
  6918.     
  6919.     RETURN (1)
  6920. GO
  6921.  
  6922. --------------------------------------------------------------------------------
  6923. --. sp_changedistributiondb
  6924. --------------------------------------------------------------------------------
  6925. if exists (select * from sysobjects    where type = 'P'
  6926.     and name = 'sp_changedistributiondb')
  6927.     drop procedure sp_changedistributiondb
  6928. go
  6929.  
  6930. raiserror('Creating procedure sp_changedistributiondb', 0,1)
  6931. go
  6932.  
  6933. CREATE PROCEDURE sp_changedistributiondb (
  6934.     @database sysname,
  6935.     @property sysname     = NULL,     /* The property to change */
  6936.     @value nvarchar(255)     = NULL      /* The new property value */
  6937.     ) AS
  6938.  
  6939.     SET NOCOUNT ON
  6940.  
  6941.     /*
  6942.     ** Declarations.
  6943.     */
  6944.     DECLARE @distributor sysname
  6945.     DECLARE @min_distretention     int
  6946.     DECLARE @max_distretention     int
  6947.     DECLARE @retcode             int
  6948.     DECLARE @new_min_distretention     int
  6949.     DECLARE @new_max_distretention     int
  6950.     DECLARE @new_history_retention     int
  6951.     DECLARE @agentname nvarchar(100)
  6952.     DECLARE @command nvarchar(255)
  6953.     DECLARE @security_mode int
  6954.     DECLARE @distbit int
  6955.  
  6956.     SELECT @distbit = 16
  6957.  
  6958.     /*
  6959.     ** Parameter Check:  @property.
  6960.     ** If the @property parameter is NULL, print the options.
  6961.     */
  6962.  
  6963.     IF @property IS NULL
  6964.         BEGIN
  6965.             CREATE TABLE #tab1 (properties sysname NOT NULL)
  6966.             INSERT INTO #tab1 VALUES ('min_distretention')
  6967.             INSERT INTO #tab1 VALUES ('max_distretention')
  6968.             INSERT INTO #tab1 VALUES ('history_retention')
  6969.             SELECT * FROM #tab1
  6970.             RETURN (0)
  6971.         END
  6972.  
  6973.     /*
  6974.     ** Parameter Check:  @property.
  6975.     ** Check to make sure that @property is a valid property in
  6976.     ** sysarticles.
  6977.     */
  6978.     IF @property IS NULL OR LOWER(@property) NOT IN ('min_distretention',
  6979.                                                      'max_distretention',
  6980.                                                      'history_retention')
  6981.              
  6982.         BEGIN
  6983.  
  6984.             RAISERROR (14115, 16, -1, 
  6985.             '''min_distretention'', ''max_distretention'' or ''history_retention''')
  6986.             RETURN (1)
  6987.         END
  6988.  
  6989.  
  6990.     /*
  6991.     ** Check to make sure this is a distributor
  6992.     */
  6993.     IF NOT EXISTS (SELECT * FROM master..sysservers
  6994.               WHERE UPPER(datasource) = UPPER(@@SERVERNAME)
  6995.                  AND srvstatus & 8 <> 0)
  6996.     BEGIN
  6997.         RAISERROR (14114, 16, -1, @@SERVERNAME)
  6998.         RETURN(1)
  6999.     END
  7000.  
  7001.     /*
  7002.     ** Check if database is configured as a distributor database
  7003.     */
  7004.     IF NOT EXISTS (SELECT * FROM master..sysdatabases
  7005.               WHERE name = @database
  7006.                  AND category & @distbit <> 0)
  7007.     BEGIN
  7008.         RAISERROR (14117, 16, -1, @database)
  7009.         RETURN(1)
  7010.     END
  7011.     
  7012.     /*
  7013.     ** Change the property.
  7014.     */
  7015.     IF LOWER(@property) = 'min_distretention'
  7016.         BEGIN
  7017.             IF @value IS NULL
  7018.                 BEGIN
  7019.                     RAISERROR (14043, 16, -1, '@value') 
  7020.                     RETURN (1)
  7021.                 END
  7022.  
  7023.             /*
  7024.             ** Set the MinDistRetention registry key value
  7025.             */
  7026.             SELECT @new_min_distretention = CONVERT(int, @value)
  7027.  
  7028.             /*
  7029.             ** Get MaxDistRetention value
  7030.             */
  7031.             SELECT @max_distretention = max_distretention FROM msdb..MSdistributiondbs
  7032.                 WHERE name = @database
  7033.                 
  7034.             /* 
  7035.             ** Check for invalid retention values 
  7036.             */
  7037.             IF @new_min_distretention < 0
  7038.                 BEGIN
  7039.                        RAISERROR(14106, 16, -1)
  7040.                     RETURN (1)
  7041.                 END
  7042.             IF @new_min_distretention > @max_distretention
  7043.                 BEGIN
  7044.                     RAISERROR(14107, 16, -1) 
  7045.                     RETURN (1)
  7046.                 END
  7047.  
  7048.             UPDATE msdb..MSdistributiondbs SET min_distretention = @new_min_distretention
  7049.                 WHERE name = @database
  7050.             IF @@error <> 0 
  7051.                 BEGIN
  7052.                     RETURN (1)
  7053.                 END
  7054.  
  7055.             /*
  7056.             ** Update Distribution Cleanup agent 
  7057.             */
  7058.             select @agentname = name from msdb..sysjobs j, msdb..sysjobsteps s where 
  7059.             j.job_id = s.job_id and
  7060.             j.category_id = 11 and
  7061.             s.database_name = @database
  7062.         
  7063.             SELECT @command =  'EXEC dbo.sp_MSdistribution_cleanup @min_distretention = ' + 
  7064.                 CONVERT(nvarchar(12), @new_min_distretention) + ', @max_distretention = ' +
  7065.                 CONVERT(nvarchar(12), @max_distretention)
  7066.             EXEC @retcode = msdb.dbo.sp_update_jobstep @job_name = @agentname, @step_id = 1, 
  7067.                 @command = @command
  7068.             IF @@error <> 0 OR @retcode <> 0
  7069.                RETURN(1)
  7070.  
  7071.         END
  7072.  
  7073.     IF LOWER(@property) = 'max_distretention'
  7074.         BEGIN
  7075.             IF @value IS NULL
  7076.                 BEGIN
  7077.                     RAISERROR (14043, 16, -1, '@value') 
  7078.                     RETURN (1)
  7079.                 END
  7080.  
  7081.             /*
  7082.             ** Set the MaxDistRetention registry key value
  7083.             */
  7084.             SELECT @new_max_distretention = CONVERT(int, @value)
  7085.  
  7086.             /*
  7087.             ** Get MinDistRetention value
  7088.             */
  7089.             SELECT @min_distretention = min_distretention FROM msdb..MSdistributiondbs
  7090.                 WHERE name = @database
  7091.  
  7092.             /* 
  7093.             ** Check for invalid retention values 
  7094.             */
  7095.             IF @new_max_distretention < 0
  7096.                 BEGIN
  7097.                        RAISERROR(14106, 16, -1)
  7098.                     RETURN (1)
  7099.                 END
  7100.             IF @new_max_distretention < @min_distretention
  7101.                 BEGIN
  7102.                     RAISERROR(14107, 16, -1) 
  7103.                     RETURN (1)
  7104.                 END
  7105.  
  7106.             UPDATE msdb..MSdistributiondbs SET max_distretention = @new_max_distretention
  7107.                 WHERE name = @database
  7108.             IF @@error <> 0 
  7109.                 BEGIN
  7110.                     RETURN (1)
  7111.                 END
  7112.             /*
  7113.             ** Update Distribution Cleanup agent 
  7114.             */
  7115.             select @agentname = name from msdb..sysjobs j, msdb..sysjobsteps s where 
  7116.                 j.job_id = s.job_id and
  7117.                 j.category_id = 11 and
  7118.                 s.database_name = @database
  7119.             SELECT @command =  'EXEC dbo.sp_MSdistribution_cleanup @min_distretention = ' + 
  7120.                 CONVERT(nvarchar(12), @min_distretention) + ', @max_distretention = ' +
  7121.                 CONVERT(nvarchar(12), @new_max_distretention)
  7122.             EXEC @retcode = msdb.dbo.sp_update_jobstep @job_name = @agentname, @step_id = 1, 
  7123.                 @command = @command
  7124.             IF @@error <> 0 OR @retcode <> 0
  7125.                RETURN(1)
  7126.         END
  7127.  
  7128.     IF LOWER(@property) = 'history_retention'
  7129.         BEGIN
  7130.             IF @value IS NULL
  7131.                 BEGIN
  7132.                     RAISERROR (14043, 16, -1, '@value') 
  7133.                     RETURN (1)
  7134.                 END
  7135.  
  7136.             /*
  7137.             ** Set the HistoryRetention registry key value
  7138.             */
  7139.             SELECT @new_history_retention = CONVERT(int, @value)
  7140.  
  7141.             UPDATE msdb..MSdistributiondbs SET history_retention = @new_history_retention
  7142.                 WHERE name = @database
  7143.             IF @@error <> 0 
  7144.                 BEGIN
  7145.                     RETURN (1)
  7146.                 END
  7147.  
  7148.             /*
  7149.             ** Update History Cleanup agent 
  7150.             */
  7151.             select @agentname = name from msdb..sysjobs j, msdb..sysjobsteps s where 
  7152.                 j.job_id = s.job_id and
  7153.                 j.category_id = 12 and
  7154.                 s.database_name = @database
  7155.             SELECT @command =  'EXEC dbo.sp_MShistory_cleanup @history_retention = ' + 
  7156.                 CONVERT(nvarchar(12), @new_history_retention)
  7157.             EXEC @retcode = msdb.dbo.sp_update_jobstep @job_name = @agentname, @step_id = 1, 
  7158.                 @command = @command
  7159.             IF @@error <> 0 OR @retcode <> 0
  7160.                RETURN(1)
  7161.  
  7162.         END
  7163.  
  7164.  
  7165.  
  7166.  
  7167.     /*
  7168.     ** Return succeed.
  7169.     */
  7170.     RAISERROR (14105, 10, -1, @property)
  7171.     RETURN (0)
  7172. go
  7173.  
  7174. --------------------------------------------------------------------------------
  7175. --. sp_dropdistributiondb
  7176. --------------------------------------------------------------------------------
  7177. if exists (select * from sysobjects    where type = 'P'
  7178.     and name = 'sp_dropdistributiondb')
  7179.     drop procedure sp_dropdistributiondb
  7180. go
  7181.  
  7182. raiserror('Creating procedure sp_dropdistributiondb', 0,1)
  7183. go
  7184.  
  7185. CREATE PROCEDURE sp_dropdistributiondb (
  7186.     @database sysname        
  7187.     
  7188. ) AS
  7189.  
  7190.     SET NOCOUNT ON
  7191.     /*
  7192.     ** Declarations.
  7193.     */
  7194.     DECLARE @retcode int
  7195.     DECLARE @agentname nvarchar(100)
  7196.     DECLARE @reg_key nvarchar(255)
  7197.     DECLARE @security_mode int
  7198.     DECLARE    @distbit int
  7199.     DECLARE @distpublisher sysname
  7200.     DECLARE @distdb sysname
  7201.     DECLARE @device_name sysname
  7202.     DECLARE @command nvarchar(255)
  7203.  
  7204.     SELECT @distbit = 16
  7205.  
  7206.     /*
  7207.     ** Check to make sure this is a distributor
  7208.     */
  7209.     IF NOT EXISTS (SELECT * FROM master..sysservers
  7210.               WHERE UPPER(datasource) = UPPER(@@SERVERNAME)
  7211.                  AND srvstatus & 8 <> 0)
  7212.     BEGIN
  7213.         RAISERROR (14114, 16, -1, @@SERVERNAME)
  7214.         RETURN(1)
  7215.     END
  7216.  
  7217.     /*
  7218.     ** Check if database is configured as a distributor database
  7219.     */
  7220.     IF NOT EXISTS (SELECT * FROM msdb..MSdistributiondbs WHERE name = @database)
  7221.     BEGIN
  7222.         RAISERROR (14117, 16, -1, @database)
  7223.         RETURN(1)
  7224.     END
  7225.  
  7226.     /*
  7227.     ** Check if any DistPublishers are using this database
  7228.     */
  7229.     IF EXISTS (SELECT * FROM msdb..MSdistpublishers WHERE
  7230.         distribution_db = @database)
  7231.     BEGIN
  7232.         RAISERROR (14120, 16, -1, @database)
  7233.         RETURN (1)
  7234.     END
  7235.     
  7236.     /*
  7237.     ** Check if the DB is being currently used
  7238.     */
  7239.     IF EXISTS (SELECT * FROM master..sysprocesses WHERE
  7240.         dbid = DB_ID(@database))
  7241.     BEGIN
  7242.         RAISERROR (21122, 16, 1, @database)
  7243.         RETURN (1)
  7244.     END
  7245.        
  7246.  
  7247.     /*
  7248.     ** Drop the history cleanup agent.
  7249.     */
  7250.     -- Get agent name
  7251.     select @agentname = null
  7252.     select @agentname = name from msdb..sysjobs j, msdb..sysjobsteps s where 
  7253.         j.job_id = s.job_id and
  7254.         j.category_id = 12 and
  7255.         s.database_name = @database
  7256.  
  7257.     if @agentname is not null
  7258.     BEGIN
  7259.         EXEC @retcode = msdb.dbo.sp_delete_job 
  7260.             @job_name = @agentname
  7261.         IF @@ERROR <> 0 or @retcode <> 0
  7262.         BEGIN
  7263.             RETURN(1)
  7264.         END
  7265.     END
  7266.  
  7267.     /*
  7268.     ** Drop the distribution cleanup agent.
  7269.     */
  7270.     select @agentname = null
  7271.     select @agentname = name from msdb..sysjobs j, msdb..sysjobsteps s where 
  7272.                 j.job_id = s.job_id and
  7273.                 j.category_id = 11 and
  7274.                 s.database_name = @database
  7275.     if @agentname is not null
  7276.     BEGIN
  7277.         EXEC @retcode = msdb.dbo.sp_delete_job 
  7278.             @job_name = @agentname
  7279.         IF @@ERROR <> 0 or @retcode <> 0
  7280.         BEGIN
  7281.             RETURN(1)
  7282.         END
  7283.     END
  7284.  
  7285.     /*
  7286.     ** Update sysdatabase category bit before dropping the database
  7287.     ** Otherwise, the database can not be dropped.
  7288.     **
  7289.     */
  7290.     UPDATE master..sysdatabases SET category = category & ~@distbit WHERE name = @database
  7291.     IF @@ERROR <> 0
  7292.         BEGIN
  7293.             RETURN (1)
  7294.         END
  7295.  
  7296.  
  7297.     -- Drop the distributor db if it exists
  7298.     IF EXISTS (SELECT * FROM master..sysdatabases WHERE name = @database)
  7299.     BEGIN
  7300.  
  7301.         CREATE TABLE #db_existed
  7302.         (
  7303.         db_existed bit  NOT NULL
  7304.         )
  7305.  
  7306.         /* Get version stamp */
  7307.         SELECT @command = 'INSERT INTO #db_existed SELECT db_existed FROM ' +
  7308.             QUOTENAME(@database) + '..MSrepl_version'
  7309.     
  7310.         EXEC(@command)
  7311.         IF @@ERROR <> 0
  7312.         BEGIN
  7313.             RETURN(1)       
  7314.         END
  7315.  
  7316.         -- Drop the distribution db only if it is created in sp_adddistributiondb.
  7317.         IF NOT EXISTS (SELECT * FROM #db_existed where db_existed = 0x1)
  7318.         BEGIN
  7319.  
  7320.             -- we're dropping the database, so don't bother to clean up
  7321.             -- individual records.  Just make sure we blow away the synchronization
  7322.             -- files & directories hosted by the file system.
  7323.  
  7324.             SELECT @command = QUOTENAME(@database) + '.dbo.sp_MSdrop_snapshot_dirs'
  7325.             SELECT @command = 'EXEC ' + @command
  7326.             EXEC (@command)
  7327.             IF (@@ERROR <> 0)
  7328.             BEGIN
  7329.                 RETURN (1)
  7330.             END
  7331.     
  7332.             /* Save the device info before dropping the database */
  7333.             CREATE TABLE #distdbdevices (name sysname  NOT NULL)
  7334.  
  7335.             /* Drop distributor devices */
  7336.             /* Query is copied from sp_helpdb */
  7337.             SELECT @command = 
  7338.                 'INSERT INTO #distdbdevices select DISTINCT name from ' + QUOTENAME(@database) + '.dbo.sysfiles'
  7339.             EXEC (@command)
  7340.             IF @@ERROR <>0
  7341.             BEGIN
  7342.                 RETURN(1)      
  7343.             END
  7344.  
  7345.             /*
  7346.             ** Drop the distribution database
  7347.             */
  7348.             SELECT @command = 'drop database ' + QUOTENAME(@database)
  7349.             EXEC (@command)
  7350.             IF @@ERROR <> 0
  7351.                 BEGIN
  7352.                     /* Mark the database as distribution database again 
  7353.                     ** Otherwise, this sp will fail when it is reentered.
  7354.                     ** It is often the case that if there's an open session
  7355.                     ** on the database, it can not be dropped.
  7356.                     */
  7357.                     RETURN(1)
  7358.                 END
  7359.  
  7360.             /* Drop distributor devices */
  7361.             /* Query is copied from sp_helpdb */
  7362.             /* SQL SERVER 7.0 may drop some auto generated device files, drop drop them here
  7363.                again
  7364.             */
  7365.             DECLARE hCdropdistributiondb CURSOR LOCAL FAST_FORWARD FOR
  7366.                 SELECT DISTINCT dd.name FROM #distdbdevices dd, master.dbo.sysdevices ss
  7367.                     WHERE ss.name = dd.name
  7368.             FOR READ ONLY
  7369.     
  7370.             OPEN hCdropdistributiondb
  7371.             FETCH hCdropdistributiondb INTO @device_name
  7372.  
  7373.             WHILE (@@fetch_status <> -1)
  7374.             BEGIN
  7375.                 /* 
  7376.                 ** Device may be used by other databases
  7377.                 ** Ignore all errors 
  7378.                 */
  7379.                 EXEC dbo.sp_dropdevice @device_name, DELFILE
  7380.                 FETCH hCdropdistributiondb INTO @device_name
  7381.             END
  7382.  
  7383.             CLOSE hCdropdistributiondb
  7384.             DEALLOCATE hCdropdistributiondb
  7385.  
  7386.         END
  7387.         -- else, database did exist before it was made the distributor, 
  7388.         -- do full cleanup
  7389.         ELSE
  7390.         BEGIN
  7391.  
  7392.             -- run 'fast clean' routine first. this removes repldata files
  7393.             -- and truncates MSrepl_transactions/commands
  7394.  
  7395.             SELECT @command = QUOTENAME(@database) + '.dbo.sp_MSfast_delete_trans'
  7396.             SELECT @command = 'EXEC ' + @command
  7397.             EXEC (@command)
  7398.             IF (@@ERROR <> 0)
  7399.             BEGIN
  7400.                 RETURN (1)
  7401.             END
  7402.  
  7403.             -- Do distribution cleanup the final time
  7404.             -- this handles those fiddly agent tables & such
  7405.             -- ( and would delete commands/xacts if we hadn't already purged 'em )
  7406.  
  7407.             SELECT @command = QUOTENAME(@database) + 
  7408.                 '.dbo.sp_MSdistribution_cleanup @min_distretention = 0, @max_distretention = 0'
  7409.             SELECT @command = 'EXEC ' + @command
  7410.             EXEC (@command)
  7411.             IF (@@ERROR <> 0)
  7412.             BEGIN
  7413.                 RETURN (1)
  7414.             END
  7415.         END
  7416.     END
  7417.     
  7418.  
  7419.     /*
  7420.     ** Delete the DistributionDB entry
  7421.     */
  7422.  
  7423.     DELETE msdb.dbo.MSdistributiondbs where name = @database
  7424.     IF @@error <> 0
  7425.     BEGIN
  7426.         RETURN(1)
  7427.     END
  7428.     
  7429.  
  7430.     RETURN (0)
  7431.                 
  7432. GO
  7433.  
  7434. --------------------------------------------------------------------------------
  7435. --. sp_MSupdate_replication_status
  7436. --------------------------------------------------------------------------------
  7437. if exists (select * from sysobjects    where type = 'P'
  7438.     and name = 'sp_MSupdate_replication_status')
  7439.     drop procedure sp_MSupdate_replication_status
  7440. go
  7441.  
  7442. raiserror('Creating procedure sp_MSupdate_replication_status', 0,1)
  7443. go
  7444.  
  7445. create procedure sp_MSupdate_replication_status
  7446. @publisher sysname,
  7447. @publisher_db sysname,
  7448. @publication sysname,
  7449. @publication_type int = 0,      -- 0 Transactional/Snapshot 1 Merge
  7450. @agent_type int,
  7451. @agent_name nvarchar(100),
  7452. @status int
  7453. as
  7454.  
  7455.     declare @deleted int
  7456.     declare @refresh int
  7457.     declare @getstatus int
  7458.     declare @dummy int
  7459.  
  7460.  
  7461.     set @deleted = -1
  7462.     set @refresh = -2            -- Status used to only update the timestamp column
  7463.     set @getstatus = -3            -- Get status of agent for dummy distribution row
  7464.  
  7465.     if (select object_id('tempdb.dbo.MSreplication_agent_status')) is NULL
  7466.         return 0
  7467.  
  7468.     if @status = @getstatus
  7469.     begin
  7470.         select @status = isnull(status, 0) from tempdb.dbo.MSreplication_agent_status where
  7471.             UPPER(publisher) = UPPER(@publisher) and
  7472.             publisher_db = @publisher_db and
  7473.             publication = 'ALL' and
  7474.             agent_type = @agent_type
  7475.     end            
  7476.  
  7477.     -- Update timestamp column via dummy update
  7478.     if @status = @refresh
  7479.     begin
  7480.         -- Dummy update to force timestamps to be updated.
  7481.         update tempdb.dbo.MSreplication_agent_status set status = status where
  7482.             UPPER(publisher) = UPPER(@publisher) and
  7483.             publisher_db = @publisher_db and
  7484.             publication like @publication -- Must use like as publication may be "%"
  7485.         return (0)
  7486.     end
  7487.  
  7488.     -- Remove row if @deleted
  7489.     if @status = @deleted
  7490.     begin
  7491.         if @@trancount > 0
  7492.         begin
  7493.             if exists (select * from tempdb.dbo.MSreplication_agent_status with (TABLOCKX) where 1 = 1)
  7494.             begin
  7495.                 select @dummy = 1
  7496.             end
  7497.         end
  7498.  
  7499.         if @agent_name = '%'
  7500.             delete from tempdb.dbo.MSreplication_agent_status with (TABLOCKX) where
  7501.                 UPPER(publisher) = UPPER(@publisher) and
  7502.                 publisher_db = @publisher_db and
  7503.                 publication = @publication and
  7504.                 agent_type = @agent_type 
  7505.         else if @agent_name = NULL    -- Special case when all agents of the type are dropped
  7506.             delete from tempdb.dbo.MSreplication_agent_status with (TABLOCKX) where
  7507.                 UPPER(publisher) = UPPER(@publisher) and
  7508.                 publisher_db = @publisher_db and
  7509.                 publication = @publication and
  7510.                 agent_type = @agent_type
  7511.         else
  7512.             delete from tempdb.dbo.MSreplication_agent_status with (TABLOCKX) where
  7513.                 UPPER(publisher) = UPPER(@publisher) and
  7514.                 publisher_db = @publisher_db and
  7515.                 publication = @publication and
  7516.                 agent_type = @agent_type and
  7517.                 agent_name = @agent_name
  7518.  
  7519.         -- Dummy update to force timestamps to be updated.  This will signal a row has been
  7520.         -- removed.
  7521.         update tempdb.dbo.MSreplication_agent_status set status = status where
  7522.             UPPER(publisher) = UPPER(@publisher) and
  7523.             publisher_db = @publisher_db and
  7524.             publication = @publication
  7525.         return (0)
  7526.     end     
  7527.  
  7528.     -- If misc. replication job then the status needs to be mapped.
  7529.     if @agent_type = 5
  7530.     begin
  7531.         set @status = 
  7532.         case isnull(@status,5)    -- mapped to never run
  7533.             when 0 then 6   -- Fail mapping
  7534.             when 1 then 2   -- Success mapping
  7535.             when 2 then 5   -- Retry mapping
  7536.             when 3 then 2   -- Shutdown mapping
  7537.             when 4 then 3   -- Inprogress mapping
  7538.             when 5 then 0   -- Unknown is mapped to never run
  7539.         end
  7540.     end
  7541.  
  7542.     if not exists (select * from tempdb.dbo.MSreplication_agent_status with (NOLOCK) where 
  7543.         UPPER(publisher) = UPPER(@publisher) and
  7544.         publisher_db = @publisher_db and
  7545.         publication = @publication and
  7546.         agent_type = @agent_type and
  7547.         agent_name = @agent_name)
  7548.         begin
  7549.             if @@trancount > 0
  7550.             begin
  7551.                 if exists (select * from tempdb.dbo.MSreplication_agent_status with (TABLOCKX) where 1 = 1)
  7552.                 begin
  7553.                     select @dummy = 1
  7554.                 end
  7555.             end
  7556.  
  7557.             insert into tempdb.dbo.MSreplication_agent_status 
  7558.                 (publisher, publisher_db, publication, publication_type, agent_type, status, agent_name) values
  7559.                 (@publisher, @publisher_db, @publication, @publication_type, @agent_type, @status, @agent_name)
  7560.             -- Dummy update to force timestamps to be updated.  This will signal a row has been
  7561.             -- added.
  7562.             update tempdb.dbo.MSreplication_agent_status set status = status where
  7563.                 UPPER(publisher) = UPPER(@publisher) and
  7564.                 publisher_db = @publisher_db and
  7565.                 publication = @publication
  7566.         end
  7567.     else
  7568.         begin
  7569.             update tempdb.dbo.MSreplication_agent_status set status = @status where
  7570.                 UPPER(publisher) = UPPER(@publisher) and
  7571.                 publisher_db = @publisher_db and
  7572.                 (publication = @publication or @publication = 'ALL')and
  7573.                 agent_type = @agent_type and
  7574.                 agent_name = @agent_name
  7575.         end                 
  7576.  
  7577.     return (0)
  7578. go
  7579.  
  7580.  
  7581. --------------------------------------------------------------------------------
  7582. --. sp_MSenum_misc_agents
  7583. --------------------------------------------------------------------------------
  7584. if exists (select * from sysobjects    where type = 'P'
  7585.     and name = 'sp_MSenum_misc_agents')
  7586.     drop procedure sp_MSenum_misc_agents
  7587. go
  7588.  
  7589. raiserror('Creating procedure sp_MSenum_misc_agents', 0,1)
  7590. go
  7591.  
  7592. create procedure sp_MSenum_misc_agents
  7593. as
  7594.     SET NOCOUNT ON
  7595.  
  7596.     declare @timestamp timestamp
  7597.  
  7598.     -- Not supported, but returned to be consistent with other sp_MSenum_replication_agent
  7599.     -- result set.
  7600.     set @timestamp = 0
  7601.  
  7602.     select j.name, 'agent_type' = c.name,
  7603.             'status' = case isnull(jh.run_status, 5) -- mapped to never run
  7604.                 when 0 then 6   -- Fail mapping
  7605.                 when 1 then 2   -- Success mapping
  7606.                 when 2 then 5   -- Retry mapping
  7607.                 when 3 then 2   -- Shutdown mapping
  7608.                 when 4 then 3   -- Inprogress mapping
  7609.                 when 5 then 0   -- Unknown is mapped to never run
  7610.             end,
  7611.             jh.message, 'start_time' = convert(nvarchar(8), jh.run_date) + N' ' +
  7612.                                        stuff(stuff(right(convert(nvarchar(7), jh.run_time + 1000000), 6), 5, 0, N':'), 3, 0, N':') + 
  7613.                                        + N'.000',
  7614.             jh.run_duration, 
  7615.             'job_id' = convert(binary(16), j.job_id), 'local_timestamp' = @timestamp from 
  7616.                 msdb..sysjobs j
  7617.             LEFT OUTER JOIN msdb..sysjobhistory jh ON
  7618.             j.job_id = jh.job_id and 
  7619.             jh.instance_id = (select max(instance_id) from msdb..sysjobhistory jh2 where
  7620.                 jh2.job_id = j.job_id)
  7621.             INNER JOIN msdb..syscategories c ON
  7622.             j.category_id = c.category_id
  7623.             where j.category_id in (11, 12,16,17,18)
  7624.  
  7625.     order by j.job_id asc
  7626. go 
  7627.  
  7628. --------------------------------------------------------------------------------
  7629. --. sp_MSrepl_startup
  7630. --------------------------------------------------------------------------------
  7631. if exists (select * from sysobjects    where type = 'P'
  7632.     and name = 'sp_MSrepl_startup')
  7633.     drop procedure sp_MSrepl_startup
  7634. go
  7635.  
  7636. raiserror('Creating procedure sp_MSrepl_startup', 0,1)
  7637. go
  7638.  
  7639. create proc sp_MSrepl_startup
  7640. as
  7641.  
  7642.     -- Drop and create publisher side cache table
  7643.     if exists (select * from tempdb..sysobjects where name = 'MSpublisher_access' and
  7644.     type = 'U')
  7645.         drop table tempdb.dbo.MSpublisher_access
  7646.  
  7647.     create table tempdb.dbo.MSpublisher_access
  7648.     (
  7649.     spid int NOT NULL,
  7650.     db_id int not null,
  7651.     publication sysname not null,
  7652.     login_time datetime not null,
  7653.     pubid uniqueidentifier null -- Used for merge only.
  7654.     )
  7655.  
  7656.     CREATE UNIQUE CLUSTERED INDEX ucMSpublisher_access ON tempdb.dbo.MSpublisher_access
  7657.         (spid, publication, db_id, login_time)
  7658.     
  7659.  
  7660.     -- Drop and create distributor side cache table
  7661.     -- We need to avoid publisher and distributor using the same table to prevent
  7662.     -- contention in local distributor case.
  7663.     if exists (select * from master..sysservers
  7664.                   WHERE  srvstatus & 8 <> 0 and UPPER(datasource) = UPPER(@@servername))
  7665.     begin
  7666.         if exists (select * from tempdb..sysobjects where name = 'MSdistributor_access' and
  7667.         type = 'U')
  7668.             drop table tempdb.dbo.MSdistributor_access
  7669.  
  7670.         create table tempdb.dbo.MSdistributor_access
  7671.         (
  7672.         spid int NOT NULL,
  7673.         db_id int not null,
  7674.         agent_id int not null,
  7675.         agent_type int not null,
  7676.         publication_id int not null,
  7677.         login_time datetime not null
  7678.         )
  7679.  
  7680.         CREATE UNIQUE CLUSTERED INDEX ucMSdistributor_access ON tempdb.dbo.MSdistributor_access
  7681.             (spid, agent_id, db_id, login_time)
  7682.     end
  7683. go
  7684.  
  7685. -- If a distributor is installed, mark the sp as a startup sp. 
  7686. if exists (select * FROM master..sysservers WHERE  srvstatus & 8 <> 0)
  7687.     exec dbo.sp_procoption 'sp_MSrepl_startup', 'startup', 'true' 
  7688. go
  7689.  
  7690. --------------------------------------------------------------------------------
  7691. --. sp_MSfix_6x_tasks
  7692. --------------------------------------------------------------------------------
  7693. if exists (select * from sysobjects    where type = 'P'
  7694.     and name = 'sp_MSfix_6x_tasks')
  7695.     drop procedure sp_MSfix_6x_tasks
  7696. go
  7697.  
  7698. raiserror('Creating procedure sp_MSfix_6x_tasks', 0,1)
  7699. go
  7700.  
  7701. CREATE PROCEDURE sp_MSfix_6x_tasks (
  7702.     @publisher sysname = NULL
  7703. ) AS
  7704.  
  7705.     SET NOCOUNT ON
  7706.  
  7707.     DECLARE @distributor sysname
  7708.     DECLARE @distproc nvarchar (255)
  7709.     declare @retcode int
  7710.  
  7711.     -- If @publisher is null redirect the call to distributor
  7712.     if @publisher is null
  7713.     begin
  7714.         /*
  7715.         ** Get distribution server information for remote RPC
  7716.         ** agent verification.
  7717.         */
  7718.         EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT
  7719.  
  7720.         IF @@error <> 0 OR @retcode <> 0
  7721.         BEGIN
  7722.             RAISERROR (14071, 16, -1)
  7723.             RETURN (1)
  7724.         END
  7725.  
  7726.         /*
  7727.         ** RPC distributor
  7728.         */
  7729.         SELECT @distproc = RTRIM(@distributor) + '.master.dbo.sp_MSfix_6x_tasks'
  7730.  
  7731.         EXECUTE @retcode = @distproc
  7732.             @publisher = @@SERVERNAME
  7733.         IF @@ERROR <> 0 or @retcode <> 0
  7734.             return (1)
  7735.     end
  7736.     else
  7737.     begin
  7738.  
  7739.         declare @category_id int
  7740.         declare @category_name sysname
  7741.         declare @server sysname
  7742.         declare @databasename sysname
  7743.         declare @name sysname
  7744.         declare @distdb sysname
  7745.         declare @job_id uniqueidentifier
  7746.         declare @sSubsystem sysname
  7747.  
  7748.         -- Drop entry in systasks first.
  7749.         DECLARE hCtasks CURSOR LOCAL FAST_FORWARD FOR
  7750.             SELECT name FROM msdb.dbo.systasks_view st WHERE 
  7751.                 
  7752.                 -- drop distribution agents.
  7753.                 (st.name LIKE @publisher + '_' + '%' + '_' + '%' AND 
  7754.                 LOWER(subsystem) = 'distribution' AND
  7755.                 server = @@SERVERNAME) OR
  7756.                                 
  7757.                 (LOWER(subsystem) = 'logreader' AND
  7758.                 server = @publisher) OR 
  7759.                 
  7760.                 (LOWER(subsystem) = 'snapshot' AND
  7761.                 server = @publisher) OR
  7762.  
  7763.                 (st.name LIKE '%' + '_' + '%' + '_Cleanup' AND 
  7764.                 st.command LIKE '%' + 'sp_replcleanup' + '%' AND
  7765.                 LOWER(subsystem) = 'tsql')
  7766.             FOR READ ONLY
  7767.  
  7768.         OPEN hCtasks
  7769.         FETCH hCtasks INTO @name
  7770.  
  7771.         WHILE (@@fetch_status <> -1)
  7772.         BEGIN
  7773.             
  7774.             EXEC @retcode = msdb.dbo.sp_droptask @name = @name
  7775.             if @retcode <> 0 or @@error <> 0
  7776.                 return(1)
  7777.             FETCH hCtasks INTO @name
  7778.         END
  7779.  
  7780.         -- Now spin through each old replication job and fixup categories names
  7781.         declare hcJobsToFix CURSOR LOCAL FAST_FORWARD for 
  7782.                 select distinct j.job_id, j.name, s.subsystem, 
  7783.                     s.server, s.database_name
  7784.                     from msdb.dbo.sysjobs j left join msdb.dbo.sysjobsteps s
  7785.                         on j.job_id = s.job_id
  7786.                     where j.category_id = 0 and s.step_id = 1 and lower(s.subsystem) in ( 'snapshot', 'logreader', 'distribution' )
  7787.                 for read only
  7788.  
  7789.         open hcJobsToFix 
  7790.         fetch hcJobsToFix into @job_id, @name, @sSubsystem,
  7791.             @server,@databasename
  7792.  
  7793.         while (@@fetch_status <> -1 )
  7794.         begin
  7795.             -- Note, have to make it a transaction, once the category_id is changed,
  7796.             -- the task will never be picked up again.
  7797.             begin tran 
  7798.  
  7799.                 -- Get Distribution category name (assumes category_id = 10)
  7800.                 select @category_id =
  7801.                     case lower(@sSubsystem) 
  7802.                         when 'snapshot' then 15
  7803.                         when 'distribution' then 10
  7804.                         when 'logreader' then 13
  7805.                         else 0
  7806.                     end
  7807.  
  7808.                 select @category_name = name FROM msdb.dbo.syscategories where category_id = @category_id
  7809.                 
  7810.                 -- raiserror( 'Would update %s to category %d based on subsystem value %s', -1, 10, @nJobName, @iCategory, @sSubsystem )
  7811.                 exec @retcode = msdb.dbo.sp_update_job @job_id = @job_id, 
  7812.                     @category_name = @category_name
  7813.                 if @retcode <> 0 or @@error <> 0
  7814.                     goto UNDO
  7815.  
  7816.  
  7817.                 -- Add the replication agent for monitoring
  7818.                 SELECT @distdb = distribution_db from msdb..MSdistpublishers where UPPER(name) = UPPER(@server)
  7819.                 IF (@category_id = 13) -- Logreader
  7820.                 BEGIN
  7821.                     SELECT @distproc = @distdb + '.dbo.sp_MSadd_logreader_agent'
  7822.                     EXECUTE @retcode = @distproc
  7823.                         @name = @name,
  7824.                         @publisher = @server,
  7825.                         @publisher_db = @databasename,
  7826.                         @publication = '',  
  7827.                         @local_job = 1,
  7828.                         @job_existing = 1,
  7829.                         @job_id = @job_id
  7830.  
  7831.                     IF (@retcode <> 0 or @@error<>0)
  7832.                         goto UNDO
  7833.                 END
  7834.                 ELSE 
  7835.                 IF (@category_id = 15) -- Snapshot
  7836.                 BEGIN
  7837.                     DECLARE @publication sysname
  7838.  
  7839.                     SELECT @publication = NULL
  7840.                     EXECUTE master.dbo.sp_MSget_publication_from_taskname
  7841.                                             @taskname = @name,
  7842.                                             @publisher = @server,
  7843.                                             @publisherdb = @databasename,
  7844.                                             @publication = @publication OUTPUT
  7845.  
  7846.                     IF (@publication IS NOT NULL )
  7847.                     BEGIN    
  7848.                         SELECT @distproc = @distdb + '.dbo.sp_MSadd_snapshot_agent'
  7849.  
  7850.                         EXECUTE @retcode = @distproc
  7851.                             @name = @name,
  7852.                             @publisher = @server,
  7853.                             @publisher_db = @databasename,
  7854.                             @publication = @publication,
  7855.                             @local_job = 1,
  7856.                             @job_existing = 1,
  7857.                             @snapshot_jobid = @job_id
  7858.  
  7859.                         IF (@retcode <> 0 or @@error<>0)
  7860.                             goto UNDO
  7861.                 
  7862.                         SELECT @distproc = @distdb + '.dbo.sp_MSadd_publication'
  7863.                         EXECUTE @retcode = @distproc
  7864.                             @publisher = @server,
  7865.                             @publisher_db = @databasename,
  7866.                             @publication = @publication,
  7867.                             @publication_type = 0 -- Transactional
  7868.                         IF (@retcode <> 0 or @@error<>0)
  7869.                             goto UNDO
  7870.                     END
  7871.                 END
  7872.             commit tran
  7873.             fetch hcJobsToFix into @job_id, @name, @sSubsystem,
  7874.                 @server,@databasename
  7875.         end            
  7876.         close hcJobsToFix
  7877.         deallocate hcJobsToFix
  7878.     end
  7879.     return (0)
  7880. UNDO:
  7881.     if @@trancount <> 0
  7882.         rollback tran
  7883.     return (1)
  7884. GO
  7885.  
  7886. --------------------------------------------------------------------------------
  7887. --. Update permissions on sp_MSenum_replication_job
  7888. --------------------------------------------------------------------------------
  7889. grant execute on sp_MSenum_replication_job to public
  7890. go
  7891.  
  7892. --------------------------------------------------------------------------------
  7893. --.    Tran repl objects (repltran.sql) 
  7894. --------------------------------------------------------------------------------
  7895. dump tran master with no_log
  7896. go
  7897.  
  7898. --------------------------------------------------------------------------------
  7899. --. sp_MSdrop_repltran
  7900. --------------------------------------------------------------------------------
  7901. if exists (select * from sysobjects    where type = 'P'
  7902.     and name = 'sp_MSdrop_repltran')
  7903.     drop procedure sp_MSdrop_repltran
  7904. go
  7905.  
  7906. raiserror('Creating procedure sp_MSdrop_repltran', 0,1)
  7907. go
  7908.  
  7909. create procedure sp_MSdrop_repltran
  7910. as
  7911.  
  7912.     if exists( select * from sysobjects 
  7913.         where type = 'P '
  7914.             and name = 'sp_MSsetfilterparent' )
  7915.         drop procedure sp_MSsetfilterparent
  7916.  
  7917.     if exists( select * from sysobjects 
  7918.         where type = 'P '
  7919.             and name = 'sp_MSdoesfilterhaveparent' )
  7920.         drop procedure sp_MSdoesfilterhaveparent
  7921.  
  7922.     if exists( select * from sysobjects 
  7923.         where type = 'P '
  7924.             and name = 'sp_MSsetfilteredstatus' )
  7925.         drop procedure sp_MSsetfilteredstatus
  7926.  
  7927.     if exists ( select * from sysobjects 
  7928.         where type = 'P '
  7929.             and name = 'sp_MSreplsup_table_has_pk' )
  7930.         DROP PROC sp_MSreplsup_table_has_pk
  7931.  
  7932.     if exists (select * from sysobjects
  7933.         where type = 'P '
  7934.                 and name = 'sp_MScreate_pub_tables')
  7935.         drop procedure sp_MScreate_pub_tables
  7936.  
  7937.     if exists (select * from sysobjects
  7938.         where type = 'P '
  7939.                 and name = 'sp_MSdrop_expired_subscription')
  7940.         drop procedure sp_MSdrop_expired_subscription
  7941.     
  7942.     if exists (select * from sysobjects
  7943.             where type = 'P '
  7944.                 and name = 'sp_replsync')
  7945.         drop procedure sp_replsync
  7946.  
  7947.     if exists (select * from sysobjects
  7948.             where type = 'P '
  7949.                 and name = 'sp_enumfullsubscribers')
  7950.         drop procedure sp_enumfullsubscribers
  7951.     
  7952.     if exists (select * from sysobjects
  7953.         where type = 'P '
  7954.                 and name = 'sp_MSaddexecarticle')
  7955.         drop procedure sp_MSaddexecarticle
  7956.     
  7957.  
  7958.     if exists (select * from sysobjects
  7959.         where type = 'P '
  7960.                 and name = 'sp_MSscript_validate_subscription')
  7961.         drop procedure sp_MSscript_validate_subscription 
  7962.  
  7963.     if exists (select * from sysobjects
  7964.         where type = 'P '
  7965.                 and name = 'sp_MSvalidate_subscription')
  7966.         drop procedure sp_MSvalidate_subscription 
  7967.  
  7968.     dump tran master with no_log
  7969.     
  7970.  
  7971.     if exists (select * from sysobjects
  7972.             where type = 'P '
  7973.                 and name = 'sp_addarticle')
  7974.         drop procedure sp_addarticle
  7975.     
  7976.  
  7977.     if exists (select * from sysobjects
  7978.         where type = 'P '
  7979.                 and name = 'sp_articlecolumn')
  7980.         drop procedure sp_articlecolumn
  7981.     
  7982.  
  7983.     dump tran master with no_log
  7984.     
  7985.  
  7986.     if exists (select * from sysobjects
  7987.             where type = 'P '
  7988.                 and name = 'sp_articlefilter')
  7989.         drop procedure sp_articlefilter
  7990.        
  7991.  
  7992.  
  7993.     if exists (select * from sysobjects
  7994.         where type = 'P '
  7995.                 and name = 'sp_MSarticletextcol')
  7996.         drop procedure sp_MSarticletextcol
  7997.     
  7998.  
  7999.     dump tran master with no_log
  8000.     
  8001.  
  8002.     if exists (select * from sysobjects
  8003.         where type = 'P '
  8004.                 and name = 'sp_MStextcolstatus')
  8005.         drop procedure sp_MStextcolstatus
  8006.     
  8007.  
  8008.     if exists (select * from sysobjects
  8009.             where type = 'P '
  8010.                 and name = 'sp_articleview')
  8011.         drop procedure sp_articleview
  8012.     
  8013.  
  8014.     dump tran master with no_log
  8015.     
  8016.  
  8017.     if exists (select * from sysobjects
  8018.             where type = 'P '
  8019.                 and name = 'sp_addpublication')
  8020.         drop procedure sp_addpublication
  8021.     
  8022.  
  8023.     dump tran master with no_log
  8024.     
  8025.  
  8026.     if exists (select * from sysobjects
  8027.             where type = 'P '
  8028.                 and name = 'sp_addsubscription')
  8029.         drop procedure sp_addsubscription
  8030.     
  8031.  
  8032.     IF EXISTS (SELECT * FROM sysobjects
  8033.             WHERE type = 'P '
  8034.                 AND name = 'sp_changearticle')
  8035.         DROP PROCEDURE sp_changearticle
  8036.     
  8037.  
  8038.     dump tran master with no_log
  8039.     
  8040.  
  8041.     IF EXISTS (SELECT * FROM sysobjects
  8042.             WHERE type = 'P '
  8043.                 AND name = 'sp_changepublication')
  8044.         DROP PROCEDURE sp_changepublication
  8045.     
  8046.  
  8047.  
  8048.     IF EXISTS (SELECT * FROM sysobjects
  8049.             WHERE type = 'P '
  8050.                 AND name = 'sp_changesubscription')
  8051.         DROP PROCEDURE sp_changesubscription
  8052.     
  8053.  
  8054.     dump tran master with no_log
  8055.     
  8056.  
  8057.     if exists (select * from sysobjects
  8058.             where type = 'P '
  8059.                 and name = 'sp_MShcchangesubstatus1')
  8060.         drop procedure sp_MShcchangesubstatus1
  8061.     
  8062.  
  8063.     if exists (select * from sysobjects
  8064.             where type = 'P '
  8065.                 and name = 'sp_MShcchangesubstatus2')
  8066.         drop procedure sp_MShcchangesubstatus2
  8067.     
  8068.  
  8069.     if exists (select * from sysobjects
  8070.             where type = 'P '
  8071.                 and name = 'sp_MShcchangesubstatus3')
  8072.         drop procedure sp_MShcchangesubstatus3
  8073.     
  8074.  
  8075.     dump tran master with no_log
  8076.     
  8077.  
  8078.     if exists (select * from sysobjects
  8079.             where type = 'P '
  8080.                 and name = 'sp_changesubstatus')
  8081.         drop procedure sp_changesubstatus
  8082.     
  8083.  
  8084.     if exists (select * from sysobjects
  8085.             where type = 'P '
  8086.                 and name = 'sp_droparticle')
  8087.         drop procedure sp_droparticle
  8088.     
  8089.  
  8090.     dump tran master with no_log
  8091.     
  8092.  
  8093.     if exists (select * from sysobjects
  8094.             where type = 'P '
  8095.                 and name = 'sp_droppublication')
  8096.         drop procedure sp_droppublication
  8097.     
  8098.  
  8099.     if exists (select * from sysobjects
  8100.             where type = 'P '
  8101.                 and name = 'sp_dropsubscription')
  8102.         drop procedure sp_dropsubscription
  8103.     
  8104.  
  8105.     dump tran master with no_log
  8106.     
  8107.  
  8108.     if exists (select * from sysobjects
  8109.             where type = 'P '
  8110.                 and name = 'sp_helparticle')
  8111.         drop procedure sp_helparticle
  8112.     
  8113.  
  8114.     dump tran master with no_log
  8115.     
  8116.  
  8117.     if exists (select * from sysobjects
  8118.             where type = 'P '
  8119.                 and name = 'sp_helparticlecolumns')
  8120.         drop procedure sp_helparticlecolumns
  8121.     
  8122.  
  8123.     if exists (select * from sysobjects
  8124.             where type = 'P '
  8125.                 and name = 'sp_helppublication')
  8126.         drop procedure sp_helppublication
  8127.     
  8128.         
  8129.     if exists (select * from sysobjects
  8130.             where type = 'P '
  8131.                 and name = 'sp_MSaddpub_snapshot')
  8132.         drop procedure sp_MSaddpub_snapshot
  8133.  
  8134.     dump tran master with no_log
  8135.     
  8136.  
  8137.     if exists (select * from sysobjects
  8138.             where type = 'P '
  8139.                 and name = 'sp_helpsubscription')
  8140.         drop procedure sp_helpsubscription
  8141.     
  8142.  
  8143.     if exists (select * from sysobjects
  8144.             where type = 'P '
  8145.                 and name = 'sp_subscribe')
  8146.         drop procedure sp_subscribe
  8147.     
  8148.  
  8149.     if exists (select * from sysobjects
  8150.             where type = 'P '
  8151.                 and name = 'sp_unsubscribe')
  8152.         drop procedure sp_unsubscribe
  8153.     
  8154.  
  8155.     if exists (select * from sysobjects
  8156.             where type = 'P '
  8157.                 and name = 'sp_refreshsubscriptions')
  8158.         drop procedure sp_refreshsubscriptions
  8159.     
  8160.  
  8161.     dump tran master with no_log
  8162.     
  8163.  
  8164.     if exists (select * from sysobjects
  8165.             where type = 'P '
  8166.                 and name = 'sp_MSpublishdb')
  8167.         drop procedure sp_MSpublishdb
  8168.     
  8169.  
  8170.     if exists (select * from sysobjects
  8171.             where type = 'P '
  8172.                 and name = 'sp_MSactivate_auto_sub')
  8173.         drop procedure sp_MSactivate_auto_sub
  8174.     
  8175.  
  8176.     if exists (select * from sysobjects
  8177.             where type = 'P '
  8178.                 and name = 'sp_MSget_synctran_commands')
  8179.         drop procedure sp_MSget_synctran_commands
  8180.  
  8181.  
  8182.     if exists (select * from sysobjects
  8183.         where type = 'P '
  8184.                 and name = 'sp_MSdrop_pub_tables')
  8185.     begin
  8186.         -- Don't drop the system tables here. repltran.sql should not
  8187.         -- delete any data in the master database (see bug 34219).
  8188.         -- exec dbo.sp_MSdrop_pub_tables
  8189.         drop procedure sp_MSdrop_pub_tables
  8190.     end
  8191.  
  8192.     -- SyncTran
  8193.     if exists (select * from sysobjects
  8194.         where type = 'P '
  8195.                 and name = 'sp_MSis_col_replicated')
  8196.         drop procedure  sp_MSis_col_replicated
  8197.  
  8198.     if exists (select * from sysobjects
  8199.         where type = 'P '
  8200.                 and name = 'sp_MSis_pk_col')
  8201.         drop procedure  sp_MSis_pk_col
  8202.  
  8203.    if exists (select * from sysobjects
  8204.         where type = 'P '
  8205.                 and name = 'sp_MSscript_insert_statement')
  8206.         drop procedure sp_MSscript_insert_statement 
  8207.  
  8208.    if exists (select * from sysobjects
  8209.         where type = 'P '
  8210.                 and name = 'sp_MSscript_update_statement')
  8211.         drop procedure sp_MSscript_update_statement
  8212.  
  8213.    if exists (select * from sysobjects
  8214.         where type = 'P '
  8215.                 and name = 'sp_MSscript_delete_statement')
  8216.         drop procedure sp_MSscript_delete_statement
  8217.  
  8218.    if exists (select * from sysobjects
  8219.         where type = 'P '
  8220.                 and name = 'sp_MSscript_beginproc')
  8221.         drop procedure sp_MSscript_beginproc
  8222.  
  8223.    if exists (select * from sysobjects
  8224.         where type = 'P '
  8225.                 and name = 'sp_MSscript_security')
  8226.         drop procedure sp_MSscript_security
  8227.  
  8228.    if exists (select * from sysobjects
  8229.         where type = 'P '
  8230.                 and name = 'sp_MSscript_endproc')
  8231.         drop procedure sp_MSscript_endproc
  8232.  
  8233.   if exists (select * from sysobjects
  8234.         where type = 'P '
  8235.                 and name = 'sp_MStable_not_modifiable')
  8236.         drop procedure sp_MStable_not_modifiable
  8237.  
  8238.    if exists (select * from sysobjects
  8239.         where type = 'P '
  8240.                 and name = 'sp_MSscript_sync_ins_proc')
  8241.         drop procedure sp_MSscript_sync_ins_proc
  8242.  
  8243.    if exists (select * from sysobjects
  8244.         where type = 'P '
  8245.                 and name = 'sp_MSscript_sync_upd_proc')
  8246.         drop procedure sp_MSscript_sync_upd_proc 
  8247.  
  8248.    if exists (select * from sysobjects
  8249.         where type = 'P '
  8250.                 and name = 'sp_MSscript_sync_del_proc')
  8251.         drop procedure sp_MSscript_sync_del_proc
  8252.  
  8253.    if exists (select * from sysobjects
  8254.         where type = 'P '
  8255.                 and name = 'sp_MSgen_sync_tran_procs')
  8256.         drop procedure sp_MSgen_sync_tran_procs 
  8257.  
  8258.     if exists (select * from sysobjects
  8259.         where type = 'P '
  8260.                 and name = 'sp_MSmark_proc_norepl')
  8261.         drop procedure sp_MSmark_proc_norepl 
  8262.  
  8263.     if exists (select * from sysobjects
  8264.         where type = 'P '
  8265.                 and name = 'sp_articlesynctranprocs')
  8266.         drop procedure sp_articlesynctranprocs
  8267.  
  8268.     if exists (select * from sysobjects
  8269.         where type = 'P '
  8270.                 and name = 'sp_reinitsubscription')
  8271.         drop procedure sp_reinitsubscription
  8272.  
  8273.     dump tran master with no_log
  8274.  
  8275.     if exists( select * from sysobjects 
  8276.         where type = 'P ' and name = N'sp_getarticlepkcolbitmap')
  8277.     begin
  8278.         drop procedure sp_getarticlepkcolbitmap
  8279.     end
  8280.  
  8281.     if exists( select * from sysobjects 
  8282.         where type = 'P ' and name = N'sp_gettypestring' )
  8283.     begin
  8284.         drop procedure sp_gettypestring
  8285.     end
  8286.  
  8287.     if exists( select * from sysobjects 
  8288.         where type = 'P ' and name = N'sp_isarticlecolbitset' )
  8289.     begin
  8290.         drop procedure sp_isarticlecolbitset
  8291.     end
  8292.  
  8293.     if exists( select * from sysobjects 
  8294.         where type = 'P ' and name = N'sp_scriptpkwhereclause' )
  8295.     begin
  8296.         drop procedure sp_scriptpkwhereclause
  8297.     end
  8298.  
  8299.     if exists( select * from sysobjects 
  8300.         where type = 'P ' and name = N'sp_scriptupdateparams' )
  8301.     begin
  8302.         drop procedure sp_scriptupdateparams
  8303.     end
  8304.  
  8305.     if exists( select * from sysobjects 
  8306.         where type = 'P ' and name = N'sp_scriptinsproc' )
  8307.     begin
  8308.         drop procedure sp_scriptinsproc
  8309.     end
  8310.  
  8311.     if exists( select * from sysobjects 
  8312.         where type = 'P ' and name = N'sp_scriptdelproc' )
  8313.     begin
  8314.         drop procedure sp_scriptdelproc
  8315.     end
  8316.  
  8317.     if exists( select * from sysobjects 
  8318.         where type = 'P ' and name = N'sp_scriptupdproc' )
  8319.     begin
  8320.         drop procedure sp_scriptupdproc
  8321.     end
  8322.  
  8323.     if exists ( select * from sysobjects 
  8324.         where type = 'P ' and name = 'sp_scriptmappedupdproc' )
  8325.     begin
  8326.         drop procedure sp_scriptmappedupdproc
  8327.     end
  8328.  
  8329.     if exists ( select * from sysobjects 
  8330.         where type = 'P ' and name = 'sp_fetchshowcmdsinput' )
  8331.     begin
  8332.         drop procedure sp_fetchshowcmdsinput
  8333.     end
  8334.  
  8335.     if exists ( select * from sysobjects 
  8336.         where type = 'P ' and name = 'sp_replshowcmds' )
  8337.     begin
  8338.         drop procedure sp_replshowcmds
  8339.     end
  8340.  
  8341.     if exists ( select * from sysobjects 
  8342.         where type = 'P ' and name = 'sp_publication_validation' )
  8343.     begin
  8344.         drop procedure sp_publication_validation
  8345.     end
  8346.  
  8347.     if exists ( select * from sysobjects 
  8348.         where type = 'P ' and name = 'sp_article_validation' )
  8349.     begin
  8350.         drop procedure sp_article_validation
  8351.     end
  8352.  
  8353.     if exists ( select * from sysobjects 
  8354.         where type = 'P ' and name = 'sp_MSdrop_6x_replication_agent' )
  8355.     begin
  8356.         drop procedure sp_MSdrop_6x_replication_agent
  8357.     end
  8358.  
  8359.     if exists ( select * from sysobjects 
  8360.         where type = 'P ' and name = 'sp_script_synctran_commands' )
  8361.     begin
  8362.         drop procedure sp_script_synctran_commands
  8363.     end
  8364.  
  8365.     dump tran master with no_log
  8366. go
  8367.  
  8368. --------------------------------------------------------------------------------
  8369. --. sp_MSscript_validate_subscription
  8370. --------------------------------------------------------------------------------
  8371. if exists (select * from sysobjects    where type = 'P'
  8372.     and name = 'sp_MSscript_validate_subscription')
  8373.     drop procedure sp_MSscript_validate_subscription
  8374. go
  8375.  
  8376. raiserror('Creating procedure sp_MSscript_validate_subscription', 0,1)
  8377. go
  8378.  
  8379. create procedure sp_MSscript_validate_subscription
  8380.     @publication sysname,
  8381.     @article sysname
  8382. as
  8383.  
  8384.     declare @pubid int
  8385.     declare @artid int
  8386.     select @pubid = pubid from syspublications where name = @publication
  8387.     select @artid = artid from sysarticles where pubid = @pubid and name = @article
  8388.  
  8389.     insert into #proctext(procedure_text) values
  8390.         (N'exec @retcode = dbo.sp_MSvalidate_subscription @orig_server, @orig_db, '
  8391.             + convert(nvarchar(10), @artid))
  8392.     insert into #proctext(procedure_text) values
  8393.         (N'if @@error <> 0 or @retcode <> 0 return -1 ' )
  8394.                     
  8395. go
  8396.  
  8397. grant execute on dbo.sp_MSscript_validate_subscription to public
  8398. go
  8399.  
  8400. --------------------------------------------------------------------------------
  8401. --. sp_MSvalidate_subscription
  8402. --------------------------------------------------------------------------------
  8403. if exists (select * from sysobjects    where type = 'P'
  8404.     and name = 'sp_MSvalidate_subscription')
  8405.     drop procedure sp_MSvalidate_subscription
  8406. go
  8407.  
  8408. raiserror('Creating procedure sp_MSvalidate_subscription', 0,1)
  8409. go
  8410.  
  8411. create procedure sp_MSvalidate_subscription
  8412.     @subscriber sysname,
  8413.     @subscriber_db sysname,
  8414.     @artid int
  8415. as
  8416.  
  8417.     declare @srvid smallint
  8418.     select @srvid = srvid from master..sysservers where srvname = @subscriber
  8419.     if not exists (select * from syssubscriptions where artid = @artid and 
  8420.         srvid = @srvid and dest_db = @subscriber_db)
  8421.     begin
  8422.         --  The subscription has been dropped from the publisher. Please run sp_subscription_cleanup to cleanup the triggers.
  8423.         exec sp_MSreplraiserror 21161
  8424.         return -1
  8425.     end                    
  8426. go
  8427.  
  8428. grant execute on dbo.sp_MSvalidate_subscription to public
  8429. go
  8430.  
  8431. --------------------------------------------------------------------------------
  8432. --. sp_addpublication
  8433. --------------------------------------------------------------------------------
  8434. if exists (select * from sysobjects    where type = 'P'
  8435.     and name = 'sp_addpublication')
  8436.     drop procedure sp_addpublication
  8437. go
  8438.  
  8439. raiserror('Creating procedure sp_addpublication', 0,1)
  8440. go
  8441.  
  8442. CREATE PROCEDURE sp_addpublication (
  8443.     @publication sysname,                           /* publication name */
  8444.     @taskid int = 0,                                /* backward compatible */
  8445.     @restricted nvarchar (10) = 'false',            /* publication security */
  8446.     @sync_method nvarchar(13) = 'native',           /* (bcp) native, (bcp) character */
  8447.     @repl_freq nvarchar(10) = 'continuous',         /* continuous, snapshot */
  8448.     @description nvarchar (255) = NULL,             /* publication description */
  8449.     @status nvarchar(8) = 'inactive',               /* publication status; 0=inactive, 1=active */
  8450.     @independent_agent nvarchar(5) = 'false',       /* true or false */
  8451.     @immediate_sync nvarchar(5) = 'false',          /* true or false */
  8452.     @enabled_for_internet nvarchar(5) = 'false',    /* true or false */
  8453.     @allow_push nvarchar(5) = 'true',               /* true or false */
  8454.     @allow_pull nvarchar(5) = 'false',              /* true or false */
  8455.     @allow_anonymous nvarchar(5) = 'false',         /* true or false */
  8456.     -- SyncTran
  8457.     @allow_sync_tran nvarchar(5) = 'false',        /* true or false */
  8458.     @autogen_sync_procs nvarchar(5) = 'true',        /* auto gen sync tran procs per article */
  8459.     @retention  int = 72                          /* over weekend - 3 days */
  8460.     ) AS
  8461.  
  8462.     SET NOCOUNT ON
  8463.  
  8464.     /*
  8465.     ** Declarations.
  8466.     */
  8467.  
  8468.     DECLARE @retcode    int         /* return code value for procedure execution */
  8469.     DECLARE @rfid tinyint           /* identifier for replication frequency */
  8470.     DECLARE @publish_bit smallint   /* publication bit (flag) in sysobjects */
  8471.     DECLARE @smid tinyint           /* identifier for sync method */
  8472.     DECLARE @statid tinyint         /* status id based on @status */
  8473.     DECLARE @subs_type_id tinyint   /* subscription type id based on @subscription_type */
  8474.     DECLARE @distributor sysname
  8475.     DECLARE @distribdb sysname
  8476.     DECLARE @distproc nvarchar (255)
  8477.     DECLARE @agentname nvarchar (40)
  8478.     DECLARE @dbname sysname
  8479.     DECLARE @mergepublish_bit smallint
  8480.     DECLARE @found int
  8481.     DECLARE @independent_agent_id bit
  8482.     DECLARE @immediate_sync_id bit
  8483.     DECLARE @enabled_for_internet_id bit
  8484.     DECLARE @allow_push_id bit
  8485.     DECLARE @allow_pull_id bit
  8486.     DECLARE @allow_anonymous_id bit
  8487.     DECLARE @pubid int
  8488.     declare @distgroup sysname
  8489.  
  8490.     -- SyncTran
  8491.     DECLARE @allow_sync_tran_id bit
  8492.     DECLARE @autogen_sync_procs_id bit
  8493.  
  8494.     select @allow_sync_tran_id = 0, @autogen_sync_procs_id = 0
  8495.     -- end SyncTran
  8496.  
  8497.     declare @qv_replication varchar(10)
  8498.     declare @qv_replication_unlimited integer
  8499.     declare @qv_value_replication integer
  8500.  
  8501.     select @qv_replication = '2745196162', @qv_replication_unlimited = 0
  8502.  
  8503.     /*
  8504.     ** The default value for TRAN publication is always 72 hours
  8505.     */
  8506.     if @retention is NULL
  8507.     BEGIN
  8508.         RAISERROR(20081, 16, -1, 'retention')
  8509.         RETURN (1)
  8510.     END
  8511.     
  8512.     /*
  8513.     ** A @retention value of zero means an infinite retention period
  8514.     */
  8515.     if @retention < 0
  8516.     BEGIN
  8517.         RAISERROR (20050, 16, -1, 1)
  8518.         RETURN(1)
  8519.     END
  8520.  
  8521.     SELECT @publish_bit         = 32
  8522.     SELECT @mergepublish_bit    = 4
  8523.  
  8524.     /*
  8525.     ** Security Check
  8526.     */
  8527.  
  8528.     exec @retcode = dbo.sp_MSreplcheck_publish
  8529.     if @@ERROR <> 0 or @retcode <> 0
  8530.         return(1)
  8531.  
  8532.     /*
  8533.     ** Check to see if the database has been activated for publication.
  8534.     */
  8535.  
  8536.     IF (SELECT category & 1
  8537.           FROM master..sysdatabases
  8538.          WHERE name = DB_NAME()) = 0
  8539.  
  8540.     BEGIN
  8541.         RAISERROR (14013, 16, -1)
  8542.         RETURN (1)
  8543.     END
  8544.  
  8545.     IF @taskid <> 0
  8546.     BEGIN
  8547.         -- No longer supported
  8548.         RAISERROR (21023, 16, -1,'@taskid')
  8549.         RETURN(1)
  8550.     END
  8551.  
  8552.     /*
  8553.     ** Parameter Check: @publication.
  8554.     ** The @publication name must conform to the rules for identifiers,
  8555.     ** and must not be the keyword 'all'.
  8556.     */
  8557.  
  8558.     IF @publication IS NULL
  8559.         BEGIN
  8560.             RAISERROR (14043, 16, -1, '@publication')
  8561.             RETURN (1)
  8562.         END
  8563.  
  8564.     exec @retcode = dbo.sp_MSreplcheck_name @publication
  8565.     if @@ERROR <> 0 or @retcode <> 0
  8566.         return(1)
  8567.  
  8568.     IF LOWER (@publication) = 'all'
  8569.         BEGIN
  8570.             RAISERROR (14034, 16, -1)
  8571.             RETURN (1)
  8572.         END
  8573.  
  8574.     /*
  8575.     **  Check if the publication already exists.
  8576.     **  1. Check transaction-level publications
  8577.     **  2. Check merge publications
  8578.     */
  8579.  
  8580.     IF EXISTS (SELECT * FROM syspublications WHERE name = @publication)
  8581.         BEGIN
  8582.             RAISERROR (14016, 16, -1, @publication)
  8583.             RETURN (1)
  8584.         END
  8585.     
  8586.     if (select category & @mergepublish_bit from master..sysdatabases where name = DB_NAME()) <> 0
  8587.         begin
  8588.             EXEC @retcode = dbo.sp_helpmergepublication @publication, @found output
  8589.  
  8590.             IF @@ERROR <> 0 OR @retcode <> 0
  8591.             BEGIN
  8592.                 RETURN (1)
  8593.             END
  8594.  
  8595.             IF @found <> 0 
  8596.             BEGIN
  8597.                 RAISERROR (20025, 16, -1, @publication)
  8598.                 RETURN (1)
  8599.             END
  8600.         end
  8601.  
  8602.     /*
  8603.     ** Get distribution server information for remote RPC
  8604.     ** agent verification.
  8605.     */
  8606.     EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  8607.                  @distribdb = @distribdb OUTPUT
  8608.  
  8609.     IF @@error <> 0 OR @retcode <> 0
  8610.         BEGIN
  8611.         RAISERROR (14071, 16, -1)
  8612.             RETURN (1)
  8613.     END
  8614.  
  8615.  
  8616.     /*
  8617.     ** Parameter Check: @sync_method
  8618.     ** The synchronization method must be one of the following:
  8619.     **
  8620.     **      0  [bcp] native
  8621.     **      1  [bcp] character
  8622.     */
  8623.  
  8624.     SELECT @sync_method = LOWER(@sync_method)
  8625.     IF @sync_method IS NULL OR @sync_method NOT IN ('native', 'character', 'bcp native', 'bcp character')
  8626.         BEGIN
  8627.             RAISERROR (14014, 16, -1)
  8628.             RETURN (1)
  8629.         END
  8630.  
  8631.     IF @sync_method IN ('character', 'bcp character')
  8632.         SELECT @smid = 1
  8633.     ELSE
  8634.         SELECT @smid = 0
  8635.  
  8636.     /*
  8637.     ** Parameter Check: @repl_freq.
  8638.     ** Make sure that the replication frequency is one of the following:
  8639.     **
  8640.     **  id  frequency
  8641.     **  ==  ==========
  8642.     **   0  continuous
  8643.     **   1  snapshot
  8644.     */
  8645.  
  8646.     SELECT @repl_freq = LOWER(@repl_freq)
  8647.     IF @repl_freq IS NULL OR @repl_freq NOT IN ('continuous', 'snapshot')
  8648.         BEGIN
  8649.             RAISERROR (14015, 16, -1)
  8650.             RETURN (1)
  8651.         END
  8652.  
  8653.     IF @repl_freq = 'snapshot' SELECT @rfid = 1
  8654.     ELSE SELECT @rfid = 0
  8655.  
  8656.     -- disable tran publishing on REPLICATION_LIMITED sku
  8657.     exec @qv_value_replication = master.dbo.xp_qv @qv_replication     
  8658.     if (@rfid = 0) and ( @qv_value_replication != @qv_replication_unlimited ) 
  8659.     begin
  8660.         raiserror(21108, 16, -1)
  8661.         return (1)
  8662.     end
  8663.  
  8664.     /*
  8665.     ** Parameter Check:  @restricted.
  8666.     */
  8667.  
  8668.     IF (@restricted IS NULL) OR (LOWER(@restricted) NOT IN ('true', 'false'))
  8669.         BEGIN
  8670.             RAISERROR (14017, 16, -1)
  8671.             RETURN (1)
  8672.         END
  8673.  
  8674.     /*
  8675.     ** Restricted publications are no longer supported
  8676.     */
  8677.     IF LOWER(@restricted) = 'true'
  8678.     BEGIN
  8679.         RAISERROR (14147, 16, -1)
  8680.         RETURN(1)
  8681.     END
  8682.  
  8683.     /*
  8684.     ** Parameter Check:  @status.
  8685.     ** The @status value can be:
  8686.     **
  8687.     **      statid  status
  8688.     **      ======  ========
  8689.     **           0  inactive
  8690.     **           1  active
  8691.     */
  8692.  
  8693.     IF @status IS NULL OR LOWER(@status) NOT IN ('inactive', 'active')
  8694.         BEGIN
  8695.             RAISERROR (14012, 16, -1)
  8696.             RETURN (1)
  8697.         END
  8698.  
  8699.     IF LOWER(@status) = 'active' SELECT @statid = 1
  8700.     ELSE SELECT @statid = 0
  8701.  
  8702.     /*
  8703.     ** Parameter Check:  @independent_agent.
  8704.     */
  8705.  
  8706.     IF @independent_agent IS NULL OR LOWER(@independent_agent) NOT IN ('true', 'false')
  8707.         BEGIN
  8708.             RAISERROR (14148, 16, -1, '@independent_agent')
  8709.             RETURN (1)
  8710.         END
  8711.  
  8712.     IF LOWER(@independent_agent) = 'true' SELECT @independent_agent_id = 1
  8713.     ELSE SELECT @independent_agent_id = 0
  8714.  
  8715.     /*
  8716.     ** Parameter Check:  @immediate_sync.
  8717.     */
  8718.  
  8719.     IF @immediate_sync IS NULL OR LOWER(@immediate_sync) NOT IN ('true', 'false')
  8720.         BEGIN
  8721.             RAISERROR (14148, 16, -1, '@immediate_sync')
  8722.             RETURN (1)
  8723.         END
  8724.  
  8725.     IF LOWER(@immediate_sync) = 'true' SELECT @immediate_sync_id = 1
  8726.     ELSE SELECT @immediate_sync_id = 0
  8727.  
  8728.     /*
  8729.     ** Parameter Check:  @enabled_for_internet.
  8730.     */
  8731.  
  8732.     IF @enabled_for_internet IS NULL OR LOWER(@enabled_for_internet) NOT IN ('true', 'false')
  8733.         BEGIN
  8734.             RAISERROR (14148, 16, -1, '@enabled_for_internet')
  8735.             RETURN (1)
  8736.         END
  8737.  
  8738.     IF LOWER(@enabled_for_internet) = 'true' SELECT @enabled_for_internet_id = 1
  8739.     ELSE SELECT @enabled_for_internet_id = 0
  8740.  
  8741.     /*
  8742.     ** Parameter Check:  @allow_push.
  8743.     */
  8744.  
  8745.     IF @allow_push IS NULL OR LOWER(@allow_push) NOT IN ('true', 'false')
  8746.         BEGIN
  8747.             RAISERROR (14148, 16, -1, '@allow_push')
  8748.             RETURN (1)
  8749.         END
  8750.     IF LOWER(@allow_push) = 'true' SELECT @allow_push_id = 1
  8751.     ELSE SELECT @allow_push_id = 0
  8752.  
  8753.     /*
  8754.     ** Parameter Check:  @allow_pull.
  8755.     */
  8756.  
  8757.     IF @allow_pull IS NULL OR LOWER(@allow_pull) NOT IN ('true', 'false')
  8758.         BEGIN
  8759.             RAISERROR (14148, 16, -1, '@allow_pull')
  8760.             RETURN (1)
  8761.         END
  8762.     IF LOWER(@allow_pull) = 'true' SELECT @allow_pull_id = 1
  8763.     ELSE SELECT @allow_pull_id = 0
  8764.  
  8765.     /*
  8766.     ** Parameter Check:  @allow_anonymous.
  8767.     */
  8768.  
  8769.     IF @allow_anonymous IS NULL OR LOWER(@allow_anonymous) NOT IN ('true', 'false')
  8770.         BEGIN
  8771.             RAISERROR (14148, 16, -1, '@allow_anonymous')
  8772.             RETURN (1)
  8773.         END
  8774.     IF LOWER(@allow_anonymous) = 'true' SELECT @allow_anonymous_id = 1
  8775.     ELSE SELECT @allow_anonymous_id = 0
  8776.  
  8777.     /* Immediate_sync publications have to be independent_agent */
  8778.     IF @immediate_sync_id = 1 AND @independent_agent_id = 0
  8779.     BEGIN
  8780.             RAISERROR (21022, 16, -1)
  8781.             RETURN (1)
  8782.     END
  8783.  
  8784.  
  8785.     /* 
  8786.     ** Non-immediate sync do not support anonymous subscriptions.
  8787.     */
  8788.  
  8789.     IF @immediate_sync_id = 0 AND @allow_anonymous_id = 1
  8790.     BEGIN
  8791.             RAISERROR (20011, 16, -1)
  8792.             RETURN (1)
  8793.     END
  8794.  
  8795.     -- SyncTran
  8796.     /*
  8797.     ** Parameter Check:  @allow_sync_tran
  8798.     */
  8799.  
  8800.     IF @allow_sync_tran IS NULL OR LOWER(@allow_sync_tran) NOT IN ('true', 'false')
  8801.     BEGIN
  8802.         RAISERROR (14148, 16, -1, '@allow_sync_tran')
  8803.         RETURN (1)
  8804.     END
  8805.  
  8806.     IF LOWER(@allow_sync_tran) = 'true' 
  8807.     BEGIN
  8808.         SELECT @allow_sync_tran_id = 1
  8809.  
  8810.         --Parameter Check:  @autogen_sync_procs
  8811.         IF @autogen_sync_procs IS NULL OR LOWER(@autogen_sync_procs) NOT IN ('true', 'false')
  8812.         BEGIN
  8813.             RAISERROR (14148, 16, -1, '@autogen_sync_procs')
  8814.             RETURN (1)
  8815.         END
  8816.  
  8817.         IF LOWER(@autogen_sync_procs) = 'true' 
  8818.             SELECT @autogen_sync_procs_id = 1
  8819.         ELSE 
  8820.             SELECT @autogen_sync_procs_id = 0
  8821.  
  8822.     END
  8823.     ELSE 
  8824.     BEGIN
  8825.         SELECT @allow_sync_tran_id = 0
  8826.         SELECT @autogen_sync_procs_id = 0
  8827.     END
  8828.     -- end SyncTran
  8829.  
  8830.     /*
  8831.     ** Get distribution server information for remote RPC call.
  8832.     */
  8833.     EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  8834.        @distribdb   = @distribdb OUTPUT
  8835.     IF @@ERROR <> 0 or @retcode <> 0
  8836.     BEGIN
  8837.         GOTO UNDO
  8838.     END
  8839.  
  8840.     /*
  8841.     **  Add publication to syspublications.
  8842.     */
  8843.     begin tran
  8844.     save TRAN sp_addpublication
  8845.  
  8846.     select @dbname = db_name()
  8847.     
  8848.     /*
  8849.     ** Construct Log Reader agent name.
  8850.     */
  8851.  
  8852.     IF @rfid = 0 and NOT EXISTS (SELECT * FROM syspublications where repl_freq = 0)
  8853.     BEGIN
  8854.         /*
  8855.         ** Schedule Log Reader agent for the database
  8856.         */
  8857.         SELECT @distproc = RTRIM(@distributor) + '.' + @distribdb +'.dbo.sp_MSadd_logreader_agent'
  8858.  
  8859.  
  8860.         EXECUTE @retcode = @distproc
  8861.             @publisher = @@SERVERNAME,
  8862.             @publisher_db = @dbname,
  8863.             @publication = 'ALL',  
  8864.             @local_job = 1 
  8865.         IF @@ERROR <> 0 or @retcode <> 0
  8866.             GOTO UNDO
  8867.     END            
  8868.  
  8869.     INSERT syspublications(description, name, repl_freq,
  8870.                            status, sync_method, snapshot_jobid, independent_agent,
  8871.                            immediate_sync, enabled_for_internet, 
  8872.                            allow_push, allow_pull, allow_anonymous, immediate_sync_ready,
  8873.                            -- SyncTran
  8874.                            allow_sync_tran, autogen_sync_procs, retention)
  8875.  
  8876.     VALUES (@description, @publication, @rfid, @statid, @smid, NULL, 
  8877.             @independent_agent_id, 
  8878.             @immediate_sync_id, @enabled_for_internet_id, @allow_push_id,
  8879.             @allow_pull_id, @allow_anonymous_id, 0,
  8880.             -- SyncTran
  8881.             @allow_sync_tran_id, @autogen_sync_procs_id, @retention)
  8882.  
  8883.     IF @@ERROR <> 0
  8884.     BEGIN
  8885.         RAISERROR (14018, 16, -1)
  8886.         GOTO UNDO
  8887.     END
  8888.  
  8889.     SELECT @pubid = @@IDENTITY
  8890.  
  8891.     DECLARE @false bit
  8892.     SELECT @false = 0
  8893.  
  8894.     DECLARE @null sysname
  8895.     SELECT @null = NULL
  8896.  
  8897.     /*
  8898.     ** Add the publication to the distributor side
  8899.     */
  8900.     SELECT @distproc = RTRIM(@distributor) + '.' + @distribdb + 
  8901.         '.dbo.sp_MSadd_publication'
  8902.     EXECUTE @retcode = @distproc
  8903.     @publisher = @@SERVERNAME,
  8904.     @publisher_db = @dbname,
  8905.     @publication = @publication,
  8906.     @publication_type = @rfid,
  8907.     @independent_agent = @independent_agent_id,
  8908.     @immediate_sync = @immediate_sync_id,
  8909.     @allow_push = @allow_push_id,
  8910.     @allow_pull = @allow_pull_id,
  8911.     @allow_anonymous = @allow_anonymous_id,
  8912.     @snapshot_agent = @null,
  8913.     @logreader_agent = @agentname,
  8914.     @description = @description,
  8915.     @retention = @retention
  8916.  
  8917.     IF @@ERROR <> 0 or @retcode <> 0
  8918.         BEGIN
  8919.             GOTO UNDO
  8920.         END
  8921.  
  8922.     -- Populate the initial list.
  8923.     exec @retcode = dbo.sp_grant_publication_access 
  8924.         @publication = @publication,
  8925.         @login = null,
  8926.         @reserved = 'init'
  8927.     IF @@error <> 0 OR @retcode <> 0
  8928.         GOTO UNDO
  8929.  
  8930.     COMMIT TRAN
  8931.  
  8932.     RETURN(0)
  8933.  
  8934. UNDO:
  8935.     IF @@TRANCOUNT > 0
  8936.     begin
  8937.         ROLLBACK TRAN sp_addpublication
  8938.         COMMIT TRAN   
  8939.     end
  8940.     return 1
  8941. go
  8942.  
  8943. grant execute on dbo.sp_addpublication to public
  8944. go
  8945.  
  8946. --------------------------------------------------------------------------------
  8947. --. sp_articlecolumn
  8948. --------------------------------------------------------------------------------
  8949. if exists (select * from sysobjects    where type = 'P'
  8950.     and name = 'sp_articlecolumn')
  8951.     drop procedure sp_articlecolumn
  8952. go
  8953.  
  8954. raiserror('Creating procedure sp_articlecolumn', 0,1)
  8955. go
  8956.  
  8957. CREATE PROCEDURE sp_articlecolumn (
  8958.         @publication sysname,           /* The publication name */
  8959.         @article sysname,               /* The article name */
  8960.         @column sysname = NULL,         /* The column name */
  8961.         @operation nvarchar(4) = 'add'      /* Add or delete a column */
  8962.         -- synctran
  8963.         , @refresh_synctran_procs bit = 1      -- refresh synctran procs or not
  8964.         , @ignore_distributor bit = 0
  8965.         ) AS
  8966.  
  8967.     /*
  8968.     ** Declarations.
  8969.     */
  8970.  
  8971.     DECLARE @bit tinyint                /* Bit offset */
  8972.     --DECLARE @byte tinyint               /* Byte offset */
  8973.     DECLARE @word tinyint               /* word offset */
  8974.     DECLARE @cnt tinyint, @idx tinyint  /* Loop counter, index */
  8975.     DECLARE @columns binary(32)         /* Temporary storage for the converted column */
  8976.     DECLARE @mask binary(2)              /* Bit mask to set the bit on */
  8977.     DECLARE @mval int
  8978. --    DECLARE @newbyte binary(1)          /* New byte to replace old byte with */
  8979. --    DECLARE @oldbyte binary(1)          /* Temporary storage for original byte */
  8980.     DECLARE @newword binary(2)
  8981.     DECLARE @oldword binary(2)
  8982.     DECLARE @pubid int                  /* Publication identification number */
  8983.     DECLARE @retcode int                /* Return code for stored procedures */
  8984. --    DECLARE @zero binary(32)            /* Constant:  0 */
  8985.     DECLARE @artid int
  8986.     DECLARE @inactive tinyint
  8987.     DECLARE @objid int            /* Article base table id */    
  8988.     DECLARE @tablename  sysname
  8989.  
  8990.     select @inactive = 0
  8991.  
  8992.     /*
  8993.     ** Security Check
  8994.     */
  8995.     exec @retcode = dbo.sp_MSreplcheck_publish
  8996.     if @@ERROR <> 0 or @retcode <> 0
  8997.         return(1)
  8998.  
  8999.     /*
  9000.     ** Check to see if the database has been activated for publication.
  9001.     ** Do not check if @ignore_distributor indicates brute force cleanup.
  9002.     */
  9003.  
  9004.     IF ( (SELECT category & 1
  9005.           FROM master..sysdatabases
  9006.          WHERE name = DB_NAME()) = 0 )  and ( @ignore_distributor = 0 )
  9007.  
  9008.     BEGIN
  9009.             RAISERROR (14013, 16, -1)
  9010.         RETURN (1)
  9011.     END
  9012.  
  9013.     /*
  9014.     ** Parameter Check:  @publication.
  9015.     ** Make sure that the publication exists and that it conforms to the
  9016.     ** rules for identifiers.
  9017.     */
  9018.  
  9019.     IF @publication IS NULL
  9020.         BEGIN
  9021.             RAISERROR (14043, 16, -1, '@publication')
  9022.             RETURN (1)
  9023.         END
  9024.  
  9025.     EXECUTE @retcode = dbo.sp_validname @publication
  9026.  
  9027.     IF @retcode <> 0
  9028.             RETURN (1)
  9029.  
  9030.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  9031.  
  9032.     IF @pubid IS NULL
  9033.         BEGIN
  9034.             RAISERROR (20026, 11, -1, @publication)
  9035.             RETURN (1)
  9036.         END
  9037.     ELSE
  9038.  
  9039.     /*
  9040.     ** Parameter Check:  @article.
  9041.     ** Check to make sure that the article exists in the publication.
  9042.     */
  9043.  
  9044.     IF @article IS NULL
  9045.         BEGIN
  9046.             RAISERROR (14043, 16, -1, '@article')
  9047.             RETURN (1)
  9048.         END
  9049.  
  9050.     /*
  9051.     EXECUTE @retcode = dbo.sp_validname @article
  9052.  
  9053.     IF @@ERROR <> 0 OR @retcode <> 0
  9054.     RETURN (1)
  9055.     */
  9056.  
  9057.     /*
  9058.     ** Make sure the article exists.
  9059.     */
  9060.     SELECT @artid = artid FROM sysarticles
  9061.        WHERE pubid = @pubid AND name = @article
  9062.     IF @artid IS NULL
  9063.         BEGIN
  9064.             RAISERROR (20027, 11, -1, @article)
  9065.             RETURN (1)
  9066.         END
  9067.  
  9068.     /*
  9069.     ** Only unsubscribed articles may be modified. (excluding virtual subscriptions)
  9070.     */
  9071.     IF EXISTS (SELECT * FROM syssubscriptions WHERE artid = @artid
  9072.        AND status <> @inactive
  9073.        AND srvid >= 0)
  9074.         BEGIN
  9075.             RAISERROR (14092, 11, -1)
  9076.             RETURN (1)
  9077.         END
  9078.  
  9079.     /*
  9080.     ** Error out if this is a not a table based article
  9081.     */
  9082.     IF NOT EXISTS ( SELECT * FROM sysarticles WHERE artid = @artid
  9083.                       AND pubid = @pubid
  9084.                       AND (type & 1) = 1 )
  9085.         BEGIN
  9086.             RAISERROR (14112, 11, -1 )
  9087.             RETURN (1)
  9088.         END
  9089.  
  9090.     /*
  9091.     ** Parameter Check:  @column.
  9092.     ** Check to make sure that the column exists and conforms to the rules
  9093.     ** for identifiers.
  9094.     */
  9095.  
  9096.     /*
  9097.     IF @column IS NOT NULL
  9098.         BEGIN
  9099.             EXECUTE @retcode = dbo.sp_validname @column
  9100.             IF @@ERROR <> 0 OR @retcode <> 0
  9101.             RETURN (1)
  9102.         END
  9103.     */
  9104.  
  9105.     /*
  9106.     ** Parameter Check:  @operation.
  9107.     ** The operation can be either 'add' or 'drop'.
  9108.     */
  9109.  
  9110.     IF LOWER(@operation) NOT IN ('add', 'drop')
  9111.         BEGIN
  9112.             RAISERROR (14019, 16, -1)
  9113.             RETURN (1)
  9114.         END
  9115.         
  9116.     SELECT @objid = (SELECT objid FROM sysarticles WHERE artid = @artid)
  9117.     SELECT @tablename = OBJECT_NAME(@objid)
  9118.     
  9119.      if @column is not null
  9120.     begin
  9121.         -- If the publication is allow_sync_tran, we cannot drop the timestamp
  9122.         -- column from the partition.
  9123.         if exists (select * from syspublications where name = @publication and
  9124.             allow_sync_tran = 1) and LOWER(@operation) = 'drop'
  9125.         begin
  9126.             declare @ts_col sysname
  9127.             exec dbo.sp_MSis_col_replicated @publication, @article, 
  9128.                 'timestamp', @ts_col OUTPUT 
  9129.             if @ts_col = @column
  9130.             BEGIN
  9131.                 if @@trancount > 0
  9132.                 begin
  9133.                     ROLLBACK TRANSACTION articlecolumn
  9134.                     commit tran
  9135.                 end
  9136.                 RAISERROR (21080, 16, -1)
  9137.                 RETURN (1)
  9138.             END
  9139.         end
  9140.     end
  9141.  
  9142.     begin tran
  9143.     save TRANSACTION articlecolumn
  9144.  
  9145.     /*
  9146.     ** Make sure that the columns column is not NULL.
  9147.     */
  9148.  
  9149.     IF EXISTS (SELECT *
  9150.                  FROM sysarticles
  9151.                 WHERE name = @article
  9152.                   AND pubid = @pubid
  9153.                   AND columns IS NULL)
  9154.  
  9155.             UPDATE sysarticles
  9156.               SET columns = 0x00
  9157.             WHERE name = @article
  9158.               AND pubid = @pubid
  9159.  
  9160.     /*
  9161.     ** If no columns are specified, or if NULL is specified, set all
  9162.     ** the bits in the 'columns' column so all columns will be included.
  9163.     */
  9164.  
  9165.     IF @column IS NULL
  9166.     BEGIN
  9167.        DECLARE hCartcolumn CURSOR LOCAL FAST_FORWARD FOR
  9168.             SELECT name FROM syscolumns where
  9169.                 id = @objid
  9170.     END
  9171.     ELSE
  9172.     BEGIN
  9173.        DECLARE hCartcolumn CURSOR LOCAL FAST_FORWARD FOR 
  9174.             SELECT @column
  9175.     END
  9176.  
  9177.  
  9178.     OPEN hCartcolumn
  9179.  
  9180.     FETCH hCartcolumn INTO @column
  9181.  
  9182.     WHILE (@@fetch_status <> -1)
  9183.     BEGIN
  9184.  
  9185.         DECLARE @columnid smallint   /* Columnid-1 = bit to set */
  9186.  
  9187.         /*
  9188.         ** Get the column id for this column.  We'll use the column id
  9189.         ** to determine the bit in the 'columns' column.  The bit we want
  9190.         ** is equal to the columnid - 1.
  9191.         */
  9192.  
  9193.         SELECT @columnid = colid
  9194.           FROM syscolumns
  9195.          WHERE id = @objid AND name = @column
  9196.  
  9197.         IF ((@@error <> 0) OR (@columnid IS NULL))
  9198.             BEGIN
  9199.                 if @@trancount > 0
  9200.                 begin
  9201.                     ROLLBACK TRANSACTION articlecolumn
  9202.                     commit tran
  9203.                 end
  9204.                 RAISERROR (14020, 16, -1)
  9205.                 RETURN (1)
  9206.             END        
  9207.  
  9208.         /*
  9209.         ** Obtain the byte offset and the bit offset, then set the
  9210.         ** mask column for the bit we want to turn on.
  9211.         */
  9212.  
  9213.         SELECT @word = CONVERT(tinyint, 16 - FLOOR((@columnid-1)/16))
  9214.         SELECT @bit = (@columnid-1) % 16
  9215.  
  9216.         IF LOWER(@operation) = 'add'
  9217.             SELECT @mval = POWER(2, @bit)
  9218.         ELSE
  9219.             SELECT @mval = ~POWER(2, @bit)
  9220.  
  9221.         select @mask = convert( binary(2), substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) )
  9222.  
  9223.         /*
  9224.         ** Save the columns column in a temporary local variable so we
  9225.         ** can twiddle the bit and then put it back into the table.
  9226.         */
  9227.  
  9228.         SELECT @columns = columns
  9229.           FROM sysarticles
  9230.          WHERE name = @article
  9231.            AND pubid = @pubid
  9232.  
  9233.         /*
  9234.         ** Fish out the byte we're interested in and save it in a
  9235.         ** a temporary local variable.  If it's NULL, just set it
  9236.         ** to 0.  Then apply the bitwise operator OR to twiddle the
  9237.         ** bit in the old byte and save it in another temporary
  9238.         ** local variable @newbyte.
  9239.         */
  9240.         SELECT @oldword = CONVERT( binary(2), SUBSTRING( CONVERT( nvarchar,@columns), @word, 1) )
  9241.  
  9242.         IF @oldword IS NULL SELECT @oldword = 0x0000
  9243.  
  9244.         IF LOWER(@operation) = 'add'
  9245.             SELECT @newword = CONVERT(binary(2), convert(smallint, @oldword) | @mask)
  9246.         ELSE
  9247.             SELECT @newword = CONVERT(binary(2), convert(smallint, @oldword ) & @mask)
  9248.  
  9249.         SELECT @columns = CONVERT(binary(32), STUFF( convert(nchar(16),@columns), @word, 1, convert( nchar(1), @newword)))
  9250.         SELECT @idx = @idx + 1
  9251.  
  9252.        IF LOWER(@operation) = 'drop'
  9253.        BEGIN
  9254.  
  9255.            /* Update Text\Image column status as not published */
  9256.           EXECUTE @retcode = dbo.sp_MSarticletextcol @artid, @columnid,
  9257.              'publish', @operation
  9258.           IF (@@error <> 0 OR @retcode <> 0)
  9259.           BEGIN
  9260.             if @@trancount > 0
  9261.             begin
  9262.                 ROLLBACK TRANSACTION articlecolumn
  9263.                 commit tran
  9264.             end
  9265.              RAISERROR (14021, 16, -1)
  9266.              RETURN (1)
  9267.           END
  9268.        END
  9269.  
  9270.         /*
  9271.         ** Update the sysarticles table.  Set the bit to 1 for the
  9272.         ** selected column.
  9273.         */
  9274.  
  9275.         UPDATE sysarticles
  9276.            SET columns = @columns
  9277.          WHERE name = @article
  9278.            AND pubid = @pubid
  9279.  
  9280.         IF @@error <> 0
  9281.             BEGIN
  9282.                 if @@trancount > 0
  9283.                 begin
  9284.                     ROLLBACK TRANSACTION articlecolumn
  9285.                     commit tran
  9286.                 end
  9287.                 RAISERROR (14021, 16, -1)
  9288.                 RETURN (1)
  9289.             END
  9290.  
  9291.        IF LOWER(@operation) = 'add'
  9292.        BEGIN
  9293.  
  9294.            /* Update Text\Image column status as not published */
  9295.           EXECUTE @retcode = dbo.sp_MSarticletextcol @artid, @columnid,
  9296.              'publish', @operation
  9297.           IF (@@error <> 0 OR @retcode <> 0)
  9298.           BEGIN
  9299.             if @@trancount > 0
  9300.             begin
  9301.                 ROLLBACK TRANSACTION articlecolumn
  9302.                 commit tran
  9303.             end
  9304.              RAISERROR (14021, 16, -1)
  9305.              RETURN (1)
  9306.           END
  9307.  
  9308.        END
  9309.        FETCH hCartcolumn INTO @column
  9310.     END
  9311.  
  9312.     -- Synctran
  9313.     /*
  9314.     ** If publication is enabled for Synctran and sprocs are auto-generated - regenerate them
  9315.     */
  9316.     declare @autogen_sync_procs_id bit
  9317.     declare @ins_proc_id int, @upd_proc_id int, @del_proc_id int
  9318.     declare @ins_proc sysname, @upd_proc sysname, @del_proc sysname, @owner sysname, @objname sysname
  9319.     declare @sync_pubid int
  9320.     declare @cmd nvarchar(4000)
  9321.  
  9322.     select @autogen_sync_procs_id = autogen_sync_procs, @sync_pubid = pubid
  9323.     from syspublications where name = @publication
  9324.  
  9325.     if  @autogen_sync_procs_id = 1 and @refresh_synctran_procs = 1 
  9326.     begin
  9327.         -- Drop existing synctran procs
  9328.         select @owner = user_name(OBJECTPROPERTY(objid, 'OwnerId')) from sysarticles a, syspublications p
  9329.         where a.name = @article and
  9330.               p.name = @publication and
  9331.               a.pubid = p.pubid
  9332.  
  9333.         select @ins_proc_id = sync_ins_proc, @upd_proc_id = sync_upd_proc, @del_proc_id = sync_del_proc
  9334.         from sysarticleupdates
  9335.         where pubid = @pubid and artid = @artid
  9336.  
  9337.         if @ins_proc_id is not null
  9338.         begin
  9339.             select @objname = object_name(@ins_proc_id)     
  9340.             exec @retcode = dbo.sp_MSdrop_object
  9341.                 @object_name = @objname,
  9342.                 @object_owner = @owner
  9343.             if @@error <> 0 or @retcode <> 0
  9344.                 return (1)
  9345.         end
  9346.  
  9347.         if @upd_proc_id is not null
  9348.         begin
  9349.             select @objname = object_name(@upd_proc_id)     
  9350.             exec @retcode = dbo.sp_MSdrop_object
  9351.                 @object_name = @objname,
  9352.                 @object_owner = @owner
  9353.             if @@error <> 0 or @retcode <> 0
  9354.                 return (1)
  9355.         end
  9356.  
  9357.         if @del_proc_id is not null
  9358.         begin
  9359.             select @objname = object_name(@del_proc_id)     
  9360.             exec @retcode = dbo.sp_MSdrop_object
  9361.                 @object_name = @objname,
  9362.                 @object_owner = @owner
  9363.             if @@error <> 0 or @retcode <> 0
  9364.                 return (1)
  9365.         end
  9366.  
  9367.         -- Now generate new ones        
  9368.         select @ins_proc = 'sp_MSsync_ins_' + SUBSTRING(RTRIM(@article), 1, 100) + '_' + rtrim(convert(varchar, @sync_pubid))
  9369.         select @upd_proc = 'sp_MSsync_upd_' + SUBSTRING(RTRIM(@article), 1, 100) + '_' + rtrim(convert(varchar, @sync_pubid))
  9370.         select @del_proc = 'sp_MSsync_del_' + SUBSTRING(RTRIM(@article), 1, 100) + '_' + rtrim(convert(varchar, @sync_pubid))
  9371.  
  9372.         -- check uniqueness of names and revert to ugly guid-based name if friendly name already exists
  9373.         if exists (select name from sysobjects where name in (@ins_proc, @upd_proc, @del_proc))
  9374.         begin
  9375.             declare @guid_name nvarchar(36)
  9376.             select @guid_name =  convert (nvarchar(36), newid())
  9377.             -- remove '-' from guid name because rpc can't handle '-'
  9378.             select @guid_name = replace (@guid_name,'-','_')
  9379.             select @ins_proc = 'sp_MSsync_ins_' + @guid_name
  9380.             select @upd_proc = 'sp_MSsync_upd_' + @guid_name
  9381.             select @del_proc = 'sp_MSsync_del_' + @guid_name
  9382.         end
  9383.  
  9384.         if @ins_proc IS NULL
  9385.         begin
  9386.             if @@trancount > 0
  9387.                 ROLLBACK TRANSACTION 
  9388.             RAISERROR (14043, 11, -1, '@ins_proc')
  9389.             RETURN (1)
  9390.         end
  9391.  
  9392.         if @upd_proc IS NULL
  9393.         begin
  9394.             if @@trancount > 0
  9395.                 ROLLBACK TRANSACTION 
  9396.             RAISERROR (14043, 11, -1, '@upd_proc')
  9397.             RETURN (1)
  9398.         end
  9399.  
  9400.         if @del_proc IS NULL
  9401.         begin
  9402.             if @@trancount > 0
  9403.                 ROLLBACK TRANSACTION 
  9404.             RAISERROR (14043, 11, -1, '@del_proc')
  9405.             RETURN (1)
  9406.         end
  9407.  
  9408.         exec @retcode = dbo.sp_MSgen_sync_tran_procs @publication, @article, @ins_proc, @upd_proc, @del_proc
  9409.  
  9410.         IF @@ERROR <> 0 OR @retcode <> 0
  9411.         BEGIN
  9412.             if @@trancount > 0
  9413.             begin
  9414.                 ROLLBACK TRAN articlecolumn
  9415.                 commit tran
  9416.             end
  9417.             RETURN (1)
  9418.         END
  9419.  
  9420.         --retrieve sproc id's, fail if they don't exist
  9421.         SELECT @ins_proc_id = id FROM sysobjects WHERE name = @ins_proc
  9422.         SELECT @upd_proc_id = id FROM sysobjects WHERE name = @upd_proc
  9423.         SELECT @del_proc_id = id FROM sysobjects WHERE name = @del_proc
  9424.  
  9425.         IF (@ins_proc_id IS NULL) OR (@upd_proc_id IS NULL) OR (@del_proc_id IS NULL)
  9426.         BEGIN
  9427.             if @ins_proc_id IS NULL RAISERROR (20500, 16, 1, @ins_proc)
  9428.             if @upd_proc_id IS NULL RAISERROR (20500, 16, 1, @upd_proc)
  9429.             if @del_proc_id IS NULL RAISERROR (20500, 16, 1, @del_proc)
  9430.             if @@trancount > 0
  9431.             begin
  9432.                 ROLLBACK tran articlecolumn
  9433.                 commit tran
  9434.             end
  9435.             RETURN (1)
  9436.         END
  9437.  
  9438.         -- perform update in sysarticleupdates
  9439.         update sysarticleupdates set sync_ins_proc = @ins_proc_id, sync_upd_proc = @upd_proc_id, 
  9440.             sync_del_proc = @del_proc_id
  9441.         where pubid = @pubid and artid = @artid
  9442.  
  9443.         IF @@ERROR <> 0
  9444.         BEGIN
  9445.             RAISERROR (20501, 16, -1)
  9446.             if @@trancount > 0
  9447.             begin
  9448.                 ROLLBACK tran articlecolumn
  9449.                 commit tran
  9450.             end
  9451.             RETURN (1)
  9452.          END
  9453.     end
  9454.     -- end synctran
  9455.  
  9456.     /*
  9457.     ** Force the article cache to be refreshed with the new definition.
  9458.     ** Nothing to flush if brute force cleanup.
  9459.     */
  9460.     if ( @ignore_distributor = 0 )
  9461.         EXECUTE dbo.sp_replflush
  9462.  
  9463.     COMMIT TRANSACTION
  9464. go
  9465.  
  9466.  
  9467. grant execute on dbo.sp_articlecolumn to public
  9468. go
  9469.  
  9470. --------------------------------------------------------------------------------
  9471. --. sp_addarticle
  9472. --------------------------------------------------------------------------------
  9473. if exists (select * from sysobjects    where type = 'P'
  9474.     and name = 'sp_addarticle')
  9475.     drop procedure sp_addarticle
  9476. go
  9477.  
  9478. raiserror('Creating procedure sp_addarticle', 0,1)
  9479. go
  9480.  
  9481. CREATE PROCEDURE sp_addarticle
  9482.     @publication sysname,               /* publication name */
  9483.     @article sysname,             /* article name */
  9484.     @source_table nvarchar (386) = NULL,         /* table name */
  9485.     @destination_table sysname = NULL, /* destination table name */
  9486.     @vertical_partition nchar(5) = 'false',  /* vertical partition */
  9487.     @type sysname = NULL,        /* article type */
  9488.     @filter nvarchar (386) = NULL,        /* stored procedure used to filter table */
  9489.     @sync_object nvarchar (386) = NULL,        /* view or table used for synchronization */
  9490.     @ins_cmd nvarchar (255) = NULL,        /* insert format string */
  9491.     @del_cmd nvarchar (255) = NULL,        /* delete format string */
  9492.     @upd_cmd nvarchar (255) = NULL,        /* update format string */
  9493.     @creation_script nvarchar (127) = NULL,  /* article schema script */
  9494.     @description nvarchar (255) = NULL,        /* article description */
  9495.     @pre_creation_cmd nvarchar(10) = 'drop', /* 'none', 'drop', 'delete', 'truncate' */
  9496.     @filter_clause ntext    = NULL,            /* where clause */
  9497.     @schema_option binary(8) = NULL,
  9498.     @destination_owner sysname = NULL,
  9499.     @status tinyint = 16,                        /* Default: binary command format */
  9500.     @source_owner    sysname = NULL,             /* NULL for 6.5 users, not NULL for 7.0 users */
  9501.     @sync_object_owner sysname = NULL,             /* NULL for 6.5 users, not NULL for 7.0 users */
  9502.     @filter_owner    sysname = NULL,                /* NULL for 6.5 users, not NULL for 7.0 users */
  9503.     @source_object    sysname = NULL                /* if @source_table is NULL, this parameter can not be NULL */
  9504.     AS
  9505.  
  9506.     SET NOCOUNT ON
  9507.  
  9508.     /*
  9509.     ** Declarations.
  9510.     */    
  9511.     DECLARE @bak_source sysname
  9512.     DECLARE @num_columns int
  9513.     DECLARE @accessid smallint
  9514.     DECLARE @db sysname
  9515.     DECLARE @filterid int
  9516.     DECLARE @object sysname
  9517.     DECLARE @owner sysname
  9518.     DECLARE @pubid int
  9519.     DECLARE @publish_bit smallint
  9520.     DECLARE @retcode int
  9521.     DECLARE @site sysname
  9522.     DECLARE @syncid int
  9523.     DECLARE @tabid int
  9524.     DECLARE @typeid smallint
  9525.     DECLARE @pkkey sysname
  9526.     DECLARE @i int
  9527.     DECLARE @indid int
  9528.     DECLARE @precmdid int
  9529.     DECLARE @object_type nchar(2)
  9530.     DECLARE @push tinyint
  9531.     DECLARE @dbname sysname
  9532.     DECLARE @cmd nvarchar(255)
  9533.     DECLARE @fHasPk int
  9534.     DECLARE @no_sync tinyint
  9535.     DECLARE @immediate_sync bit
  9536.     DECLARE @is_filter_in_use int
  9537.     DECLARE @distributor sysname
  9538.     DECLARE @distribdb sysname
  9539.     DECLARE @distproc nvarchar (255)
  9540.     DECLARE @article_id int
  9541.     DECLARE @sync_method tinyint
  9542.     -- SyncTran
  9543.     DECLARE @autogen_sync_procs_id int
  9544.     DECLARE @custom_proc_name varchar(32)
  9545.     DECLARE @guid varbinary(16)
  9546.     declare @allow_sync_tran bit
  9547.     DECLARE @repl_freq int
  9548.  
  9549.  
  9550.     SELECT @push = 0
  9551.     SELECT @dbname = DB_NAME()
  9552.  
  9553.     SELECT @publish_bit = 1
  9554.  
  9555.     SELECT @no_sync = 2 /* no sync type in syssubscriptions */
  9556.  
  9557.     /*
  9558.     ** Security Check.
  9559.     */
  9560.     exec @retcode = dbo.sp_MSreplcheck_publish
  9561.     if @@ERROR <> 0 or @retcode <> 0
  9562.         return(1)
  9563.  
  9564.     /*
  9565.     ** Parameter Check: @article.
  9566.     ** The @article name cannot be NULL and must conform to the rules
  9567.     ** for identifiers.
  9568.     */
  9569.  
  9570.     IF @article IS NULL
  9571.         BEGIN
  9572.             RAISERROR (14043, 16, -1, '@article')
  9573.             RETURN (1)
  9574.         END
  9575.  
  9576.     exec @retcode = dbo.sp_MSreplcheck_name @article
  9577.     if @@ERROR <> 0 or @retcode <> 0
  9578.         return(1)
  9579.  
  9580.     if LOWER(@article) = 'all'
  9581.         BEGIN
  9582.             RAISERROR (14032, 16, -1, '@article')
  9583.             RETURN (1)
  9584.         END
  9585.  
  9586.     /*
  9587.     ** Parameter Check: @publication.
  9588.     ** The @publication name cannot be NULL and must conform to the rules
  9589.     ** for identifiers.
  9590.     */
  9591.  
  9592.     IF @publication IS NULL
  9593.     BEGIN
  9594.         RAISERROR (14043, 16, -1, '@publication')
  9595.         RETURN (1)
  9596.     END
  9597.  
  9598.     EXECUTE @retcode = dbo.sp_validname @publication
  9599.  
  9600.     IF @retcode <> 0
  9601.     RETURN (1)
  9602.  
  9603.     /*
  9604.     ** Parameter Check: @destination_owner.
  9605.     ** The @destination_owner must conform to the rules
  9606.     ** for identifiers.
  9607.     */
  9608.  
  9609.     if @destination_owner is not null
  9610.     BEGIN
  9611.         -- native bcp mode publications are for odbc subscribers. Destination
  9612.         -- owner name is not supported.
  9613.         if exists (select * from syspublications where name = @publication and
  9614.             sync_method = 1)
  9615.         begin
  9616.             raiserror(21039,16, -1)
  9617.             return(1)
  9618.         end
  9619.         EXECUTE @retcode = dbo.sp_validname @destination_owner
  9620.  
  9621.         IF @retcode <> 0
  9622.             RETURN (1)
  9623.     END
  9624.  
  9625.     /*
  9626.     ** Parameter Check: @source_table.
  9627.     ** Check to see that the @source_table is local, that it conforms
  9628.     ** to the rules for identifiers, and that it is a table, and not
  9629.     ** a view or another database object.
  9630.     */
  9631.  
  9632.     IF @source_table IS NULL
  9633.         BEGIN
  9634.             if @source_object is NOT NULL
  9635.                 select @source_table = @source_object
  9636.             else
  9637.                 begin
  9638.                     RAISERROR (14043, 16, -1, '@source_table')
  9639.                     RETURN (1)
  9640.                 end
  9641.         END
  9642.  
  9643.     IF @source_owner is NULL -- 6.5 users only
  9644.     begin
  9645.         IF @source_table LIKE '%.%.%' AND PARSENAME(@source_table, 3) <> DB_NAME()
  9646.                BEGIN
  9647.                   RAISERROR (14004, 16, -1, @source_table)
  9648.                   RETURN (1)
  9649.                END
  9650.     end
  9651.  
  9652.     -- For 7.0 users, @source_owner is not nullable.
  9653.     
  9654.     select @bak_source = @source_table
  9655.     
  9656.     IF @source_owner is not NULL
  9657.         begin
  9658.             select @source_table = QUOTENAME(@source_owner) + '.' + QUOTENAME(@source_table)
  9659.             IF @destination_table IS NULL
  9660.                 SELECT @destination_table = @bak_source
  9661.         end
  9662.     ELSE IF @destination_table IS NULL
  9663.         -- Set destination_table if not provided or default by now.
  9664.         -- If @source_table is qualified (6.x behavior) only use table name for destination name.
  9665.         SELECT @destination_table = PARSENAME(@source_table, 1)    
  9666.         
  9667.     select @num_columns=count(*) from syscolumns where id = object_id(@source_table)
  9668.     if @num_columns > 255
  9669.         begin
  9670.             RAISERROR (20068, 16, @source_table, 255)
  9671.             RETURN (1)
  9672.         end
  9673.  
  9674.     /*
  9675.     **  Get the id of the @source_table
  9676.     */
  9677.     SELECT @tabid = id, @object_type = type
  9678.     FROM sysobjects
  9679.     WHERE id = OBJECT_ID(@source_table)
  9680.  
  9681.     IF @tabid IS NULL
  9682.         BEGIN
  9683.             RAISERROR (14027, 11, -1, @source_table)
  9684.             RETURN (1)
  9685.         END
  9686.  
  9687.     -- at this point, we've done all the common parameter checks.
  9688.     -- If this is a procedure, branch to the proc execution publishing
  9689.     -- routine, otherwise continue processing as if it were a table
  9690.  
  9691.     IF @object_type = 'P'
  9692.     BEGIN
  9693.         begin tran
  9694.         save TRAN sp_addarticle
  9695.  
  9696.         EXECUTE @retcode = dbo.sp_MSaddexecarticle @publication,
  9697.             @article,
  9698.             @source_table,
  9699.             @destination_table,
  9700.             @type,
  9701.             @creation_script,
  9702.             @description,
  9703.             @pre_creation_cmd,
  9704.             @schema_option,
  9705.             @destination_owner,
  9706.             @article_id OUTPUT
  9707.  
  9708.         IF @retcode <> 0
  9709.         BEGIN
  9710.             if @@trancount > 0
  9711.             begin
  9712.                 ROLLBACK TRAN sp_addarticle
  9713.                 commit tran
  9714.             end
  9715.             RETURN (1)
  9716.         END
  9717.         ELSE
  9718.             GOTO DONE
  9719.     END
  9720.  
  9721.     /*
  9722.     ** Make sure that the table name specified is a table and not a view.
  9723.     */
  9724.  
  9725.     IF NOT EXISTS (SELECT * FROM sysobjects
  9726.         WHERE id = (SELECT OBJECT_ID(@source_table))
  9727.         AND type = 'U')
  9728.     BEGIN
  9729.         RAISERROR (14028, 16, -1)
  9730.         RETURN (1)
  9731.     END
  9732.  
  9733.     /*
  9734.     ** Parameter Check:  @destination_table.
  9735.     ** If the destination table is not specified, assume it's the same
  9736.     ** as the source table.  Make sure that the table name is not qualified.
  9737.     */
  9738.  
  9739.     IF @destination_table LIKE '%.%.%'
  9740.     BEGIN
  9741.         RAISERROR (14001, 16, -1)
  9742.         RETURN (1)
  9743.     END
  9744.  
  9745.     IF @destination_table LIKE '%.%'
  9746.     BEGIN
  9747.         RAISERROR (14044, 16, -1, '@destination_table')
  9748.         RETURN (1)
  9749.     END
  9750.  
  9751.     /*
  9752.     ** Parameter Check: @vertical_partition
  9753.     ** Check to make sure that the vertical partition is either TRUE or FALSE.
  9754.     */
  9755.  
  9756.     SELECT @vertical_partition = LOWER(@vertical_partition)
  9757.     IF @vertical_partition NOT IN ('true', 'false')
  9758.     BEGIN
  9759.         RAISERROR (14029, 16, -1)
  9760.         RETURN (1)
  9761.     END
  9762.  
  9763.     --
  9764.     -- parameter check: @status
  9765.     --
  9766.  
  9767.     IF (@status & ~24 ) <> 0
  9768.     BEGIN
  9769.         RAISERROR( 21061, 16, -1, @status, @article )
  9770.         RETURN (1)
  9771.     END
  9772.  
  9773.     /*
  9774.     ** Parameter Check: @filter
  9775.     ** Make sure that the filter is a valid stored procedure.
  9776.     */
  9777.     IF @filter IS NOT NULL
  9778.     BEGIN
  9779.         IF @filter_owner IS NULL
  9780.         BEGIN
  9781.             select @object = PARSENAME( @filter, 1 )
  9782.             select @owner  = PARSENAME( @filter, 2 )
  9783.             select @db     = PARSENAME( @filter, 3 )
  9784.             select @site   = PARSENAME( @filter, 4 )
  9785.  
  9786.             if @object IS NULL
  9787.               return 1
  9788.         END  
  9789.         ELSE
  9790.         BEGIN
  9791.             select @filter = QUOTENAME(@filter_owner) + '.' + QUOTENAME(@filter)
  9792.         END
  9793.  
  9794.         /*
  9795.         ** Get the id of the @filter
  9796.         */
  9797.         select @filterid = id from sysobjects where
  9798.             id = OBJECT_ID(@filter) and type = 'RF'
  9799.         IF @filterid IS NULL
  9800.         BEGIN
  9801.             RAISERROR (14027, 11, -1, @filter)
  9802.             RETURN (1)
  9803.         END
  9804.  
  9805.         EXEC @is_filter_in_use = dbo.sp_MSdoesfilterhaveparent @filterid
  9806.         if( @is_filter_in_use <> 0 )
  9807.         BEGIN
  9808.             RAISERROR( 21009, 11, -1 )
  9809.             RETURN (1)
  9810.         END
  9811.     END
  9812.     ELSE
  9813.         select @filterid = 0
  9814.  
  9815.  
  9816.     /*
  9817.     ** Get the pubid.
  9818.     */
  9819.  
  9820.     -- SyncTran
  9821.     -- SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  9822.     SELECT @pubid = pubid, @autogen_sync_procs_id = autogen_sync_procs, @sync_method = sync_method,
  9823.         @allow_sync_tran = allow_sync_tran 
  9824.     FROM syspublications WHERE name = @publication
  9825.     -- end SyncTran
  9826.  
  9827.     IF @pubid IS NULL
  9828.         BEGIN
  9829.             RAISERROR (14027, 11, -1, @publication)
  9830.             RETURN (1)
  9831.         END
  9832.  
  9833.     /*
  9834.     ** Parameter Check:  @article, @publication.
  9835.     ** Check if the article already exists in this publication.
  9836.     */
  9837.  
  9838.     IF EXISTS (SELECT *
  9839.                  FROM sysarticles
  9840.                 WHERE pubid = @pubid
  9841.                   AND name = @article)
  9842.         BEGIN
  9843.             RAISERROR (14030, 16, -1, @article, @publication)
  9844.             RETURN (1)
  9845.         END
  9846.  
  9847.     /*
  9848.     ** Set the typeid.  The default type is logbased.  Anything else is
  9849.     ** currently undefined (reserved for future use).
  9850.     **
  9851.     **      @typeid     type
  9852.     **      =======     ========
  9853.     **          1     logbased
  9854.     **          3     logbased manualfilter
  9855.     **          5     logbased manualview
  9856.     **          7     logbased manualboth
  9857.     **          8     proc exec              (valid in dbo.sp_MSaddexecarticle)
  9858.     **          24    serializable proc exec (valid in dbo.sp_MSaddexecarticle)
  9859.     */
  9860.  
  9861.  
  9862.     IF @type IS NULL
  9863.     BEGIN
  9864.     SELECT @type = 'logbased'
  9865.     END
  9866.     ELSE IF LOWER(@type) NOT IN ('logbased', 'logbased manualfilter', 'logbased manualview', 'logbased manualboth')
  9867.     BEGIN
  9868.         RAISERROR (14023, 16, -1)
  9869.         RETURN (1)
  9870.     END
  9871.  
  9872.     IF LOWER(@type) = 'logbased'
  9873.         SELECT @typeid = 1
  9874.     ELSE IF LOWER(@type) = 'logbased manualfilter'
  9875.        SELECT @typeid = 3
  9876.     ELSE IF LOWER(@type) = 'logbased manualview'
  9877.        SELECT @typeid = 5
  9878.     ELSE IF LOWER(@type) = 'logbased manualboth'
  9879.         SELECT @typeid = 7
  9880.  
  9881.     /*
  9882.     ** Set the precmdid.  The default type is 'drop'.
  9883.     **
  9884.     **      @precmdid   pre_creation_cmd
  9885.     **      =========   ================
  9886.     **            0     none
  9887.     **          1     drop
  9888.     **          2     delete
  9889.     **          3     truncate
  9890.     */
  9891.     IF LOWER(@pre_creation_cmd) NOT IN ('none', 'drop', 'delete', 'truncate')
  9892.     BEGIN
  9893.         RAISERROR (14061, 16, -1)
  9894.         RETURN (1)
  9895.     END
  9896.  
  9897.     /*
  9898.     ** Determine the integer value for the pre_creation_cmd.
  9899.     */
  9900.     IF LOWER(@pre_creation_cmd) = 'none'
  9901.         SELECT @precmdid = 0
  9902.     ELSE IF LOWER(@pre_creation_cmd) = 'drop'
  9903.         SELECT @precmdid = 1
  9904.     ELSE IF LOWER(@pre_creation_cmd) = 'delete'
  9905.         SELECT @precmdid = 2
  9906.     ELSE IF LOWER(@pre_creation_cmd) = 'truncate'
  9907.         SELECT @precmdid = 3
  9908.  
  9909.     IF @sync_object IS NULL
  9910.         select @syncid = @tabid
  9911.     ELSE
  9912.     BEGIN
  9913.  
  9914.     IF @sync_object_owner is NULL  -- 6.5 only
  9915.     BEGIN
  9916.  
  9917.         /*
  9918.         ** Parameter Check: @sync_object.
  9919.         ** Check to see that the sync_object is local and that it
  9920.         ** conforms to the rules for identifiers.
  9921.         */
  9922.  
  9923.         select @object = PARSENAME( @sync_object, 1 )
  9924.         select @owner  = PARSENAME(  @sync_object, 2 )
  9925.         select @db     = PARSENAME(  @sync_object, 3 )
  9926.         select @site   = PARSENAME(  @sync_object, 4 )
  9927.  
  9928.         if @object IS NULL
  9929.               return 1
  9930.  
  9931.  
  9932.         IF @sync_object LIKE '%.%.%' AND @db <> DB_NAME()
  9933.         BEGIN
  9934.             RAISERROR (14004, 16, -1, @sync_object)
  9935.             RETURN (1)
  9936.         END
  9937.  
  9938.     END -- end of 65 processing
  9939.     else -- for sphinx, @sync_object_owner can not be null
  9940.         select @sync_object = QUOTENAME(@sync_object_owner) + '.' + QUOTENAME(@sync_object)
  9941.         
  9942.         /*
  9943.         **  Get the id of the @sync_object
  9944.         */
  9945.  
  9946.         SELECT @syncid = id FROM sysobjects WHERE id = OBJECT_ID(@sync_object)
  9947.  
  9948.         IF @syncid IS NULL
  9949.         BEGIN
  9950.             RAISERROR (14027, 11, -1, @sync_object)
  9951.             RETURN (1)
  9952.         END
  9953.  
  9954.         /*
  9955.         ** Make sure the sync object specified is a table or a view.
  9956.         */
  9957.  
  9958.         IF NOT EXISTS (SELECT * FROM sysobjects
  9959.                 WHERE id = (SELECT OBJECT_ID(@sync_object))
  9960.                 AND (type = 'U' or
  9961.                      type = 'V'))
  9962.         BEGIN
  9963.             RAISERROR (14031, 16, -1)
  9964.             RETURN (1)
  9965.         END
  9966.     END
  9967.  
  9968.     /*
  9969.     ** If the publication is log-based,
  9970.     ** make sure there is a primary key on the source table.
  9971.     ** NOTE!  sprok in SPSUP.SQL
  9972.     */
  9973.     IF EXISTS (SELECT * FROM syspublications 
  9974.         WHERE pubid = @pubid AND
  9975.             (repl_freq = 0 OR allow_sync_tran = 1)
  9976.             )
  9977.     BEGIN
  9978.         EXEC @fHasPk = dbo.sp_MSreplsup_table_has_pk @tabid
  9979.  
  9980.         IF @fHasPk = 0
  9981.         BEGIN
  9982.             RAISERROR (14088, 16, -1, @source_table)
  9983.             RETURN (1)
  9984.         END
  9985.     END
  9986.  
  9987.     /*
  9988.     ** Parameter Check:  @creation_script and @schema_option
  9989.     ** @schema_option cannot be null
  9990.     ** If @schema_option is 0, there have to be @creation_script defined.
  9991.     */
  9992.     SELECT @repl_freq = repl_freq from syspublications where name = @publication
  9993.     IF @schema_option IS NULL
  9994.     BEGIN
  9995.         -- Snapshot publication, no cust. proc. generation
  9996.         IF @repl_freq = 1 
  9997.         BEGIN
  9998.             SELECT @schema_option  = 0x0000000000000071
  9999.         END
  10000.         ELSE
  10001.         BEGIN
  10002.             SELECT @schema_option  = 0x0000000000000073
  10003.         END
  10004.     END
  10005.  
  10006.     /*
  10007.     ** Parameter Check: @schema_option
  10008.     ** If bit 0x2 is set, this cannot be an article for a snapshot publication
  10009.     **
  10010.     */
  10011.     IF ((CONVERT(INT, @schema_option) & 0x2) <> 0) AND (@repl_freq = 1)
  10012.     BEGIN
  10013.         RAISERROR (21143, 16, -1)
  10014.         RETURN (1)
  10015.     END
  10016.  
  10017.     -- If pub sync_type is character mode bcp(1) 
  10018.     if @sync_method = 1
  10019.     begin
  10020.         select @status = 0
  10021.         if @ins_cmd is NULL  select @ins_cmd = 'SQL'
  10022.         if @upd_cmd is NULL  select @upd_cmd = 'SQL'
  10023.         if @del_cmd is NULL  select @del_cmd = 'SQL'
  10024.     end
  10025.  
  10026.     /*
  10027.     ** Parameter Check: @schema_option
  10028.     ** If Autogeneration of custom procedures is not enabled 
  10029.     ** then the default commands will be SQL
  10030.     */
  10031.     IF ((CONVERT(int, @schema_option) & 0x2) = 0)
  10032.     BEGIN
  10033.         if @ins_cmd is NULL  select @ins_cmd = 'SQL'
  10034.         if @upd_cmd is NULL  select @upd_cmd = 'SQL'
  10035.         if @del_cmd is NULL  select @del_cmd = 'SQL'
  10036.     END
  10037.           
  10038.     -- Autogenerate custom procedure names if not provided.
  10039.     -- If unable to construct a name because the article name is close to the maximum length, then create a
  10040.     -- name based on the database timestamp
  10041.     if ((@source_object is not NULL and len(@article) > 119) or
  10042.         (@source_object is NULL and len(@article) > 21)) or
  10043.         exists (select * from sysarticles where name = @article)
  10044.     begin
  10045.         set @guid = CONVERT(varbinary(16), LEFT(NEWID(),8))
  10046.         exec @retcode = master.dbo.xp_varbintohexstr @guid, @custom_proc_name OUTPUT
  10047.         if @@error <> 0 or @retcode <> 0
  10048.             RETURN(1)
  10049.     end
  10050.     else
  10051.         set @custom_proc_name = @article
  10052.  
  10053.     -- If no command then construct name 
  10054.     if @ins_cmd is NULL
  10055.     begin
  10056.         if (@status & 16) <> 0 -- parameterized
  10057.         begin
  10058.             if @source_object is not NULL  -- 7.0 format
  10059.                 set @ins_cmd = N'CALL ' + convert (sysname, 'sp_MSins_' + @custom_proc_name)
  10060.             else -- 6.x compatible
  10061.                 set @ins_cmd = N'CALL ' + convert(nvarchar(30), 'sp_MSins_' + @custom_proc_name)
  10062.         end
  10063.         else
  10064.             select @ins_cmd = 'SQL'
  10065.     end
  10066.  
  10067.     if @del_cmd is NULL
  10068.     begin
  10069.         if (@status & 16) <> 0 -- parameterized
  10070.         begin
  10071.             if @source_object is not NULL  -- 7.0 format
  10072.                 set @del_cmd = N'CALL ' + convert (sysname, 'sp_MSdel_' + @custom_proc_name)
  10073.             else -- 6.x compatible
  10074.                 set @del_cmd = N'CALL ' + convert(nvarchar(30), 'sp_MSdel_' + @custom_proc_name)
  10075.         end
  10076.         else
  10077.             select @del_cmd = 'SQL'
  10078.     end
  10079.  
  10080.     if @upd_cmd is NULL
  10081.     begin
  10082.         if (@status & 16) <> 0 -- parameterized
  10083.         begin
  10084.             if @source_object is not NULL  -- 7.0 format
  10085.                 set @upd_cmd = N'MCALL ' + convert (sysname, 'sp_MSupd_' + @custom_proc_name)
  10086.             else -- 6.x compatible
  10087.                 set @upd_cmd = N'CALL ' + convert(nvarchar(30), 'sp_MSupd_' + @custom_proc_name)
  10088.         end
  10089.         else
  10090.             select @upd_cmd = 'SQL'
  10091.     end
  10092.  
  10093.     -- SyncTran
  10094.     -- Add timestamp column if not exists
  10095.     if @allow_sync_tran = 1 and ObjectProperty(@tabid, 'TableHasTimestamp') = 0
  10096.     begin
  10097.         exec ('alter table ' + @source_table + ' add msrepl_synctran_ts timestamp not null' )
  10098.         IF @@ERROR <> 0 
  10099.             RETURN (1)
  10100.     end
  10101.  
  10102.     /*
  10103.     **  Add article to sysarticles and update sysobjects category bit.
  10104.     */
  10105.     begin tran
  10106.     save TRAN sp_addarticle
  10107.         INSERT sysarticles (columns, creation_script, del_cmd, description,
  10108.             dest_table, filter, filter_clause, ins_cmd, name,
  10109.             objid, pre_creation_cmd, pubid,
  10110.             status, sync_objid, type, upd_cmd, schema_option,
  10111.             dest_owner)
  10112.         VALUES (0, @creation_script, @del_cmd, @description, @destination_table,
  10113.             @filterid, @filter_clause, @ins_cmd, @article, @tabid,
  10114.             @precmdid, @pubid, @status, @syncid, @typeid, @upd_cmd, @schema_option, 
  10115.             @destination_owner)
  10116.  
  10117.         IF @@ERROR <> 0
  10118.         BEGIN
  10119.             if @@trancount > 0
  10120.             begin
  10121.                 ROLLBACK TRAN sp_addarticle
  10122.                 commit tran
  10123.             end
  10124.             RETURN (1)
  10125.         END
  10126.  
  10127.         SELECT @article_id = @@IDENTITY
  10128.  
  10129.         UPDATE sysobjects SET replinfo =  replinfo |  @publish_bit
  10130.             WHERE id = (SELECT objid FROM sysarticles WHERE name = @article 
  10131.                 and pubid =  @pubid)
  10132.  
  10133.         IF @@ERROR <> 0
  10134.         BEGIN
  10135.             if @@trancount > 0
  10136.             begin
  10137.                 ROLLBACK TRAN sp_addarticle
  10138.                 commit tran
  10139.             end
  10140.             RETURN (1)
  10141.         END
  10142.  
  10143.         IF @filter IS NOT NULL
  10144.         BEGIN
  10145.             EXEC dbo.sp_MSsetfilterparent @filter, @tabid
  10146.             IF @@ERROR <> 0
  10147.             BEGIN
  10148.                 if @@trancount > 0
  10149.                 begin
  10150.                     ROLLBACK TRAN sp_addarticle
  10151.                     commit tran
  10152.                 end
  10153.                 RETURN (1)
  10154.             END
  10155.         END
  10156.  
  10157.         EXEC dbo.sp_MSsetfilteredstatus @tabid
  10158.         IF @@ERROR <> 0
  10159.         BEGIN
  10160.             if @@trancount > 0
  10161.             begin
  10162.                 ROLLBACK TRAN sp_addarticle
  10163.                 commit tran
  10164.             end
  10165.             RETURN (1)
  10166.         END
  10167.  
  10168.         /*
  10169.         ** Set all bits to '1' in the columns column to include all columns.
  10170.         */
  10171.  
  10172.         IF @vertical_partition = 'false'
  10173.         BEGIN
  10174.             EXECUTE @retcode  = dbo.sp_articlecolumn @publication, @article
  10175.             -- synctran
  10176.             , @refresh_synctran_procs = 0
  10177.             
  10178.             IF @@ERROR <> 0 OR @retcode <> 0
  10179.             BEGIN
  10180.                 if @@trancount > 0
  10181.                 begin
  10182.                     ROLLBACK TRAN sp_addarticle
  10183.                     commit tran
  10184.                 end
  10185.                 RETURN (1)
  10186.             END
  10187.         END
  10188.         
  10189.         /*
  10190.         ** 1. Set all bits to '1' for all columns in the primary key.
  10191.         ** 2. Set timestamp column bit to 1 if the publication is synctran
  10192.         */
  10193.         ELSE
  10194.         BEGIN
  10195.             SELECT @indid = indid FROM sysindexes
  10196.             WHERE id = @tabid
  10197.             AND (status & 2048) <> 0    /* PK index */
  10198.         
  10199.             /*
  10200.             **  First we'll figure out what the keys are.
  10201.             */
  10202.             SELECT @i = 1
  10203.  
  10204.             WHILE (@i <= 16)
  10205.             BEGIN
  10206.                 SELECT @pkkey = INDEX_COL(@source_table, @indid, @i)
  10207.                 if @pkkey is NULL
  10208.                     break
  10209.  
  10210.                 EXECUTE @retcode  = dbo.sp_articlecolumn @publication,
  10211.                     @article, @pkkey, 'add'
  10212.                     -- synctran
  10213.                     , @refresh_synctran_procs = 0
  10214.                 IF @@ERROR <> 0 OR @retcode <> 0
  10215.                 BEGIN
  10216.                     if @@trancount > 0
  10217.                     begin
  10218.                         ROLLBACK TRAN sp_addarticle
  10219.                         commit tran
  10220.                     end
  10221.                     RETURN (1)
  10222.                 END
  10223.  
  10224.                 select @i = @i + 1
  10225.             END
  10226.  
  10227.             if @allow_sync_tran = 1 and ObjectProperty(@tabid, 'TableHasTimestamp') = 1
  10228.             begin
  10229.                 declare @ts_col sysname
  10230.                 -- Get synctran column
  10231.                 select @ts_col = name from syscolumns 
  10232.                     where id = @tabid and type_name(xtype) = 'timestamp' 
  10233.                 if @ts_col is not null
  10234.                 begin
  10235.                     EXECUTE @retcode  = dbo.sp_articlecolumn @publication,
  10236.                         @article, @ts_col, 'add'
  10237.                         -- synctran
  10238.                         , @refresh_synctran_procs = 0
  10239.                     IF @@ERROR <> 0 OR @retcode <> 0
  10240.                     BEGIN
  10241.                         if @@trancount > 0
  10242.                         begin
  10243.                             ROLLBACK TRAN sp_addarticle
  10244.                             commit tran
  10245.                         end
  10246.                         RETURN (1)
  10247.                     END
  10248.                 end
  10249.             end
  10250.         END
  10251.  
  10252.         ------------------------------------------------------------------------------
  10253.         -- if table based article does not use a view for sync, create one and use it
  10254.         ------------------------------------------------------------------------------
  10255.  
  10256.         if @tabid = @syncid 
  10257.         begin
  10258.             -- generate view name
  10259.  
  10260.             declare @viewname varchar(255)
  10261.  
  10262.             set @guid = CONVERT(varbinary(16), LEFT(NEWID(),8))
  10263.             exec @retcode = master.dbo.xp_varbintohexstr @guid, @viewname OUTPUT
  10264.             if @@ERROR <> 0 OR @retcode <> 0
  10265.             begin
  10266.                 if @@trancount > 0
  10267.                 begin
  10268.                     ROLLBACK TRAN sp_addarticle
  10269.                     commit tran
  10270.                 end
  10271.                 return 1
  10272.             end
  10273.             
  10274.             set @viewname = 'syncobj_' + @viewname
  10275.  
  10276.             -- create view for object synchronization
  10277.  
  10278.             exec @retcode = dbo.sp_articleview @publication, @article, @viewname, @filter_clause
  10279.             if @@ERROR <> 0 OR @retcode <> 0
  10280.             begin
  10281.                 if @@trancount > 0
  10282.                 begin
  10283.                     ROLLBACK TRAN sp_addarticle
  10284.                     commit tran
  10285.                 end
  10286.                 return 1
  10287.             end
  10288.         end
  10289.  
  10290.  DONE:
  10291.  
  10292.         /*
  10293.         ** Get distribution server information for remote RPC call.
  10294.         */
  10295.         EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  10296.            @distribdb   = @distribdb OUTPUT
  10297.         IF @@ERROR <> 0 or @retcode <> 0
  10298.             BEGIN
  10299.                 RAISERROR (14071, 16, -1)
  10300.                 RETURN (1)
  10301.             END
  10302.  
  10303.         SELECT @dbname =  DB_NAME()
  10304.         
  10305.         SELECT @distproc = RTRIM(@distributor) + '.' + @distribdb + 
  10306.             '.dbo.sp_MSadd_article'
  10307.         EXECUTE @retcode = @distproc
  10308.             @publisher = @@SERVERNAME,
  10309.             @publisher_db = @dbname,
  10310.             @publication = @publication,
  10311.             @article = @article,
  10312.             @article_id = @article_id,
  10313.             @destination_object = @destination_table,
  10314.             @source_owner = @source_owner,
  10315.             @source_object = @bak_source,
  10316.             @description = @description
  10317.  
  10318.  
  10319.         IF @@ERROR <> 0 OR @retcode <> 0
  10320.         BEGIN
  10321.             if @@trancount > 0
  10322.             begin
  10323.                 ROLLBACK TRAN sp_addarticle
  10324.                 commit tran
  10325.             end
  10326.             RETURN (1)
  10327.         END
  10328.         
  10329.         
  10330.         /* If the publication is immediate_sync type
  10331.         ** 1. Change the immediate_sync_ready status to false 
  10332.         ** 2. Add a virtual subscription on the article 
  10333.         ** 3. Add subscriptions for all the subscriber
  10334.         ** that have no_sync subscriptions on the publication
  10335.         **
  10336.         ** Note: Subscriptions for subscribers that have automatic sync subscriptions
  10337.         ** on the publication will be added by snasphot agent.
  10338.         */
  10339.         if EXISTS (SELECT *    FROM syspublications WHERE
  10340.             name = @publication    AND
  10341.             immediate_sync = 1 )
  10342.         BEGIN
  10343.             UPDATE syspublications SET immediate_sync_ready = 0
  10344.                 WHERE name = @publication 
  10345.             IF @@ERROR <> 0 
  10346.             BEGIN
  10347.                 if @@trancount > 0
  10348.                 begin
  10349.                     ROLLBACK TRAN sp_addarticle
  10350.                     commit tran
  10351.                 end
  10352.                 RETURN (1)
  10353.             END
  10354.  
  10355.  
  10356.             EXECUTE @retcode  = dbo.sp_addsubscription 
  10357.                 @publication = @publication, 
  10358.                 @article = @article, 
  10359.                 @subscriber = NULL, 
  10360.                 @destination_db = 'virtual', 
  10361.                 @sync_type = 'automatic', 
  10362.                 @status = NULL, 
  10363.                 @reserved = 'internal'
  10364.             IF @@ERROR <> 0 OR @retcode <> 0
  10365.             BEGIN
  10366.                 if @@trancount > 0
  10367.                 begin
  10368.                     ROLLBACK TRAN sp_addarticle
  10369.                     commit tran
  10370.                 end
  10371.                 RETURN (1)
  10372.             END
  10373.  
  10374.             -- Note: We have to add the subscriptions to the new article before 
  10375.             -- the virtual subscriptions being activated!!!! Otherwise, the snapshot 
  10376.             -- transactions may be skipped by dist agents.
  10377.             EXECUTE @retcode  = dbo.sp_refreshsubscriptions @publication
  10378.  
  10379.             IF @@ERROR <> 0 OR @retcode <> 0
  10380.             BEGIN
  10381.                 if @@trancount > 0
  10382.                 begin
  10383.                     ROLLBACK TRAN sp_addarticle
  10384.                     commit tran
  10385.                 end
  10386.                 RETURN (1)
  10387.             END 
  10388.         END
  10389.  
  10390.         /* 
  10391.         ** if @autogen_sync_procs_id is 1, autogen the sync tran procs, including name 
  10392.         */
  10393.         if @tabid > 0 and @autogen_sync_procs_id = 1
  10394.         begin
  10395.             declare @insproc sysname, @updproc sysname, @delproc sysname
  10396.  
  10397.             select @insproc = 'sp_MSsync_ins_' + SUBSTRING(RTRIM(@article), 1, 100) + '_' + rtrim(convert(varchar, @pubid))
  10398.             select @updproc = 'sp_MSsync_upd_' + SUBSTRING(RTRIM(@article), 1, 100) + '_' + rtrim(convert(varchar, @pubid))
  10399.             select @delproc = 'sp_MSsync_del_' + SUBSTRING(RTRIM(@article), 1, 100) + '_' + rtrim(convert(varchar, @pubid))
  10400.  
  10401.             -- check uniqueness of names and revert to ugly guid-based name if friendly name already exists
  10402.             if exists (select name from sysobjects where name in (@insproc, @updproc, @delproc))
  10403.             begin
  10404.                 declare @guid_name nvarchar(36)
  10405.                 select @guid_name =  convert (nvarchar(36), newid())
  10406.                 -- remove '-' from guid name because rpc can't handle '-'
  10407.                 select @guid_name = replace (@guid_name,'-','_')
  10408.                 select @insproc = 'sp_MSsync_ins_' + @guid_name
  10409.                 select @updproc = 'sp_MSsync_upd_' + @guid_name
  10410.                 select @delproc = 'sp_MSsync_del_' + @guid_name
  10411.             end
  10412.  
  10413.             if @insproc IS NULL
  10414.             begin
  10415.                 if @@trancount > 0
  10416.                 begin
  10417.                     ROLLBACK TRANSACTION sp_addarticle
  10418.                     commit tran
  10419.                 end
  10420.                 RAISERROR (14043, 11, -1, '@insproc')
  10421.                 RETURN (1)
  10422.             end
  10423.  
  10424.             if @updproc IS NULL
  10425.             begin
  10426.                 if @@trancount > 0
  10427.                 begin
  10428.                     ROLLBACK TRANSACTION sp_addarticle
  10429.                     commit tran
  10430.                 end
  10431.                 RAISERROR (14043, 11, -1, '@updproc')
  10432.                 RETURN (1)
  10433.             end
  10434.  
  10435.             if @delproc IS NULL
  10436.             begin
  10437.                 if @@trancount > 0
  10438.                 begin
  10439.                     ROLLBACK TRANSACTION sp_addarticle
  10440.                     commit tran
  10441.                 end
  10442.                 RAISERROR (14043, 11, -1, '@delproc')
  10443.                 RETURN (1)
  10444.             end
  10445.  
  10446.  
  10447.             exec @retcode = dbo.sp_articlesynctranprocs @publication, @article, @insproc, @updproc, @delproc, true
  10448.  
  10449.             IF @@ERROR <> 0 OR @retcode <> 0
  10450.             BEGIN
  10451.                 if @@trancount > 0
  10452.                 begin
  10453.                     ROLLBACK TRANSACTION sp_addarticle
  10454.                     commit tran
  10455.                 end
  10456.                 RETURN (1)
  10457.             END
  10458.         end
  10459.         -- end SyncTran
  10460.  
  10461.     COMMIT TRANSACTION
  10462. go
  10463.  
  10464. grant execute on dbo.sp_addarticle to public
  10465. go
  10466.  
  10467. --------------------------------------------------------------------------------
  10468. --. sp_MSpublishdb
  10469. --------------------------------------------------------------------------------
  10470. if exists (select * from sysobjects    where type = 'P'
  10471.     and name = 'sp_MSpublishdb')
  10472.     drop procedure sp_MSpublishdb
  10473. go
  10474.  
  10475. raiserror('Creating procedure sp_MSpublishdb', 0,1)
  10476. go
  10477.  
  10478.  
  10479. CREATE PROCEDURE sp_MSpublishdb(
  10480.       @value     sysname,
  10481.       @ignore_distributor bit = 0
  10482.     ) AS
  10483.  
  10484.     SET NOCOUNT ON
  10485.  
  10486.     /*
  10487.     ** Declarations.
  10488.     */
  10489.     declare @quoted_db      sysname
  10490.     declare @db_name        sysname
  10491.     declare @command        nvarchar(255)
  10492.     declare @description    nvarchar(500)
  10493.     declare @category_name  nvarchar(100)
  10494.     DECLARE @agentname      nvarchar(300)
  10495.     DECLARE @dbname         sysname 
  10496.     DECLARE @retcode        int
  10497.     DECLARE @distributor    sysname
  10498.     DECLARE @distribdb      sysname
  10499.     DECLARE @distproc       nvarchar (255)
  10500.     DECLARE @replicate_bit    smallint
  10501.  
  10502.     SELECT @replicate_bit = 2
  10503.  
  10504.     /*
  10505.     ** Initialization
  10506.     */
  10507.  
  10508.     SELECT @dbname = DB_NAME()
  10509.  
  10510.     /*
  10511.     ** Parameter check
  10512.     ** @value
  10513.     */
  10514.     IF LOWER(@value) NOT IN ('true','false')
  10515.     BEGIN
  10516.       RAISERROR(14137,16,-1)
  10517.       RETURN(1)
  10518.     END
  10519.  
  10520.     /*
  10521.     ** if @ignore_distributor = 1, we are in bruteforce cleanup mode, don't do RPC.
  10522.     */
  10523.     if @ignore_distributor = 0
  10524.     begin
  10525.         /*
  10526.         ** Test to see if the distributor is installed and online.
  10527.         */
  10528.         EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  10529.            @distribdb   = @distribdb OUTPUT
  10530.  
  10531.         IF @@ERROR <> 0 or @retcode <> 0 or @distributor IS NULL or @distribdb IS NULL
  10532.         BEGIN
  10533.             IF LOWER(@value) = 'true'
  10534.                 RAISERROR (20028, 16, -1)
  10535.             ELSE
  10536.                 RAISERROR (20029, 16, -1)
  10537.             RETURN (1)
  10538.         END
  10539.     end
  10540.  
  10541.     /*
  10542.     ** Enable the database for publishing.
  10543.     */
  10544.     IF LOWER(@value) = 'true'
  10545.     BEGIN
  10546.  
  10547.         /*
  10548.         ** Drop and then create central publish tables
  10549.         */
  10550.  
  10551.         /* 
  10552.         ** Drop first if exists
  10553.         */
  10554.  
  10555.         EXEC @retcode = dbo.sp_MSdrop_pub_tables
  10556.         IF @@ERROR <> 0 or @retcode <> 0
  10557.         BEGIN
  10558.             return (1)
  10559.         END
  10560.  
  10561.         /*
  10562.         ** Create central publish tables
  10563.         */
  10564.  
  10565.         EXEC @retcode = dbo.sp_MScreate_pub_tables
  10566.         IF @@ERROR <> 0 or @retcode <> 0
  10567.         BEGIN
  10568.             return (1)
  10569.         END
  10570.     END
  10571.  
  10572.     ELSE    /* Disable the database for publishing. */
  10573.     BEGIN
  10574.         /*
  10575.         ** Remove all subscriptions in the database.
  10576.         ** WARNING : must owner qualify proc calls for these to run inside server on restore/attach
  10577.         */
  10578.         EXEC @retcode = dbo.sp_dropsubscription @publication = 'all',
  10579.             @article = 'all', @subscriber = 'all', 
  10580.             @ignore_distributor = @ignore_distributor
  10581.         IF @@ERROR <> 0 or @retcode <> 0
  10582.         BEGIN
  10583.             return (1)
  10584.         END
  10585.  
  10586.         -- Used for attach and restored db.
  10587.         -- sysservers table in master db might be changed so that
  10588.         -- sp_dropsubscription won't work. Delete the table directly.
  10589.         -- Before dropping the table, we need to unmark repl bits in sysobjects
  10590.         -- see below
  10591.  
  10592.         delete syssubscriptions where srvid >= 0
  10593.         IF @@ERROR <> 0 
  10594.         BEGIN
  10595.             return (1)
  10596.         END
  10597.  
  10598.         /*
  10599.         ** Remove all publications and articles in the database.
  10600.         */
  10601.         EXEC @retcode = dbo.sp_droppublication @publication = 'all', 
  10602.             @ignore_distributor = @ignore_distributor
  10603.         IF @@ERROR <> 0 or @retcode <> 0
  10604.         BEGIN
  10605.             return (1)
  10606.         END
  10607.   
  10608.         /*
  10609.         ** Remove all published database transactions from the distribution
  10610.         ** database.
  10611.         */
  10612.         if @ignore_distributor = 0
  10613.         begin
  10614.             SELECT  @distproc = RTRIM(@distributor) + '.' +
  10615.                     RTRIM(@distribdb) + '.dbo.sp_MSremove_published_jobs '
  10616.             EXEC @retcode = @distproc @@SERVERNAME, @dbname
  10617.             IF @@ERROR <> 0 or @retcode <> 0
  10618.             BEGIN
  10619.                 return (1)
  10620.             END
  10621.         end
  10622.  
  10623.         /*
  10624.         ** Publishing shutdown, remove all xacts pending distribution
  10625.         */
  10626.  
  10627.         /* ensure we can get in as logreader */
  10628.  
  10629.         EXEC @retcode = dbo.sp_replflush
  10630.         IF @@ERROR <> 0 or @retcode <> 0
  10631.         BEGIN
  10632.             return (1)
  10633.         END
  10634.  
  10635.         /* unmark all xacts marked for replication */
  10636.  
  10637.         select @quoted_db = QUOTENAME(@dbname)
  10638.         EXEC ( 'USE ' + @quoted_db + ' exec dbo.sp_repldone NULL, NULL, 0, 0, 1' )
  10639.         IF @@ERROR <> 0 
  10640.         BEGIN
  10641.             return (1)
  10642.         END
  10643.     
  10644.         /* release our hold on the db as logreader */
  10645.         EXEC dbo.sp_replflush
  10646.         IF @@ERROR <> 0 
  10647.         BEGIN
  10648.             RETURN(1)
  10649.         END
  10650.  
  10651.         /* 
  10652.         ** Drop central publish tables
  10653.         */ 
  10654.         EXEC @retcode = dbo.sp_MSdrop_pub_tables
  10655.         IF @@ERROR <> 0 or @retcode <> 0
  10656.         BEGIN
  10657.             return (1)
  10658.         END
  10659.             
  10660.         -- Used for attached and restored db.
  10661.         -- sysservers table in master db might be changed so that
  10662.         -- sp_dropsubscription won't work. Unmark repl bits in sysobjects
  10663.         -- directly.
  10664.         UPDATE sysobjects SET replinfo =  replinfo & ~@replicate_bit
  10665.     END
  10666.     return (0)
  10667. GO
  10668.  
  10669. --------------------------------------------------------------------------------
  10670. --. sp_MSget_synctran_commands
  10671. --------------------------------------------------------------------------------
  10672. if exists (select * from sysobjects    where type = 'P'
  10673.     and name = 'sp_MSget_synctran_commands')
  10674.     drop procedure sp_MSget_synctran_commands
  10675. go
  10676.  
  10677. raiserror('Creating procedure sp_MSget_synctran_commands', 0,1)
  10678. go
  10679.  
  10680. CREATE PROCEDURE sp_MSget_synctran_commands(
  10681.     @publication sysname    /* publication name */,
  10682.     @article sysname = 'all',
  10683.     @command_only bit = 0   /* 0 if called by snapshot agent, 1 if called by sp_script_..., */
  10684. ) AS
  10685.  
  10686.     SET NOCOUNT ON
  10687.     DECLARE @artid int
  10688.     DECLARE @tabid int
  10689.     DECLARE @retcode int
  10690.     declare @art_type tinyint        
  10691.     declare @filter_id int
  10692.     declare @filter_clause nvarchar(4000)
  10693.     declare @columns binary(32)
  10694.  
  10695.     DECLARE @pubid int,
  10696.         @art_name sysname, 
  10697.         @posted_synctran_artid int,
  10698.         @dest_table sysname, 
  10699.         @dest_owner sysname,
  10700.         @proc_owner sysname
  10701.  
  10702.     /*
  10703.     ** Initializations.
  10704.     */
  10705.     select @posted_synctran_artid = 0 
  10706.  
  10707.     /* 
  10708.     ** Security Check.
  10709.     ** We use login_name stored in syssubscriptions to manage security 
  10710.     ** Do a relaxed security check here.
  10711.     */
  10712.     exec @retcode = dbo.sp_MSreplcheck_publish
  10713.     if @@ERROR <> 0 or @retcode <> 0
  10714.         return(1)
  10715.  
  10716.     /*
  10717.     ** Parameter Check:  @publication
  10718.     ** Check to make sure that the publication exists, that it's not NULL,
  10719.     ** and that it conforms to the rules for identifiers.
  10720.     */
  10721.  
  10722.     IF @publication IS NULL
  10723.         BEGIN
  10724.             RAISERROR (14043, 16, -1, '@publication')
  10725.             RETURN (1)
  10726.         END
  10727.  
  10728.     EXECUTE @retcode = dbo.sp_validname @publication
  10729.     IF @@ERROR <> 0 OR @retcode <> 0
  10730.     RETURN (1)
  10731.  
  10732.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  10733.  
  10734.     IF @pubid IS NULL
  10735.     BEGIN
  10736.         RAISERROR (20026, 11, -1, @publication)
  10737.         RETURN (1)
  10738.     END
  10739.  
  10740.     -- If the publication does not allow sync tran return nothing
  10741.     IF NOT EXISTS (SELECT * FROM syspublications WHERE pubid = @pubid and
  10742.         allow_sync_tran = 1)
  10743.         RETURN(0)
  10744.  
  10745.     CREATE TABLE #art_commands (artid int NOT NULL, commands nvarchar(4000) NULL, id int identity NOT NULL)
  10746.     
  10747.     declare @all_article bit 
  10748.  
  10749.     if lower(@article) = 'all'
  10750.         select @all_article = 1
  10751.     else
  10752.         select @all_article = 0
  10753.  
  10754.     DECLARE hCsynctran_arts CURSOR LOCAL FAST_FORWARD FOR
  10755.         SELECT art.artid,
  10756.                art.objid,
  10757.                
  10758.                art.dest_table,
  10759.                art.dest_owner,
  10760.                art.name,
  10761.                art.type,
  10762.                art.filter,
  10763.                art.columns
  10764.           FROM sysarticles art,
  10765.                syspublications pub
  10766.          WHERE pub.pubid = @pubid and
  10767.                pub.pubid = art.pubid and
  10768.                (art.type & 0x1) = 1 and
  10769.                (art.name = @article or
  10770.                @all_article = 1)
  10771.     FOR READ ONLY
  10772.  
  10773.     OPEN hCsynctran_arts
  10774.  
  10775.     FETCH hCsynctran_arts INTO @artid, @tabid, @dest_table, @dest_owner, @art_name, 
  10776.         @art_type, @filter_id, @columns
  10777.     
  10778.     WHILE (@@fetch_status <> -1)
  10779.     BEGIN
  10780.  
  10781.     /*
  10782.     ** Determine conflict detection method 
  10783.     */
  10784.         declare @ts_col sysname
  10785.         -- Determine if table has timestamp property
  10786.         select @ts_col = NULL
  10787.         if ObjectProperty(@tabid, 'TableHasTimestamp') = 1 
  10788.         begin
  10789.             exec dbo.sp_MSis_col_replicated @publication, @art_name, 
  10790.                 'timestamp', @ts_col OUTPUT
  10791.         end
  10792.  
  10793.         declare @replcmd nvarchar(4000)
  10794.         declare @insproc sysname, @updproc sysname, @delproc sysname
  10795.         declare @identity_col sysname
  10796.         declare @identity_prop tinyint
  10797.  
  10798.         select @posted_synctran_artid = @artid
  10799.  
  10800.         select @insproc = null, @updproc = null, @delproc = null
  10801.  
  10802.         -- Get sproc names and owner name of the sprocs
  10803.         -- Note artid is unique
  10804.         select @insproc = o.name, @proc_owner = u.name from sysobjects o, sysarticleupdates a, sysusers u
  10805.         where a.artid = @artid and a.sync_ins_proc = o.id and
  10806.             u.uid = o.uid
  10807.  
  10808.         select @updproc = o.name from sysobjects o, sysarticleupdates a
  10809.         where a.artid = @artid and a.sync_upd_proc = o.id
  10810.         
  10811.         select @delproc = o.name from sysobjects o, sysarticleupdates a
  10812.         where a.artid = @artid and a.sync_del_proc = o.id 
  10813.  
  10814.         if @insproc IS NULL
  10815.         begin
  10816.             CLOSE hCsynctran_arts
  10817.             DEALLOCATE hCsynctran_arts
  10818.             RAISERROR (14043, 11, -1, '@insproc')
  10819.             RETURN (1)
  10820.         end
  10821.  
  10822.         if @updproc IS NULL 
  10823.         begin
  10824.             CLOSE hCsynctran_arts
  10825.             DEALLOCATE hCsynctran_arts
  10826.             RAISERROR (14043, 11, -1, '@updproc')
  10827.             RETURN (1)
  10828.         end
  10829.  
  10830.         if @delproc IS NULL
  10831.         begin
  10832.             CLOSE hCsynctran_arts
  10833.             DEALLOCATE hCsynctran_arts
  10834.             RAISERROR (14043, 11, -1, '@delproc')
  10835.             RETURN (1)
  10836.         end
  10837.  
  10838.         -- Determine if published table has identity  col
  10839.         select @identity_col = NULL
  10840.         if ObjectProperty(@tabid, 'TableHasIdentity') = 1 
  10841.             exec @retcode = dbo.sp_MSis_col_replicated @publication, @art_name, 'identity', @identity_col OUTPUT
  10842.                 
  10843.         -- Horizontal partition
  10844.         select @filter_clause = 'null'
  10845.         if @filter_id <> 0
  10846.         begin
  10847.             -- We don't handle manual filters;  allow all updates
  10848.             if ((@art_type & 0x3) = 0x3) 
  10849.                 select @filter_clause = ''
  10850.             else
  10851.                 select @filter_clause = RTRIM(LTRIM(CONVERT(nvarchar(4000), filter_clause)))
  10852.                      from sysarticles where artid = @artid
  10853.         end
  10854.     
  10855.         declare @fullname nvarchar(512)
  10856.         declare @indkey       int
  10857.         declare @indid        int
  10858.         declare @key          sysname
  10859.         declare @col          sysname
  10860.         declare @this_col      int
  10861.         declare @src_cols      int
  10862.         declare @primary_key_bitmap varbinary(4000)
  10863.         declare @byte varbinary(1)
  10864.         declare @i_byte            int
  10865.         declare @num_bytes        int
  10866.         declare @i_bit            tinyint    
  10867.         declare @bitmap_str    varchar(8000)
  10868.         declare @bitmap            varbinary(4000)
  10869.  
  10870.  
  10871.         -- Get qualified name
  10872.         exec dbo.sp_MSget_qualified_name @tabid, @fullname output
  10873.         
  10874.         -- Get number of columns in the partition.
  10875.         exec dbo.sp_MSget_col_position @tabid, @columns, @key, @col output, 
  10876.             @this_col output, 
  10877.             1, -- Get num of columns in the partition.
  10878.             @src_cols output
  10879.         select @num_bytes = @src_cols / 8 + 1
  10880.     
  10881.         -- Set varbinary length
  10882.         set @byte = 0
  10883.         set @primary_key_bitmap = @byte
  10884.         set @i_byte = 1
  10885.         while @i_byte < @num_bytes
  10886.         begin
  10887.             set @primary_key_bitmap = @primary_key_bitmap + @byte
  10888.             set @i_byte = @i_byte + 1
  10889.         end
  10890.     
  10891.         -- get index id
  10892.         exec @indid = dbo.sp_MStable_has_unique_index @tabid
  10893.         set @indkey = 1
  10894.         while @indkey < 16 and index_col(@fullname, @indid, @indkey) is not null
  10895.         begin
  10896.             set @key = index_col(@fullname, @indid, @indkey)
  10897.             exec dbo.sp_MSget_col_position @tabid, @columns, @key, @col output, @this_col output
  10898.             set @i_byte = 1 + (@this_col-1) / 8
  10899.             set @i_bit  = power(2, (@this_col-1) % 8 )
  10900.             set @byte = substring(@primary_key_bitmap, @i_byte, 1 )
  10901.             set @byte = @byte | @i_bit
  10902.             if @i_byte = 1
  10903.             begin
  10904.                 set @bitmap = @byte
  10905.             end
  10906.             else
  10907.             begin
  10908.                 set @bitmap = substring(@primary_key_bitmap, 1, @i_byte - 1)
  10909.                 set @bitmap = @bitmap + @byte
  10910.             end
  10911.  
  10912.             if @i_byte <> @num_bytes
  10913.             begin
  10914.                 set @primary_key_bitmap = @bitmap + 
  10915.                     substring(@primary_key_bitmap, @i_byte + 1, @num_bytes - @i_byte)
  10916.             end
  10917.             else
  10918.                 set @primary_key_bitmap = @bitmap
  10919.  
  10920.             select @indkey = @indkey + 1
  10921.         end
  10922.         exec @retcode = master..xp_varbintohexstr @primary_key_bitmap, @bitmap_str output
  10923.         if @retcode <> 0 or @@error <> 0
  10924.             return 1
  10925.  
  10926.         if @dest_owner is null 
  10927.         begin
  10928.             select @dest_owner = N'null'
  10929.         end
  10930.         select @replcmd = '{call sp_addsynctriggers (N' + 
  10931.             quotename(@dest_table,'''') + ', N' + 
  10932.             quotename(@dest_owner,'''') + ', N' +  
  10933.             quotename(@@SERVERNAME,'''') + ', N' +   
  10934.             quotename(db_name(),'''') + ', N' + 
  10935.             quotename(@publication,'''') + ', N' +  
  10936.             quotename(@insproc,'''') + ', N' +   
  10937.             quotename(@updproc,'''') + ', N' +   
  10938.             quotename(@delproc,'''') + ', N' +    
  10939.             quotename(@proc_owner,'''') + ', N' + 
  10940.             ISNULL(quotename(@identity_col,''''),'''null''') + ', N' + 
  10941.             ISNULL(quotename(@ts_col,''''), '''null''') + ', N''' + 
  10942.             replace(@filter_clause,'''', '''''')  + ''', ' + 
  10943.             @bitmap_str + ')}'
  10944.  
  10945.         insert into #art_commands values (@artid, @replcmd)
  10946.  
  10947.         FETCH hCsynctran_arts INTO @artid, @tabid, @dest_table, @dest_owner, @art_name, 
  10948.             @art_type, @filter_id, @columns
  10949.     end
  10950.  
  10951.     -- end SyncTran
  10952.     if @command_only = 0 
  10953.         select * from #art_commands order by id
  10954.     else
  10955.         select commands from #art_commands order by id
  10956.  
  10957.     CLOSE hCsynctran_arts
  10958.     DEALLOCATE hCsynctran_arts
  10959.  
  10960. go
  10961.  
  10962. grant exec on dbo.sp_MSget_synctran_commands to public
  10963. go
  10964.  
  10965. --------------------------------------------------------------------------------
  10966. --. sp_MSis_pk_col
  10967. --------------------------------------------------------------------------------
  10968. if exists (select * from sysobjects    where type = 'P'
  10969.     and name = 'sp_MSis_pk_col')
  10970.     drop procedure sp_MSis_pk_col
  10971. go
  10972.  
  10973. raiserror('Creating procedure sp_MSis_pk_col', 0,1)
  10974. go
  10975.  
  10976. create proc sp_MSis_pk_col @source_table sysname, @colname sysname, @indid int
  10977. as
  10978. begin
  10979.  
  10980.     declare @indkey int
  10981.     select @indkey = 1
  10982.  
  10983.     while @indkey < 16 and index_col(@source_table, @indid, @indkey) is not null
  10984.     begin
  10985.         if index_col(@source_table, @indid, @indkey) = @colname
  10986.             return (1)
  10987.  
  10988.         select @indkey = @indkey + 1
  10989.     end
  10990.  
  10991.     return (0)
  10992. end
  10993. GO
  10994.  
  10995. --------------------------------------------------------------------------------
  10996. --. sp_MSdrop_expired_subscription
  10997. --------------------------------------------------------------------------------
  10998. if exists (select * from sysobjects    where type = 'P'
  10999.     and name = 'sp_MSdrop_expired_subscription')
  11000.     drop procedure sp_MSdrop_expired_subscription
  11001. go
  11002.  
  11003. raiserror('Creating procedure sp_MSdrop_expired_subscription', 0,1)
  11004. go
  11005.  
  11006. create procedure sp_MSdrop_expired_subscription
  11007. AS
  11008. /*
  11009. ** This stored procedure is to periodically check the status of all the subscriptions 
  11010. ** of every merge publication. If any of them is out-of-date, i.e., has lost contact
  11011. ** with publisher for a certain length of time, we can declare the death of that replica
  11012. ** and cleanup their traces at the publisher side
  11013. */
  11014. declare @independent_agent  bit
  11015. declare @article            sysname
  11016. declare @publication        sysname
  11017. declare @pubid              int
  11018. declare @artid              int
  11019. declare @publisher          sysname
  11020. declare @subscriber         sysname
  11021. declare @subscriber_id      smallint
  11022. declare @subscriber_db      sysname
  11023. declare @publisher_db       sysname
  11024. declare @out_of_date        int
  11025. declare @distributor        sysname
  11026. declare @distribdb          sysname
  11027. declare @retention          int  -- in days         
  11028. declare @retcode            smallint
  11029. declare @distproc           nvarchar(255)
  11030. declare @localproc          nvarchar(255)
  11031. declare @msg                nvarchar(255)
  11032. declare @open_cursor        nvarchar(400)
  11033.  
  11034.     /*
  11035.     ** Security Check
  11036.     */
  11037. EXEC @retcode = dbo.sp_MSreplcheck_publish
  11038.     IF @@ERROR <> 0 or @retcode <> 0
  11039.         return (1)
  11040.  
  11041.     /*
  11042.     ** Get distribution server information for remote RPC call.
  11043.     */
  11044. EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  11045.      @distribdb   = @distribdb OUTPUT
  11046. IF @@ERROR <> 0 or @retcode <> 0
  11047.     BEGIN
  11048.         RAISERROR (20036, 16, -1)
  11049.         return (1)
  11050.     END
  11051.  
  11052.     
  11053. SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '.dbo.sp_MShelp_subscription_status '
  11054. select @publisher = @@SERVERNAME
  11055. select @publisher_db = db_name()
  11056.  
  11057. declare PC CURSOR LOCAL FAST_FORWARD for select DISTINCT name, pubid, independent_agent, retention from syspublications p
  11058.     open PC
  11059.     fetch PC into @publication, @pubid, @independent_agent, @retention
  11060.     WHILE (@@fetch_status <> -1)
  11061.         BEGIN
  11062.             -- Don't do anything if the retention is zero, this means 
  11063.             -- subscriptions to the publication will never expire
  11064.             IF @retention = 0
  11065.             BEGIN 
  11066.                 GOTO ZERO_RETENTION
  11067.             END
  11068.             declare SC CURSOR LOCAL FAST_FORWARD for select s.srvid, s.dest_db, a.name from syssubscriptions s, sysarticles a 
  11069.                 where a.pubid= @pubid and s.artid = a.artid and s.srvid<>-1 
  11070.                 for read only
  11071.             open SC
  11072.             fetch SC into @subscriber_id, @subscriber_db, @article
  11073.             WHILE (@@fetch_status <> -1)
  11074.                 BEGIN
  11075.                     select @subscriber=srvname from master..sysservers where srvid=@subscriber_id
  11076.                     exec @retcode = @distproc @publisher = @publisher, 
  11077.                                     @publisher_db = @publisher_db, 
  11078.                                     @publication = @publication, 
  11079.                                     @subscriber = @subscriber, 
  11080.                                     @subscriber_db = @subscriber_db,
  11081.                                     @retention = @retention,
  11082.                                     @out_of_date = @out_of_date OUTPUT,
  11083.                                     @independent_agent = @independent_agent
  11084.                     if @retcode<>0 or @@ERROR<>0 
  11085.                         begin
  11086.                             close SC
  11087.                             deallocate SC
  11088.                             close PC
  11089.                             deallocate PC
  11090.                             return (1)
  11091.                         end
  11092.                     IF (@out_of_date = 1)
  11093.                         begin
  11094.                             exec @retcode = dbo.sp_dropsubscription   -- publisher_db.dbo.sp_dropsubscription
  11095.                                 @publication = @publication,
  11096.                                 @article = @article,
  11097.                                 @subscriber = @subscriber,
  11098.                                 @destination_db = @subscriber_db
  11099.                             if @retcode <>0 or @@ERROR<>0
  11100.                                 begin
  11101.                                     close SC
  11102.                                     deallocate SC
  11103.                                     close PC
  11104.                                     deallocate PC
  11105.                                     return (1)
  11106.                                 end
  11107.                             raiserror(14157, 10, -1, @subscriber, @publication) 
  11108.                         end
  11109.                     fetch SC into @subscriber_id, @subscriber_db, @article
  11110.                 END
  11111.             CLOSE SC
  11112.             DEALLOCATE SC
  11113. ZERO_RETENTION:    
  11114.             fetch PC into @publication, @pubid, @independent_agent, @retention
  11115.         END
  11116.     CLOSE PC
  11117.     DEALLOCATE PC
  11118.  
  11119. GO
  11120.  
  11121. --------------------------------------------------------------------------------
  11122. --. sp_MSscript_update_statement
  11123. --------------------------------------------------------------------------------
  11124. if exists (select * from sysobjects    where type = 'P'
  11125.     and name = 'sp_MSscript_update_statement')
  11126.     drop procedure sp_MSscript_update_statement
  11127. go
  11128.  
  11129. raiserror('Creating procedure sp_MSscript_update_statement', 0,1)
  11130. go
  11131.  
  11132. create procedure sp_MSscript_update_statement
  11133.     @publication sysname,
  11134.     @article     sysname, 
  11135.     @objid int,
  11136.     @columns binary(32)
  11137. as
  11138.  
  11139.     declare @cmd          nvarchar(4000)
  11140.     declare @cmd2         nvarchar(4000)
  11141.     declare @qualname     nvarchar(512)
  11142.     declare @colname      sysname
  11143.     declare @typestring   nvarchar(4000)
  11144.     declare @spacer       nvarchar(1)
  11145.     declare @ccoltype     sysname
  11146.     declare @src_cols     int
  11147.     declare @this_col     int
  11148.     declare @rc           int
  11149.     declare @column          nvarchar(4000)
  11150.     declare @num_col      int
  11151.  
  11152.     declare @art_col      int -- position in the article partition.
  11153.     declare @isset          int
  11154.  
  11155.     select @src_cols = count(*) from syscolumns where id = @objid
  11156.  
  11157.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  11158.     select @cmd2 = N'update ' + @qualname + N' set'
  11159.  
  11160.     -- col names
  11161.     select @spacer = N' '
  11162.     select @this_col = 1
  11163.     select @cmd = N''
  11164.  
  11165.     -- If the table have only identity in pk and a ts col, update statement will be empty 
  11166.     -- and the query will fail. Prevent it here.
  11167.     select @num_col = 0
  11168.     select @art_col = 0
  11169.     -- script update
  11170.     while @this_col <= @src_cols 
  11171.     begin
  11172.         -- Get the ordinal of the article partition or not.
  11173.         exec @isset = dbo.sp_isarticlecolbitset @this_col, @columns
  11174.         if @isset != 0
  11175.             select @art_col = @art_col + 1
  11176.  
  11177.         exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, @columns, 0, @colname output, @ccoltype output
  11178.         if @rc = 0 and EXISTS (select name from syscolumns where id=@objid and colid=@this_col and iscomputed<>1)
  11179.         begin
  11180.             if rtrim(@ccoltype) not like N'timestamp' and ColumnProperty(@objid, @colname, 'IsIdentity') != 1
  11181.             begin
  11182.                 if @cmd2 is not null
  11183.                 begin
  11184.                     exec dbo.sp_MSflush_command @cmd2 output, 1
  11185.                     select @cmd2 = null
  11186.                 end
  11187.  
  11188.                 select @num_col = @num_col + 1
  11189.                 -- Optimization:
  11190.                 -- Get null or actual column name
  11191.                 -- Note: the output is quoted.
  11192.                 exec dbo.sp_MSget_synctran_column 
  11193.                         @ts_col = null,
  11194.                         @op_type = null , -- 'ins, 'upd', 'del'
  11195.                         @is_new = null,
  11196.                         @primary_key_bitmap = null,
  11197.                         @colname = @colname,
  11198.                         @this_col = @this_col,
  11199.                         @column = @column output,
  11200.                         @from_proc = 1,
  11201.                         @art_col = @art_col -- position in the partition.
  11202.  
  11203.  
  11204.                 select @cmd = @cmd + @spacer + QUOTENAME(@colname) + N' = ' + @column 
  11205.                 select @spacer = N','
  11206.                 -- flush command if necessary
  11207.                 exec dbo.sp_MSflush_command @cmd output, 0
  11208.  
  11209.             end
  11210.         end
  11211.         
  11212.         select @this_col = @this_col + 1
  11213.     end
  11214.  
  11215.     -- save off cmd fragment
  11216.     if @num_col > 0
  11217.     begin
  11218.         exec dbo.sp_MSflush_command @cmd output, 1
  11219.           
  11220.         -- Determine method of conflict detection and add where clause
  11221.         if ObjectProperty(@objid, 'TableHasTimestamp') = 1
  11222.         begin
  11223.             exec @rc = dbo.sp_MSis_col_replicated @publication, @article, 'timestamp', @colname OUTPUT 
  11224.             if @rc = 1
  11225.             begin
  11226.                 insert into #proctext(procedure_text) values( N'
  11227.     ') 
  11228.                 exec dbo.sp_MSscript_where_clause @objid, @columns, 'upd ts', @colname, 4
  11229.             end
  11230.         end
  11231.         else
  11232.         begin
  11233.             insert into #proctext(procedure_text) values( N'
  11234.     ')
  11235.             exec dbo.sp_MSscript_where_clause @objid, @columns, 'upd rc', null, 4
  11236.         end
  11237.     end 
  11238.     else
  11239.         -- set the @@rowcount
  11240.         insert into #proctext(procedure_text) values( N' select @retcode = @retcode
  11241.     ')
  11242. go
  11243.  
  11244. grant execute on dbo.sp_MSscript_update_statement to public
  11245. go
  11246.  
  11247. --------------------------------------------------------------------------------
  11248. --. sp_MSscript_sync_ins_proc
  11249. --------------------------------------------------------------------------------
  11250. if exists (select * from sysobjects    where type = 'P'
  11251.     and name = 'sp_MSscript_sync_ins_proc')
  11252.     drop procedure sp_MSscript_sync_ins_proc
  11253. go
  11254.  
  11255. raiserror('Creating procedure sp_MSscript_sync_ins_proc', 0,1)
  11256. go
  11257.  
  11258. create procedure sp_MSscript_sync_ins_proc 
  11259.     @publication sysname, 
  11260.     @article     sysname,
  11261.     @procname    sysname
  11262. as
  11263.     declare @source_objid int
  11264.     declare @colname sysname
  11265.     declare @indid int
  11266.     declare @cmd          nvarchar(4000)
  11267.     declare @ins_cmd      nvarchar(4000)
  11268.     declare @columns      binary(32)
  11269.     declare @outvars      nvarchar(4000)
  11270.     declare @rc           int
  11271.  
  11272.     set nocount on
  11273.     -- Create temp table
  11274.     create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) NULL)
  11275.  
  11276.     -- preamble common to all synctran procs
  11277.     exec @rc = dbo.sp_MSscript_beginproc @publication, @article, @procname, @source_objid output, @columns output
  11278.     if @rc = 0
  11279.         return
  11280.     
  11281.     -- construct parameter list
  11282.     exec dbo.sp_MSscript_params @source_objid, @columns, null, 1,  @outvars output
  11283.  
  11284.     -- construct body of procedure
  11285.     insert into #proctext(procedure_text) values( N'
  11286.  as
  11287. ')
  11288.  
  11289.     -- set cycle detection
  11290.     insert into #proctext(procedure_text) values(N'declare @retcode int
  11291.  
  11292. ')
  11293.  
  11294.     insert into #proctext(procedure_text) values( N'exec @retcode = dbo.sp_replsetoriginator @orig_server, @orig_db
  11295. ')
  11296.     insert into #proctext(procedure_text) values( N'if @retcode <> 0 or @@error <> 0 return -1
  11297.  
  11298. ')
  11299.  
  11300.     -- script out security check
  11301.     exec dbo.sp_MSscript_security @publication
  11302.  
  11303.      -- script out subscription validation
  11304.     exec dbo.sp_MSscript_validate_subscription @publication, @article
  11305.  
  11306.     -- Work around for case where article has 1 col that is not user-modfied (identity, timestamp)
  11307.     exec @rc = dbo.sp_MStable_not_modifiable @source_objid, @columns
  11308.     if @rc = 1
  11309.         insert into #proctext(procedure_text) values( N'exec sp_MSreplraiserror 20516
  11310.  
  11311. ')
  11312.      
  11313.     else
  11314.     begin
  11315.         exec @indid = dbo.sp_MStable_has_unique_index @source_objid 
  11316.         if @outvars <> null and @indid = 0
  11317.            -- no insert/update allowed if timestamp/identity col and no unique index
  11318.             insert into #proctext(procedure_text) values( N'exec sp_MSreplraiserror 20516
  11319.  
  11320. ')
  11321.     
  11322.         else
  11323.         begin
  11324.                 
  11325.             -- script insert statemnt
  11326.             exec dbo.sp_MSscript_insert_statement @source_objid, @columns
  11327.  
  11328.             -- script closing 
  11329.             exec dbo.sp_MSscript_endproc @source_objid, 'ins', @columns, @outvars
  11330.         end
  11331.     end
  11332.  
  11333.     -- send fragments to client
  11334.     select procedure_text from #proctext order by c1 asc
  11335.  
  11336. go
  11337.  
  11338. grant execute on dbo.sp_MSscript_sync_ins_proc  to public
  11339. go
  11340.  
  11341. --------------------------------------------------------------------------------
  11342. --. sp_MSscript_sync_upd_proc
  11343. --------------------------------------------------------------------------------
  11344. if exists (select * from sysobjects    where type = 'P'
  11345.     and name = 'sp_MSscript_sync_upd_proc')
  11346.     drop procedure sp_MSscript_sync_upd_proc
  11347. go
  11348.  
  11349. raiserror('Creating procedure sp_MSscript_sync_upd_proc', 0,1)
  11350. go
  11351.  
  11352. create procedure sp_MSscript_sync_upd_proc 
  11353.     @publication sysname, 
  11354.     @article     sysname,
  11355.     @procname    sysname
  11356. as
  11357.     declare @source_objid int
  11358.     declare @colname      sysname
  11359.     declare @indid        int
  11360.     declare @cmd          nvarchar(4000)
  11361.     declare @ins_cmd      nvarchar(4000)
  11362.     declare @columns      binary(32)
  11363.     declare @outvars      nvarchar(4000)
  11364.     declare @rc           int
  11365.  
  11366.     set nocount on
  11367.  
  11368.     -- Create temp table
  11369.     create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) NULL)
  11370.  
  11371.     -- preamble common to all synctran procs
  11372.     exec @rc = dbo.sp_MSscript_beginproc @publication, @article, @procname, @source_objid output, @columns output
  11373.     if @rc = 0
  11374.         return
  11375.  
  11376.     -- construct parameter list
  11377.     exec dbo.sp_MSscript_params @source_objid, @columns, null, 1, @outvars output
  11378.     insert into #proctext(procedure_text) values( N', 
  11379. ')
  11380.     exec dbo.sp_MSscript_params @source_objid, @columns, N'_old', 0, null
  11381.  
  11382.     -- Script bitmap parameter
  11383.     insert into #proctext(procedure_text) values( N', @bitmap varbinary(4000)')
  11384.  
  11385.     -- construct body of procedure
  11386.     insert into #proctext(procedure_text) values( N'
  11387.  as
  11388. ')
  11389.  
  11390.     -- set cycle detection
  11391.     insert into #proctext(procedure_text) values(N'declare @retcode int
  11392.  
  11393. ')
  11394.     insert into #proctext(procedure_text) values( N'exec @retcode = dbo.sp_replsetoriginator @orig_server, @orig_db
  11395. ')
  11396.     insert into #proctext(procedure_text) values( N'if @retcode <> 0 or @@error <> 0 return -1
  11397.     
  11398. ')
  11399.  
  11400.     -- script out security check
  11401.     exec dbo.sp_MSscript_security @publication
  11402.  
  11403.      -- script out subscription validation
  11404.     exec dbo.sp_MSscript_validate_subscription @publication, @article
  11405.  
  11406.     -- Work around for case where article has 1 col that is not user-modfied (identity, timestamp)
  11407.     exec @rc = dbo.sp_MStable_not_modifiable @source_objid, @columns
  11408.     if @rc = 1
  11409.         insert into #proctext(procedure_text) values( N'exec sp_MSreplraiserror 20516
  11410.  
  11411. ')
  11412.      
  11413.     else
  11414.     begin
  11415.         exec @indid = dbo.sp_MStable_has_unique_index @source_objid
  11416.         if @outvars <> null and @indid = 0
  11417.             -- no insert/update allowed if timestamp/identity col and no unique index
  11418.             insert into #proctext(procedure_text) values( N'exec sp_MSreplraiserror 20516
  11419.  
  11420. ')
  11421.         else
  11422.         begin
  11423.             -- script update statemnt
  11424.             exec dbo.sp_MSscript_update_statement @publication, @article, @source_objid, @columns
  11425.  
  11426.             -- script closing 
  11427.             exec dbo.sp_MSscript_endproc @source_objid, 'upd', @columns, @outvars
  11428.         end
  11429.     end
  11430.  
  11431.     -- send fragments to client
  11432.     select procedure_text from #proctext order by c1 asc
  11433.  
  11434. go
  11435.  
  11436. grant execute on dbo.sp_MSscript_sync_upd_proc  to public
  11437. go
  11438.  
  11439. --------------------------------------------------------------------------------
  11440. --. sp_MSscript_sync_del_proc
  11441. --------------------------------------------------------------------------------
  11442. if exists (select * from sysobjects    where type = 'P'
  11443.     and name = 'sp_MSscript_sync_del_proc')
  11444.     drop procedure sp_MSscript_sync_del_proc
  11445. go
  11446.  
  11447. raiserror('Creating procedure sp_MSscript_sync_del_proc', 0,1)
  11448. go
  11449.  
  11450. create procedure sp_MSscript_sync_del_proc 
  11451.     @publication sysname, 
  11452.     @article     sysname,
  11453.     @procname    sysname
  11454. as
  11455.     declare @source_objid int
  11456.     declare @colname sysname
  11457.     declare @indid int
  11458.     declare @cmd          nvarchar(4000)
  11459.     declare @ins_cmd      nvarchar(4000)
  11460.     declare @columns      binary(32)
  11461.     declare @outvars      nvarchar(4000)
  11462.     declare @rc           int
  11463.  
  11464.     set nocount on
  11465.  
  11466.     -- Create temp table
  11467.     create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) NULL)
  11468.     
  11469.     -- preamble common to all synctran procs
  11470.     exec @rc = dbo.sp_MSscript_beginproc @publication, @article, @procname, @source_objid output, @columns output
  11471.     if @rc = 0
  11472.         return
  11473.          
  11474.     -- construct parameter list
  11475.     exec dbo.sp_MSscript_params @source_objid, @columns, N'_old', 0, null
  11476.     
  11477.     -- construct body of procedure
  11478.     insert into #proctext(procedure_text) values( N'
  11479.  as
  11480. ')
  11481.  
  11482.     -- set cycle detection
  11483.     insert into #proctext(procedure_text) values(N'declare @retcode int
  11484.  
  11485. ')
  11486.     insert into #proctext(procedure_text) values( N'exec @retcode = dbo.sp_replsetoriginator @orig_server, @orig_db
  11487. ')
  11488.     insert into #proctext(procedure_text) values( N'if @retcode <> 0 or @@error <> 0 return -1
  11489.  
  11490. ')
  11491.  
  11492.     -- script out security check
  11493.     exec dbo.sp_MSscript_security @publication
  11494.     
  11495.      -- script out subscription validation
  11496.     exec dbo.sp_MSscript_validate_subscription @publication, @article
  11497.  
  11498.     -- Work around for case where article has 1 col that is not user-modfied (identity, timestamp)
  11499.     exec @rc = dbo.sp_MStable_not_modifiable @source_objid, @columns
  11500.     if @rc = 1
  11501.         insert into #proctext(procedure_text) values( N'exec sp_MSreplraiserror 20516
  11502.  
  11503. ')
  11504.      
  11505.     else
  11506.         begin
  11507.             exec @indid = dbo.sp_MStable_has_unique_index @source_objid
  11508.             if @indid = 0
  11509.                 -- no delete allowed if  no unique index
  11510.                 insert into #proctext(procedure_text) values( N'exec sp_MSreplraiserror 20516
  11511.  
  11512. ')
  11513.             else
  11514.             begin    
  11515.                 -- script insert statemnt
  11516.                 exec dbo.sp_MSscript_delete_statement @publication, @article, @source_objid, @columns
  11517.  
  11518.                 -- script closing 
  11519.                 exec dbo.sp_MSscript_endproc @source_objid, 'del', @columns, null
  11520.             end
  11521.         end
  11522.  
  11523.         -- send fragments to client
  11524.         select procedure_text from #proctext order by c1 asc
  11525. go
  11526.  
  11527. grant execute on dbo.sp_MSscript_sync_del_proc  to public
  11528. go
  11529.  
  11530. --------------------------------------------------------------------------------
  11531. --. sp_scriptinsproc
  11532. --------------------------------------------------------------------------------
  11533. if exists (select * from sysobjects    where type = 'P'
  11534.     and name = 'sp_scriptinsproc')
  11535.     drop procedure sp_scriptinsproc
  11536. go
  11537.  
  11538. raiserror('Creating procedure sp_scriptinsproc', 0,1)
  11539. go
  11540.  
  11541. create procedure sp_scriptinsproc @artid int
  11542. as
  11543. declare @cmd          nvarchar(4000)
  11544. declare @dest_owner   nvarchar(255)
  11545. declare @dest_tabname sysname
  11546. declare @src_objid    int
  11547. declare @columns      binary(32)
  11548. declare @ins_cmd      nvarchar(255)
  11549. declare @dest_proc    sysname
  11550. declare @src_cols     int
  11551. declare @this_col     int
  11552. declare @art_col      int
  11553. declare @isset        int
  11554.  
  11555. declare @typestring   nvarchar(255)
  11556. declare @spacer       nvarchar(1)
  11557.  
  11558. if not exists( select * from sysarticles where artid = @artid AND (type & 1) = 1 )
  11559. begin
  11560.     raiserror (14155, 16, 1 )
  11561.     return 1
  11562. end
  11563.  
  11564. -------- create temp table for command fragments
  11565.  
  11566. create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) NULL)
  11567.  
  11568. -------- get sysarticles information
  11569.  
  11570. select @dest_owner = dest_owner, @dest_tabname = dest_table, 
  11571.        @src_objid = objid, @columns = columns, @ins_cmd = ins_cmd
  11572. from sysarticles
  11573. where artid = @artid
  11574.  
  11575. if @dest_owner is not null
  11576. begin
  11577.     select @dest_owner = QUOTENAME( @dest_owner ) + N'.'
  11578. end
  11579. else
  11580. begin
  11581.     select @dest_owner = N''
  11582. end
  11583.  
  11584.  
  11585. -------- get dest proc name
  11586.  
  11587. if( 1 != charindex( N'CALL', upper(@ins_cmd) ) ) or @ins_cmd is null
  11588. begin
  11589.     raiserror (14156, 16, 1 )
  11590.     return 1
  11591. end
  11592.  
  11593. select @dest_proc = substring( @ins_cmd, 6, len( @ins_cmd ) - 4 )
  11594. select @cmd = N'create procedure ' + QUOTENAME(@dest_proc)
  11595.  
  11596. -------- construct parameter list
  11597.  
  11598. select @this_col = 1
  11599. select @art_col = 1
  11600. select @src_cols = max(colid) from syscolumns where id = @src_objid
  11601. select @spacer = N' '
  11602.  
  11603. while @this_col <= @src_cols 
  11604. begin
  11605.    exec @isset = dbo.sp_isarticlecolbitset @this_col, @columns
  11606.    if @isset != 0 and EXISTS (select name from syscolumns where id=@src_objid and @this_col=colid and iscomputed<>1)
  11607.    begin
  11608.         if len( @cmd ) > 3000
  11609.         begin
  11610.         insert into #proctext(procedure_text) values( @cmd )
  11611.             select @cmd = N''
  11612.         end
  11613.  
  11614.         exec dbo.sp_gettypestring @src_objid, @this_col, @typestring OUTPUT
  11615.         select @cmd = @cmd + @spacer + N'@c' + convert( nvarchar, @art_col ) + N' ' + @typestring 
  11616.         select @art_col = @art_col + 1
  11617.         select @spacer = N','
  11618.    end
  11619.    select @this_col = @this_col + 1
  11620. end
  11621.  
  11622.  
  11623. -- save off cmd fragment
  11624.  
  11625. insert into #proctext(procedure_text) values( @cmd )
  11626.  
  11627. insert into #proctext(procedure_text) values( N'as' )
  11628.  
  11629. ------- construct proc body
  11630.  
  11631. select @cmd = N'insert into ' + @dest_owner + QUOTENAME(@dest_tabname) + N' values ('
  11632. select @this_col = 1
  11633. select @art_col = 1
  11634. select @spacer = N' '
  11635.  
  11636. while @this_col <= @src_cols 
  11637. begin
  11638.     exec @isset = dbo.sp_isarticlecolbitset @this_col, @columns
  11639.     if @isset != 0 and EXISTS (select name from syscolumns where colid=@this_col and iscomputed<>1 and id = @src_objid)
  11640.     begin
  11641.         if len( @cmd ) > 3000
  11642.         begin
  11643.         insert into #proctext(procedure_text) values( @cmd )
  11644.             select @cmd = N''
  11645.         end
  11646.  
  11647.         select @cmd = @cmd + @spacer + N'@c' + convert( nvarchar, @art_col ) 
  11648.         select @art_col = @art_col + 1
  11649.         select @spacer = N','
  11650.     end
  11651.     select @this_col = @this_col + 1
  11652. end
  11653.  
  11654. -- finish up proc body
  11655.  
  11656. select @cmd = @cmd + N' )'
  11657.  
  11658. -- save off cmd fragement
  11659.  
  11660. insert into #proctext(procedure_text) values( @cmd )
  11661.  
  11662. -- send fragements to client
  11663.  
  11664. select procedure_text from #proctext order by c1 asc
  11665.  
  11666. go
  11667.  
  11668. grant exec on dbo.sp_scriptinsproc to public
  11669. go
  11670.  
  11671. --------------------------------------------------------------------------------
  11672. --. sp_scriptdelproc
  11673. --------------------------------------------------------------------------------
  11674. if exists (select * from sysobjects    where type = 'P'
  11675.     and name = 'sp_scriptdelproc')
  11676.     drop procedure sp_scriptdelproc
  11677. go
  11678.  
  11679. raiserror('Creating procedure sp_scriptdelproc', 0,1)
  11680. go
  11681.  
  11682. create procedure sp_scriptdelproc @artid int
  11683. as
  11684. declare @cmd          nvarchar(4000)
  11685. declare @dest_owner   nvarchar(255)
  11686. declare @dest_tabname sysname
  11687. declare @src_objid    int
  11688. declare @pkcolumns    binary(32)
  11689. declare @del_cmd      nvarchar(255)
  11690. declare @dest_proc    sysname
  11691. declare @src_cols     int
  11692. declare @this_col     int
  11693. declare @art_col      int
  11694. declare @isset        int
  11695.  
  11696. declare @typestring   nvarchar(255)
  11697. declare @spacer       nvarchar(10)
  11698.  
  11699. if not exists( select * from sysarticles where artid = @artid AND (type & 1) = 1 )
  11700. begin
  11701.     raiserror (14155, 16, 1 )
  11702.     return 1
  11703. end
  11704.  
  11705. -------- create temp table for command fragments
  11706.  
  11707. create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) NULL)
  11708.  
  11709. -- get sysarticles information
  11710.  
  11711. select @dest_owner = dest_owner, @dest_tabname = dest_table, 
  11712.        @src_objid = objid, @del_cmd = del_cmd
  11713. from sysarticles
  11714. where artid = @artid
  11715.  
  11716. if @dest_owner is not null
  11717. begin
  11718.     select @dest_owner = QUOTENAME( @dest_owner ) + N'.'
  11719. end
  11720. else
  11721. begin
  11722.     select @dest_owner = N''
  11723. end
  11724.  
  11725. -------- get dest proc name
  11726.  
  11727. if( 1 != charindex( N'CALL', upper(@del_cmd) ) ) or @del_cmd is null
  11728. begin
  11729.     raiserror (14156, 16, 1 )
  11730.     return 1
  11731. end
  11732.  
  11733. select @dest_proc = substring( @del_cmd, 6, len( @del_cmd ) - 4 )
  11734. select @cmd = N'create procedure ' + QUOTENAME(@dest_proc)
  11735.  
  11736. -------- construct parameter list
  11737.  
  11738. select @this_col = 1
  11739. select @art_col = 1
  11740. select @src_cols = max(colid) from syscolumns where id = @src_objid
  11741. select @spacer = N' '
  11742.  
  11743. exec dbo.sp_getarticlepkcolbitmap @src_objid, @pkcolumns output
  11744.  
  11745. while @this_col <= @src_cols 
  11746. begin
  11747.    exec @isset = dbo.sp_isarticlecolbitset @this_col, @pkcolumns
  11748.    if @isset != 0 and EXISTS (select name from syscolumns where id=@src_objid and @this_col=colid and iscomputed<>1)
  11749.    begin
  11750.         if len( @cmd ) > 3000
  11751.         begin
  11752.         insert into #proctext(procedure_text) values( @cmd )
  11753.             select @cmd = N''
  11754.         end
  11755.  
  11756.         exec dbo.sp_gettypestring @src_objid, @this_col, @typestring OUTPUT
  11757.         select @cmd = @cmd + @spacer + N'@pkc' + convert( nvarchar, @art_col ) + N' ' + @typestring 
  11758.         select @art_col = @art_col + 1
  11759.         select @spacer = N','
  11760.    end
  11761.    select @this_col = @this_col + 1
  11762. end
  11763.  
  11764.  
  11765. -- save off 
  11766.  
  11767. insert into #proctext(procedure_text) values( @cmd )
  11768. insert into #proctext(procedure_text) values( N'as' )
  11769.  
  11770. ------- construct proc body
  11771.  
  11772. insert into #proctext(procedure_text) values( N'delete ' + @dest_owner + QUOTENAME(@dest_tabname) ) 
  11773.  
  11774. exec dbo.sp_scriptpkwhereclause @src_objid, @src_cols, @pkcolumns
  11775.  
  11776. -- flush to client
  11777.  
  11778. select procedure_text from #proctext order by c1 asc
  11779.  
  11780.  
  11781. go
  11782.  
  11783. grant exec on dbo.sp_scriptdelproc to public
  11784. go
  11785.  
  11786. --------------------------------------------------------------------------------
  11787. --. sp_scriptupdproc
  11788. --------------------------------------------------------------------------------
  11789. if exists (select * from sysobjects    where type = 'P'
  11790.     and name = 'sp_scriptupdproc')
  11791.     drop procedure sp_scriptupdproc
  11792. go
  11793.  
  11794. raiserror('Creating procedure sp_scriptupdproc', 0,1)
  11795. go
  11796.  
  11797. create procedure sp_scriptupdproc @artid int
  11798. as
  11799. declare @cmd          nvarchar(4000)
  11800. declare @dest_owner   nvarchar(255)
  11801. declare @dest_tabname sysname
  11802. declare @src_objid    int
  11803. declare @artcolumns   binary(32)
  11804. declare @pkcolumns    binary(32)
  11805. declare @upd_cmd      nvarchar(255)
  11806. declare @dest_proc    sysname
  11807. declare @src_cols     int
  11808. declare @this_col     int
  11809. declare @art_col      int
  11810. declare @pkart_col    int
  11811. declare @isset        int
  11812.  
  11813. declare @typestring   nvarchar(255)
  11814. declare @spacer       nvarchar(10)
  11815.  
  11816. if not exists( select * from sysarticles where artid = @artid AND (type & 1) = 1 )
  11817. begin
  11818.     raiserror (14155, 16, 1 )
  11819.     return 1
  11820. end
  11821.  
  11822. -------- create temp table for command fragments
  11823.  
  11824. create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) NULL)
  11825.  
  11826. -------- get sysarticles information
  11827.  
  11828. select @dest_owner = dest_owner, @dest_tabname = dest_table, 
  11829.        @src_objid = objid, @artcolumns = columns, @upd_cmd = upd_cmd
  11830. from sysarticles
  11831. where artid = @artid
  11832.  
  11833. if @dest_owner is not null
  11834. begin
  11835.     select @dest_owner = QUOTENAME( @dest_owner ) + N'.'
  11836. end
  11837. else
  11838. begin
  11839.     select @dest_owner = N''
  11840. end
  11841.  
  11842. -------- get dest proc name
  11843.  
  11844. if( 1 != charindex( N'CALL', upper(@upd_cmd) ) ) or @upd_cmd is null
  11845. begin
  11846.     raiserror (14156, 16, 1 )
  11847.     return 1
  11848. end
  11849.  
  11850. select @dest_proc = substring( @upd_cmd, 6, len( @upd_cmd ) - 4 )
  11851.  
  11852. insert into #proctext( procedure_text ) values (  N'create procedure ' + QUOTENAME(@dest_proc) + N' ')
  11853.  
  11854. -------- construct parameter list
  11855.  
  11856. select @src_cols = max(colid) from syscolumns where id = @src_objid
  11857.  
  11858. exec dbo.sp_getarticlepkcolbitmap @src_objid, @pkcolumns output
  11859.  
  11860. exec dbo.sp_scriptupdateparams @src_objid, @src_cols, @artcolumns, @pkcolumns
  11861.  
  11862. insert into #proctext(procedure_text) values ( N'as' )
  11863.  
  11864. -------- now create the update statement
  11865.  
  11866. -- construct test to see if pk has changed 
  11867. -- only do this if the article has columns not included in the pk
  11868.  
  11869. if @artcolumns != @pkcolumns
  11870. begin
  11871.     select @cmd = N'if'
  11872.  
  11873.     select @this_col = 1
  11874.     select @art_col = 1
  11875.     select @pkart_col = 1
  11876.     select @spacer = ' '
  11877.  
  11878.     while @this_col <= @src_cols
  11879.     begin
  11880.         exec @isset = dbo.sp_isarticlecolbitset @this_col, @artcolumns
  11881.         if @isset != 0 and EXISTS (select name from syscolumns where id=@src_objid and @this_col=colid and iscomputed<>1)
  11882.         begin
  11883.             exec @isset = dbo.sp_isarticlecolbitset @this_col, @pkcolumns
  11884.             if @isset != 0
  11885.             begin
  11886.                 select @cmd = @cmd + @spacer + N'@c'+convert( nvarchar, @art_col ) + N' = @pkc' + convert( nvarchar, @pkart_col ) 
  11887.                 select @spacer = N' and '
  11888.                 select @pkart_col = @pkart_col + 1
  11889.                 if len( @cmd ) > 3000
  11890.                 begin
  11891.                 insert into #proctext(procedure_text) values( @cmd )
  11892.                     select @cmd = N''
  11893.                 end
  11894.             end
  11895.             select @art_col = @art_col + 1
  11896.         end
  11897.         select @this_col = @this_col + 1
  11898.     end
  11899.  
  11900.     insert into #proctext(procedure_text) values( @cmd )
  11901.  
  11902.     -- construct update if pk hasn't changed
  11903.  
  11904.     select @cmd = N'update ' + @dest_owner + QUOTENAME(@dest_tabname) + N' set'
  11905.  
  11906.     -- create SET clause
  11907.  
  11908.     select @this_col = 1
  11909.     select @art_col = 1
  11910.     select @spacer = N' '
  11911.  
  11912.     while @this_col <= @src_cols
  11913.     begin
  11914.         exec @isset = dbo.sp_isarticlecolbitset @this_col, @artcolumns
  11915.         if @isset != 0  and EXISTS (select name from syscolumns where id=@src_objid and @this_col=colid and iscomputed<>1)
  11916.         begin
  11917.             exec @isset = dbo.sp_isarticlecolbitset @this_col, @pkcolumns
  11918.             if @isset = 0
  11919.             begin
  11920.                 select @cmd = @cmd + @spacer + QUOTENAME(col_name( @src_objid, @this_col)) + N' = @c' + convert( nvarchar, @art_col ) 
  11921.                 select @spacer = N','
  11922.  
  11923.                 if len( @cmd ) > 3000
  11924.                 begin
  11925.                     insert into #proctext(procedure_text) values( @cmd )
  11926.                     select @cmd = N''
  11927.                 end
  11928.             end
  11929.             select @art_col = @art_col + 1
  11930.         end
  11931.         select @this_col = @this_col + 1
  11932.     end
  11933.  
  11934.     insert into #proctext(procedure_text) values( @cmd )
  11935.  
  11936.     exec dbo.sp_scriptpkwhereclause @src_objid, @src_cols, @pkcolumns
  11937.  
  11938.     insert into #proctext(procedure_text) values( N'else' )
  11939.  
  11940. end -- end if artcols != pkcols
  11941.  
  11942. -- construct update if pk has changed
  11943.  
  11944. select @cmd = N'update ' + @dest_owner + QUOTENAME(@dest_tabname) + N' set'
  11945.  
  11946. -- create SET clause
  11947.  
  11948. select @this_col = 1
  11949. select @art_col = 1
  11950. select @spacer = N' '
  11951.  
  11952. while @this_col <= @src_cols
  11953. begin
  11954.     exec @isset = dbo.sp_isarticlecolbitset @this_col, @artcolumns
  11955.     if @isset != 0 and EXISTS (select name from syscolumns where id=@src_objid and @this_col=colid and iscomputed<>1)
  11956.     begin
  11957.         select @cmd = @cmd + @spacer + QUOTENAME(col_name( @src_objid, @this_col)) + N' = @c' + convert( nvarchar, @art_col ) 
  11958.         select @art_col = @art_col + 1
  11959.         select @spacer = N','
  11960.  
  11961.         if len( @cmd ) > 3000
  11962.         begin
  11963.         insert into #proctext(procedure_text) values( @cmd )
  11964.             select @cmd = N''
  11965.         end
  11966.     end
  11967.     select @this_col = @this_col + 1
  11968. end
  11969.  
  11970. insert into #proctext(procedure_text) values( @cmd )
  11971.  
  11972. exec dbo.sp_scriptpkwhereclause @src_objid, @src_cols, @pkcolumns
  11973.  
  11974. -- flush to client
  11975.  
  11976. select procedure_text from #proctext order by c1 asc
  11977.  
  11978. go
  11979.  
  11980. grant exec on dbo.sp_scriptupdproc to public
  11981. go
  11982.  
  11983. --------------------------------------------------------------------------------
  11984. --. sp_scriptmappedupdproc
  11985. --------------------------------------------------------------------------------
  11986. if exists (select * from sysobjects    where type = 'P'
  11987.     and name = 'sp_scriptmappedupdproc')
  11988.     drop procedure sp_scriptmappedupdproc
  11989. go
  11990.  
  11991. raiserror('Creating procedure sp_scriptmappedupdproc', 0,1)
  11992. go
  11993.  
  11994. create procedure sp_scriptmappedupdproc @artid int
  11995. as
  11996. declare @cmd          nvarchar(4000)
  11997. declare @dest_owner   nvarchar(255)
  11998. declare @dest_tabname sysname
  11999. declare @src_objid    int
  12000. declare @artcolumns   binary(32)
  12001. declare @pkcolumns    binary(32)
  12002. declare @upd_cmd      nvarchar(255)
  12003. declare @dest_proc    sysname
  12004. declare @src_cols     int
  12005. declare @art_cols     int
  12006. declare @this_col     int
  12007. declare @art_col      int
  12008. declare @pkart_col    int
  12009. declare @isset        int
  12010. declare @bytestr      nvarchar(10)
  12011. declare @bitstr       nvarchar(10)
  12012. declare @typestring   nvarchar(255)
  12013. declare @spacer       nvarchar(10)
  12014. declare @exists_else  bit
  12015.  
  12016. select @exists_else     = 0
  12017.  
  12018. if not exists( select * from sysarticles where artid = @artid AND (type & 1) = 1 )
  12019. begin
  12020.     raiserror (14155, 16, 1 )
  12021.     return 1
  12022. end
  12023.  
  12024. -------- create temp table for command fragments
  12025.  
  12026. create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) )
  12027.  
  12028. -------- get sysarticles information
  12029.  
  12030. select @dest_owner = dest_owner, @dest_tabname = dest_table, 
  12031.        @src_objid = objid, @artcolumns = columns, @upd_cmd = upd_cmd
  12032. from sysarticles
  12033. where artid = @artid
  12034.  
  12035. if @dest_owner is not null
  12036. begin
  12037.     select @dest_owner = QUOTENAME( @dest_owner ) + N'.'
  12038. end
  12039. else
  12040. begin
  12041.     select @dest_owner = N''
  12042. end
  12043.  
  12044. -------- get dest proc name
  12045.  
  12046. if( 1 != charindex( N'MCALL', upper(@upd_cmd) ) ) or @upd_cmd is null
  12047. begin
  12048.     raiserror (14156, 16, 1 )
  12049.     return 1
  12050. end
  12051.  
  12052. select @dest_proc = substring( @upd_cmd, 7, len( @upd_cmd ) - 5 )
  12053. insert into #proctext( procedure_text ) values ( N'create procedure ' + QUOTENAME(@dest_proc) + N' ' )
  12054.   
  12055.  
  12056. -------- construct parameter list
  12057.  
  12058. select @src_cols = max(colid) from syscolumns where id = @src_objid
  12059.  
  12060. exec dbo.sp_getarticlepkcolbitmap @src_objid, @pkcolumns output
  12061.  
  12062. exec dbo.sp_scriptupdateparams @src_objid, @src_cols, @artcolumns, @pkcolumns
  12063.  
  12064. ----- add changed data bitmap
  12065.  
  12066. select @this_col = 1
  12067. select @art_col = 1
  12068.  
  12069. while @this_col <= @src_cols
  12070. begin
  12071.    exec @isset = dbo.sp_isarticlecolbitset @this_col, @artcolumns
  12072.    if @isset != 0 and EXISTS (select name from syscolumns where colid=@this_col and iscomputed<>1 and id = @src_objid)
  12073.    begin
  12074.         select @art_col = @art_col + 1
  12075.    end
  12076.    select @this_col = @this_col + 1
  12077. end
  12078.  
  12079. -- Note that bitmap size is based on number of article columns
  12080. -- (computed by loop above) not source table columns
  12081.  
  12082. select @cmd = N',@bitmap binary(' + convert(nvarchar,1+(@art_col-1) / 8) + N')'
  12083.  
  12084. insert into #proctext(procedure_text) values( @cmd )
  12085. insert into #proctext(procedure_text) values( N'as' )
  12086.  
  12087.  
  12088. -- construct IF statement
  12089. -- do this only if the article contains columns not included in the pk
  12090.  
  12091. if @artcolumns != @pkcolumns
  12092. begin
  12093.     select @this_col = 1
  12094.     select @art_col = 1
  12095.     select @spacer = N' '
  12096.  
  12097.     select @cmd = N'if'
  12098.  
  12099.     while @this_col <= @src_cols
  12100.     begin
  12101.         exec @isset = dbo.sp_isarticlecolbitset @this_col, @artcolumns
  12102.         if @isset != 0 and EXISTS (select name from syscolumns where id=@src_objid and @this_col=colid and iscomputed<>1)
  12103.         begin 
  12104.             exec @isset = dbo.sp_isarticlecolbitset @this_col, @pkcolumns
  12105.             if @isset != 0
  12106.             begin
  12107.                 select @bytestr = convert( nvarchar, 1 + (@art_col-1) / 8 )
  12108.                 select @bitstr =  convert( nvarchar, power(2, (@art_col-1) % 8 ) )
  12109.  
  12110.                 select @cmd = @cmd + @spacer + N'substring(@bitmap,' + @bytestr + N',1) & ' + @bitstr +  
  12111.                          N' = ' + @bitstr 
  12112.                 
  12113.                 select @spacer = N' or '
  12114.  
  12115.                 if len( @cmd ) > 3000
  12116.                 begin
  12117.                     insert into #proctext(procedure_text) values( @cmd )
  12118.                     select @cmd = N''
  12119.                 end
  12120.             end
  12121.             select @art_col = @art_col + 1
  12122.         end
  12123.         select @this_col = @this_col + 1
  12124.     end
  12125.  
  12126.     insert into #proctext(procedure_text) values( @cmd )
  12127.  
  12128. end  -- if artcolumns != pkcolumns
  12129.  
  12130. -- construct update statement including PK columns
  12131.  
  12132. insert into #proctext(procedure_text) values( N'update ' + @dest_owner + QUOTENAME(@dest_tabname) + N' set' )
  12133.  
  12134. -- create SET clause consisting of CASE statements
  12135.  
  12136. select @this_col = 1
  12137. select @art_col = 1
  12138. select @spacer = N''
  12139.  
  12140. while @this_col <= @src_cols
  12141. begin
  12142.     exec @isset = dbo.sp_isarticlecolbitset @this_col, @artcolumns
  12143.     if @isset != 0  and EXISTS (select name from syscolumns where colid=@this_col and iscomputed<>1 and id = @src_objid)
  12144.     begin
  12145.         select @bytestr = convert( nvarchar, 1 + (@art_col-1) / 8 )
  12146.         select @bitstr =  convert( nvarchar, power(2, (@art_col-1) % 8 ) )
  12147.  
  12148.         insert into #proctext(procedure_text) values (
  12149.              @spacer + QUOTENAME(col_name( @src_objid, @this_col)) + N' = case substring(@bitmap,' + @bytestr + N',1) & ' + @bitstr +  
  12150.              N' when ' + @bitstr + N' then ' + N'@c'+ convert( nvarchar, @art_col ) + 
  12151.              N' else ' + QUOTENAME(col_name( @src_objid, @this_col)) + N' end' )
  12152.  
  12153.         select @spacer = ',' 
  12154.  
  12155.         select @art_col = @art_col + 1
  12156.     end
  12157.     select @this_col = @this_col + 1
  12158. end
  12159.  
  12160. -- create where clause
  12161.  
  12162. exec dbo.sp_scriptpkwhereclause @src_objid, @src_cols, @pkcolumns
  12163.  
  12164.  
  12165. -- construct UPDATE that does not set PK cols
  12166. -- only do this if the article contains columns that are not included
  12167. -- in the pk
  12168.  
  12169. if @artcolumns != @pkcolumns
  12170. begin
  12171.  
  12172.     -- create SET clause consisting of CASE statements
  12173.  
  12174.     select @this_col = 1
  12175.     select @art_col = 1
  12176.     select @spacer = N''
  12177.  
  12178.     while @this_col <= @src_cols
  12179.     begin
  12180.         exec @isset = dbo.sp_isarticlecolbitset @this_col, @artcolumns
  12181.         if @isset != 0  and EXISTS (select name from syscolumns where colid=@this_col and iscomputed<>1 and id = @src_objid)
  12182.         begin
  12183.             exec @isset = dbo.sp_isarticlecolbitset @this_col, @pkcolumns 
  12184.             if @isset = 0 
  12185.             begin
  12186.                 if (@exists_else = 0)
  12187.                 begin
  12188.                     insert into #proctext(procedure_text) values( N'else' )
  12189.                     insert into #proctext(procedure_text) values( N'update ' + @dest_owner + QUOTENAME(@dest_tabname) + N' set' )
  12190.                     select @exists_else = 1
  12191.                 end
  12192.                 select @bytestr = convert( nvarchar, 1 + (@art_col-1) / 8 )
  12193.                 select @bitstr =  convert( nvarchar, power(2, (@art_col-1) % 8 ) )
  12194.  
  12195.                 insert into #proctext(procedure_text) values (
  12196.                      @spacer + QUOTENAME(col_name( @src_objid, @this_col)) + N' = case substring(@bitmap,' + @bytestr + N',1) & ' + @bitstr +  
  12197.                      N' when ' + @bitstr + N' then ' + N'@c'+ convert( nvarchar, @art_col ) + 
  12198.                      N' else ' + QUOTENAME(col_name( @src_objid, @this_col)) + N' end' )
  12199.  
  12200.                 select @spacer = ',' 
  12201.             end
  12202.             select @art_col = @art_col + 1
  12203.         end
  12204.         select @this_col = @this_col + 1
  12205.     end
  12206.  
  12207.     if @exists_else=1
  12208.         exec dbo.sp_scriptpkwhereclause @src_objid, @src_cols, @pkcolumns
  12209. end
  12210.  
  12211. select procedure_text from #proctext order by c1 asc
  12212.  
  12213. go
  12214.  
  12215. grant exec on dbo.sp_scriptmappedupdproc to public
  12216. go
  12217.  
  12218. --------------------------------------------------------------------------------
  12219. --.    Merge repl objects (rladmin.sql)
  12220. --------------------------------------------------------------------------------
  12221. dump tran master with no_log
  12222. go
  12223. --------------------------------------------------------------------------------
  12224. --. sp_MSdrop_rladmin
  12225. --------------------------------------------------------------------------------
  12226. if exists (select * from sysobjects
  12227.     where type = 'P ' and name = 'sp_MSdrop_rladmin')
  12228.         drop procedure sp_MSdrop_rladmin
  12229. go
  12230.  
  12231. raiserror('Creating procedure sp_MSdrop_rladmin', 0,1)
  12232. go
  12233.  
  12234. create procedure sp_MSdrop_rladmin
  12235. as
  12236.  
  12237.     if exists (select * from sysobjects
  12238.             where type in ('P ') 
  12239.                 and name = 'sp_MSaddmergepub_snapshot')
  12240.         drop procedure sp_MSaddmergepub_snapshot
  12241.  
  12242.  
  12243.     if exists (select * from sysobjects
  12244.             where type in ('P ') 
  12245.                 and name = 'sp_MScheckatpublisher')
  12246.         drop procedure sp_MScheckatpublisher    
  12247.     
  12248.     if exists (select * from sysobjects
  12249.             where type in ('P ') 
  12250.                 and name = 'sp_MSdropmergepub_snapshot')
  12251.         drop procedure sp_MSdropmergepub_snapshot
  12252.     
  12253.     if exists (select * from sysobjects
  12254.             where type = 'P'
  12255.                 and name = 'sp_addmergepublication')
  12256.         drop procedure sp_addmergepublication
  12257.  
  12258.     if exists (select * from sysobjects
  12259.         where type = 'P'
  12260.             and name = 'sp_changemergepublication')
  12261.         drop procedure sp_changemergepublication
  12262.     
  12263.  
  12264.     if exists (select * from sysobjects
  12265.             where type = 'P'
  12266.                 and name = 'sp_helpmergepublication')
  12267.         drop procedure sp_helpmergepublication
  12268.  
  12269.     if exists (select * from sysobjects
  12270.             where type = 'P'
  12271.                 and name = 'sp_MSpublicationview')
  12272.         drop procedure sp_MSpublicationview
  12273.  
  12274.      if exists (select * from sysobjects
  12275.                 where type = 'P' and
  12276.                 name = 'sp_reinitmergesubscription')
  12277.         drop procedure sp_reinitmergesubscription
  12278.         
  12279.     if exists (select * from sysobjects
  12280.             where type = 'P'
  12281.                 and name = 'sp_MSdrop_expired_mergesubscription')
  12282.         drop procedure sp_MSdrop_expired_mergesubscription
  12283.     
  12284.     if exists (select * from sysobjects
  12285.         where type = 'P'
  12286.             and name = 'sp_dropmergepublication')
  12287.         drop procedure sp_dropmergepublication
  12288.     
  12289.     if exists (select * from sysobjects
  12290.             where type = 'P'
  12291.                 and name = 'sp_addmergearticle')
  12292.         drop procedure sp_addmergearticle
  12293.     
  12294.  
  12295.     if exists (select * from sysobjects
  12296.         where type = 'P'
  12297.             and name = 'sp_changemergearticle')
  12298.         drop procedure sp_changemergearticle
  12299.     
  12300.  
  12301.     if exists (select * from sysobjects
  12302.         where type = 'P'
  12303.             and name = 'sp_helpmergearticle')
  12304.         drop procedure sp_helpmergearticle
  12305.     
  12306.  
  12307.     if exists (select * from sysobjects
  12308.         where type = 'P'
  12309.             and name = 'sp_dropmergearticle')
  12310.         drop procedure sp_dropmergearticle
  12311.     
  12312.     if exists (select * from sysobjects
  12313.         where type = 'P'
  12314.             and name = 'sp_addmergesubscription')
  12315.         drop procedure sp_addmergesubscription
  12316.     
  12317.     if exists (select * from sysobjects
  12318.         where type = 'P'
  12319.             and name = 'sp_changemergesubscription')
  12320.         drop procedure sp_changemergesubscription
  12321.  
  12322.     if exists (select * from sysobjects
  12323.         where type = 'P'
  12324.             and name = 'sp_helpmergesubscription')
  12325.         drop procedure sp_helpmergesubscription
  12326.  
  12327.     if exists (select * from sysobjects
  12328.         where type = 'P'
  12329.             and name = 'sp_dropmergesubscription')
  12330.         drop procedure sp_dropmergesubscription
  12331.  
  12332.     if exists (select * from sysobjects
  12333.         where type = 'P'
  12334.             and name = 'sp_helpmergefilter')
  12335.         drop procedure sp_helpmergefilter
  12336.  
  12337.     if exists (select * from sysobjects
  12338.         where type = 'P'
  12339.             and name = 'sp_changemergefilter')
  12340.         drop procedure sp_changemergefilter
  12341.     
  12342.     if exists (select * from sysobjects
  12343.         where type = 'P'
  12344.             and name = 'sp_addmergefilter')
  12345.         drop procedure sp_addmergefilter
  12346.     
  12347.     if exists (select * from sysobjects
  12348.         where type = 'P'
  12349.             and name = 'sp_dropmergefilter')
  12350.         drop procedure sp_dropmergefilter
  12351.  
  12352.     if exists (select * from sysobjects
  12353.             where type in ('P ') 
  12354.                 and name = 'sp_MSmergepublishdb')
  12355.         drop procedure sp_MSmergepublishdb
  12356.  
  12357.     if exists (select * from sysobjects
  12358.             where type in ('P ') 
  12359.                 and name = 'sp_helpallowmerge_publication')
  12360.         drop procedure sp_helpallowmerge_publication
  12361.  
  12362.     if exists (select * from sysobjects
  12363.             where type in ('P ') 
  12364.                 and name = 'sp_enumcustomresolvers')
  12365.         drop procedure sp_enumcustomresolvers
  12366.  
  12367.     if exists (select * from sysobjects
  12368.             where type in ('P ') 
  12369.                 and name = 'sp_MSenumpubreferences')
  12370.         drop procedure sp_MSenumpubreferences
  12371.  
  12372.     if exists (select * from sysobjects
  12373.         where type = 'P ' and name = 'sp_MSscript_dri')
  12374.     drop procedure sp_MSscript_dri
  12375.     
  12376.     if exists (select * from sysobjects
  12377.             where type in ('P ') 
  12378.                 and name = 'sp_MSsubsetpublication')
  12379.         drop procedure sp_MSsubsetpublication
  12380.     if exists (select * from sysobjects
  12381.             where type = 'P'
  12382.                 and name = 'sp_generatefilters')
  12383.         drop procedure sp_generatefilters
  12384.     if exists (select * from sysobjects
  12385.             where type = 'P'
  12386.                 and name = 'sp_MSmakejoinfilter')
  12387.         drop procedure sp_MSmakejoinfilter
  12388.     if exists (select * from sysobjects
  12389.             where type = 'P'
  12390.                 and name = 'sp_MSmakeexpandproc')
  12391.         drop procedure sp_MSmakeexpandproc
  12392.     if exists (select * from sysobjects
  12393.             where type = 'P'
  12394.                 and name = 'sp_MSindexcolfrombin')
  12395.         drop procedure sp_MSindexcolfrombin
  12396.  
  12397.     if exists (select * from sysobjects
  12398.                 where type = 'P' and
  12399.                 name = 'sp_helpmergearticleconflicts')
  12400.         drop procedure sp_helpmergearticleconflicts
  12401.  
  12402.     if exists (select * from sysobjects
  12403.                 where type = 'P' and
  12404.                 name = 'sp_MShelpmergeconflictcounts')
  12405.         drop procedure sp_MShelpmergeconflictcounts
  12406.  
  12407.     if exists (select * from sysobjects
  12408.                 where type = 'P' and
  12409.                 name = 'sp_helpmergeconflictrows')
  12410.         drop procedure sp_helpmergeconflictrows
  12411.  
  12412.     if exists (select * from sysobjects
  12413.                 where type = 'P' and
  12414.                 name = 'sp_helpmergedeleteconflictrows')
  12415.         drop procedure sp_helpmergedeleteconflictrows
  12416.  
  12417.     if exists (select * from sysobjects
  12418.                 where type = 'P' and
  12419.                 name = 'sp_deletemergeconflictrow')
  12420.         drop procedure sp_deletemergeconflictrow
  12421.  
  12422.     if exists (select * from sysobjects
  12423.                 where type = 'P' and
  12424.                 name = 'sp_getmergedeletetype')
  12425.         drop procedure sp_getmergedeletetype
  12426.  
  12427.     if exists (select * from sysobjects
  12428.                 where type = 'P' and
  12429.                 name = 'sp_mergedummyupdate')
  12430.         drop procedure sp_mergedummyupdate
  12431.  
  12432.     if exists (select * from sysobjects
  12433.                 where type = 'P' and
  12434.                 name = 'sp_addtabletocontents')
  12435.         drop procedure sp_addtabletocontents
  12436.  
  12437.     if exists (select * from sysobjects
  12438.                 where type = 'P' and
  12439.                 name = 'sp_MSaddpubtocontents')
  12440.         drop procedure sp_MSaddpubtocontents
  12441.  
  12442.     if exists (select * from sysobjects
  12443.         where type = 'P' and
  12444.         name = 'sp_MSget_subtypedatasrc')
  12445.         drop procedure sp_MSget_subtypedatasrc
  12446.  
  12447.     if exists (select * from sysobjects
  12448.         where type = 'P' and
  12449.         name = 'sp_mergecleanupmetadata')
  12450.         drop procedure sp_mergecleanupmetadata
  12451.         
  12452.     if exists (select * from sysobjects
  12453.         where type = 'P' and
  12454.         name = 'sp_MScleanup_metadata')
  12455.         drop procedure sp_MScleanup_metadata
  12456.  
  12457. go
  12458.  
  12459.  
  12460. --------------------------------------------------------------------------------
  12461. --. sp_addmergearticle
  12462. --------------------------------------------------------------------------------
  12463. if exists (select * from sysobjects    where type = 'P'
  12464.     and name = 'sp_addmergearticle')
  12465.     drop procedure sp_addmergearticle
  12466. go
  12467.  
  12468. raiserror('Creating procedure sp_addmergearticle', 0,1)
  12469. go
  12470.  
  12471. create procedure sp_addmergearticle
  12472.     @publication            sysname,                            /* publication name */
  12473.     @article                sysname,                            /* article name */
  12474.     @source_object          sysname,                            /* source object name */
  12475.     @type                   sysname = 'table',                  /* article type */
  12476.     @description            nvarchar(255)= NULL,                /* article description */
  12477.     @column_tracking        nvarchar(10) = 'false',             /* column level tracking */
  12478.     @status                 nvarchar(10) = 'unsynced',          /* unsynced, active */
  12479.     @pre_creation_cmd       nvarchar(10) = 'drop',              /* 'none', 'drop', 'delete', 'truncate' */
  12480.     @creation_script        nvarchar(255)= NULL,                /* article schema script */
  12481.     @schema_option          binary(8)   = 0x00000000000000f1,   /* article schema creation options */
  12482.     @subset_filterclause    nvarchar(2000) = '',                /* filter clause */
  12483.     @article_resolver       nvarchar(255)= NULL,                 /* custom resolver for article */
  12484.     @resolver_info          nvarchar(255) = NULL,                     /* custom resolver info */
  12485.     @source_owner           sysname = NULL
  12486.     AS
  12487.  
  12488.     set nocount on
  12489.  
  12490.     /*
  12491.     ** Declarations.
  12492.     */
  12493.     declare @resolver_info_len        int
  12494.     declare @sp_resolver            sysname
  12495.     declare @num_columns            smallint
  12496.     declare @pubid                  uniqueidentifier                /* Publication id */
  12497.     declare @db                     sysname
  12498.     declare @object                 sysname
  12499.     declare @owner                  sysname
  12500.     declare @destination_object     sysname
  12501.     declare @retcode                int
  12502.     declare @objid                  int
  12503.     declare @sync_objid             int
  12504.     declare @typeid                 smallint
  12505.     declare @nickname               int
  12506.     declare @merge_pub_object_bit int
  12507.     declare @column_tracking_id     int
  12508.     declare @cmd                    nvarchar(255)
  12509.     declare @statusid               tinyint
  12510.     declare @precmdid               int
  12511.     declare @resolver_clsid         nvarchar(50)
  12512.     declare @resolver_clsid_old     nvarchar(50)
  12513.     declare @tablenick              int
  12514.     declare @artid                  uniqueidentifier
  12515.     declare @distributor            sysname
  12516.     declare @distribdb              sysname
  12517.     declare @distproc               nvarchar(255)
  12518.     declare @dbname                 sysname
  12519.     declare @replinfo               int
  12520.     declare @db_name                sysname
  12521.     declare @subset                 int
  12522.     declare @row_size               int
  12523.     declare @sp_name                sysname
  12524.     declare @sp_owner                sysname
  12525.     declare @qualified_name         nvarchar(257)
  12526.  
  12527.     -- PARSENAME VARS
  12528.     declare     @UnqualName      nvarchar(258)  --rightmost name node
  12529.                ,@QualName1       nvarchar(258)  
  12530.                ,@QualName2       nvarchar(258)
  12531.     -- END PARSENAME VARS
  12532.  
  12533.     /*
  12534.     ** Initializations 
  12535.     */
  12536.     select @statusid        = 0
  12537.     select @resolver_clsid  = NULL
  12538.     select @subset          = 1     /* Const: publication type 'subset' */
  12539.     select @merge_pub_object_bit    = 128
  12540.  
  12541.     select @sp_resolver = 'Microsoft SQLServer Stored Procedure Resolver'
  12542.     
  12543.     if @source_owner is NULL
  12544.         begin
  12545.             select @source_owner = user_name(uid) from sysobjects where id = object_id(@source_object)
  12546.             if @source_owner is NULL  
  12547.                 begin
  12548.                     raiserror (14027, 11, -1, @source_object)
  12549.                     return (1)
  12550.                 end
  12551.         end
  12552.     select @qualified_name = QUOTENAME(@source_owner) + '.' + QUOTENAME(@source_object)
  12553.     
  12554.     /*
  12555.     ** Security Check
  12556.     */
  12557.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  12558.     IF @@ERROR <> 0 or @retcode <> 0
  12559.         return (1)
  12560.  
  12561.     /*
  12562.     ** Parameter Check: @publication.
  12563.     ** The @publication id cannot be NULL and must conform to the rules
  12564.     ** for identifiers.
  12565.     */   
  12566.         
  12567.     if @publication is NULL
  12568.         begin
  12569.             raiserror (14043, 16, -1, '@publication')
  12570.             return (1)
  12571.         end
  12572.  
  12573.     select @pubid = pubid from sysmergepublications 
  12574.         where name = @publication and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name()
  12575.     if @pubid is NULL
  12576.         begin
  12577.             raiserror (14027, 11, -1, @publication)
  12578.             return (1)
  12579.         end
  12580.     /*
  12581.     ** Only publisher can call sp_addmergearticle
  12582.     */
  12583.     EXEC @retcode = dbo.sp_MScheckatpublisher @pubid
  12584.     IF @@ERROR <> 0 or @retcode <>  0
  12585.         BEGIN
  12586.             RAISERROR (20073, 16, -1)
  12587.             RETURN (1)
  12588.         END
  12589.         
  12590.     select @sync_objid = id from sysobjects where id = OBJECT_ID(@qualified_name)
  12591.     if @sync_objid is NULL
  12592.         begin
  12593.             raiserror (14027, 11, -1, @qualified_name)
  12594.             return (1)
  12595.         end
  12596.  
  12597.     select @row_size=sum(length) from syscolumns where id=OBJECT_ID(@qualified_name)
  12598.     if @row_size>6000 
  12599.         begin
  12600.             RAISERROR (21062, 16, -1, @qualified_name)  
  12601.             -- RETURN (1)
  12602.         end
  12603.  
  12604.     select @num_columns=count(*) from syscolumns where id = object_id(@qualified_name)
  12605.     if @num_columns > 246
  12606.         begin
  12607.             RAISERROR (20068, 16, -1, @qualified_name, 246)
  12608.             RETURN (1)
  12609.         end
  12610.  
  12611.     /*
  12612.     ** Parameter Check: @article.
  12613.     ** Check to see that the @article is local, that it conforms
  12614.     ** to the rules for identifiers, and that it is a table, and not
  12615.     ** a view or another database object.
  12616.     */
  12617.  
  12618.     if @article is NULL
  12619.         begin
  12620.             raiserror (20045, 16, -1)
  12621.             return (1)
  12622.         end
  12623.  
  12624.     exec @retcode = dbo.sp_MSreplcheck_name @article
  12625.     if @@ERROR <> 0 or @retcode <> 0
  12626.         return(1)
  12627.         
  12628.     /*
  12629.     ** Merge does not really support destination object. It has the same value as source
  12630.     */
  12631.     select @destination_object = @source_object
  12632.  
  12633.     /*
  12634.     **  Get the id of the @qualified_name
  12635.     */
  12636.     select @objid = id, @replinfo = replinfo from sysobjects where id = OBJECT_ID(@qualified_name)
  12637.     if @objid is NULL
  12638.         begin
  12639.             raiserror (14027, 11, -1, @qualified_name)
  12640.             return (1)
  12641.         end
  12642.  
  12643.     /*
  12644.     ** If current publication contains a non-sync subscription, all articles to be added in it
  12645.     ** has to contain a rowguidcol.
  12646.     */
  12647.     if exists (select * from sysmergesubscriptions where pubid = @pubid and sync_type = 2)
  12648.         begin
  12649.             if not exists (select * from syscolumns c 
  12650.                 where c.id=@objid and ColumnProperty(c.id, c.name, 'isrowguidcol') = 1)
  12651.                 begin
  12652.                     raiserror(20085 , 16, -1, @article, @publication)
  12653.                     return (1)
  12654.                 end
  12655.         end
  12656.  
  12657.     /*
  12658.     ** Make sure that the table name specified is a table and not a view.
  12659.     */
  12660.  
  12661.     if NOT exists (select * from sysobjects
  12662.         where id = (select OBJECT_ID(@qualified_name)) AND type = 'U')
  12663.         begin
  12664.             raiserror (20074, 16, -1)
  12665.             return (1)
  12666.         end
  12667.  
  12668.     /*
  12669.     ** Check that the underlying table has no timestamp columns.  If it does,
  12670.     ** return an appropriate error.
  12671.     */
  12672.     
  12673.     if EXISTS (SELECT * FROM syscolumns c WHERE c.id = @sync_objid
  12674.                 AND type_name(c.xtype) = 'timestamp')
  12675.         BEGIN
  12676.             RAISERROR (20055, 16, -1, @qualified_name)
  12677.             RETURN (1)
  12678.         END
  12679.         
  12680.     /*
  12681.     ** Parameter Check:  @creation_script and @schema_option
  12682.     ** @schema_option cannot be null
  12683.     ** If @schema_option is 0, there have to be @creation_script defined.
  12684.     */
  12685.     IF @schema_option IS NULL
  12686.     BEGIN
  12687.         select @schema_option  = 0x00000000000000f1
  12688.     END
  12689.  
  12690.     IF @schema_option = 0x0000000000000000
  12691.     BEGIN
  12692.         RAISERROR (3217, 16, -1, '@schema_option')
  12693.         RETURN (1)
  12694.     END
  12695.  
  12696.     /*
  12697.     ** Set the typeid.  The default type is table.  Anything else is
  12698.     ** currently undefined (reserved for future use).
  12699.     **
  12700.     **      @typeid     type
  12701.     **      =======     ========
  12702.     **          1       table
  12703.     ** UNDONE - message
  12704.     */
  12705.  
  12706.     IF LOWER(@type) NOT IN ('table')
  12707.        BEGIN
  12708.             RAISERROR (20074, 16, -1)
  12709.             RETURN (1)
  12710.        END
  12711.  
  12712.     IF LOWER(@type) = 'table'
  12713.        SET @typeid = 0x0a
  12714.  
  12715.     /*
  12716.     ** Validate the column tracking
  12717.     */
  12718.     if @column_tracking IS NULL OR LOWER(@column_tracking) NOT IN ('true', 'false')
  12719.         BEGIN
  12720.             RAISERROR (14148, 16, -1, '@column_tracking')
  12721.             RETURN (1)
  12722.         END
  12723.     if LOWER(@column_tracking) = 'true' 
  12724.         SET @column_tracking_id = 1
  12725.     else 
  12726.         SET @column_tracking_id = 0
  12727.  
  12728.     /*
  12729.     ** Get the pubid.
  12730.     */
  12731.     SELECT @pubid = pubid FROM sysmergepublications 
  12732.         WHERE name = @publication and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name()
  12733.     if @pubid is NULL
  12734.         begin
  12735.             raiserror (14027, 11, -1, @publication)
  12736.             return (1)
  12737.         end
  12738.  
  12739.     /*
  12740.     ** Parameter Check:  @article, @publication.
  12741.     ** Check if the article already exists in this publication.
  12742.     */
  12743.  
  12744.     IF EXISTS (SELECT *
  12745.                  FROM sysmergearticles
  12746.                 WHERE pubid = @pubid
  12747.                   AND name = @article)
  12748.         BEGIN
  12749.             RAISERROR (14030, 16, -1, @article, @publication)
  12750.             RETURN (1)
  12751.         END
  12752.         
  12753.     execute @retcode = dbo.sp_MSgetreplnick @pubid = @pubid, @nickname = @nickname output
  12754.     if (@@error <> 0) or @retcode <> 0 or @nickname IS NULL 
  12755.         begin
  12756.         RAISERROR (14055, 11, -1)
  12757.         RETURN(1)
  12758.         end                 
  12759.  
  12760.     /*
  12761.     ** Set the precmdid.  The default type is 'drop'.
  12762.     **
  12763.     **      @precmdid   pre_creation_cmd
  12764.     **      =========   ================
  12765.     **            0     none
  12766.     **          1     drop
  12767.     **          2     delete
  12768.     **          3     truncate
  12769.     */
  12770.     IF LOWER(@pre_creation_cmd) NOT IN ('none', 'drop', 'delete', 'truncate')
  12771.        BEGIN
  12772.           RAISERROR (14061, 16, -1)
  12773.           RETURN (1)
  12774.        END
  12775.  
  12776.     /*
  12777.     ** Determine the integer value for the pre_creation_cmd.
  12778.     */
  12779.     IF LOWER(@pre_creation_cmd) = 'none'
  12780.        select @precmdid = 0
  12781.     ELSE IF LOWER(@pre_creation_cmd) = 'drop'
  12782.        select @precmdid = 1
  12783.     ELSE IF LOWER(@pre_creation_cmd) = 'delete'
  12784.        select @precmdid = 2
  12785.     ELSE IF LOWER(@pre_creation_cmd) = 'truncate'
  12786.        select @precmdid = 3
  12787.  
  12788.     /*
  12789.     ** Validate the article resolver
  12790.     */
  12791.     if @article_resolver IS NOT NULL
  12792.         begin
  12793.             if @article_resolver = 'default' OR @article_resolver = ''
  12794.                 begin
  12795.                     select @article_resolver = NULL
  12796.                     select @resolver_clsid = NULL
  12797.                 end                 
  12798.             else
  12799.                 begin
  12800.                     /*
  12801.                     ** Get the distributor info
  12802.                     */
  12803.                     EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT
  12804.                     IF @@error <> 0 OR @retcode <> 0 OR @distributor IS NULL
  12805.                         BEGIN
  12806.                             RAISERROR (20036, 16, -1)
  12807.                             RETURN (1)
  12808.                     END
  12809.                     select @distproc = RTRIM(@distributor) + '.master.dbo.xp_regread'
  12810.                     EXECUTE @retcode = @distproc 'HKEY_LOCAL_MACHINE',
  12811.                                   'SOFTWARE\Microsoft\MSSQLServer\Replication\ArticleResolver',
  12812.                                   @article_resolver,
  12813.                                   @param = @resolver_clsid  OUTPUT
  12814.  
  12815.                     /* if xp_regread failed, is it because distributor server is running on Shiloh */
  12816.                     IF @retcode <> 0 or @resolver_clsid IS NULL
  12817.                         begin
  12818.                             EXECUTE @retcode = @distproc 'HKEY_LOCAL_MACHINE',
  12819.                                 'SOFTWARE\Microsoft\Microsoft SQL Server\75\Replication\ArticleResolver',
  12820.                                 @article_resolver,
  12821.                                 @param = @resolver_clsid  OUTPUT
  12822.                             IF @retcode <> 0 or @resolver_clsid IS NULL
  12823.                                 BEGIN
  12824.                                       RAISERROR (20020, 16, -1)
  12825.                                       RETURN (1)
  12826.                                 END
  12827.                         end
  12828.                 end
  12829.         end
  12830.  
  12831.         /*
  12832.         ** If article resolver is 'SP resolver', make sure that resolver_info refers to an SP or XP;
  12833.         ** Also make sure it is stored with owner qualification
  12834.         */
  12835.         if  @article_resolver = @sp_resolver
  12836.             begin
  12837.                 if not exists (select * from sysobjects where id = object_id(@resolver_info) and ( type = 'P' or type = 'X'))
  12838.                     begin
  12839.                         select @resolver_info_len = datalength(@resolver_info)
  12840.                         raiserror(2812, 16, -1, @resolver_info_len, @resolver_info)
  12841.                         return (1)
  12842.                     end
  12843.                     
  12844.                 select @sp_name = name, @sp_owner=user_name(uid) from sysobjects where id = object_id(@resolver_info)
  12845.                 select @resolver_info = QUOTENAME(@sp_owner) + '.' + QUOTENAME(@sp_name) 
  12846.             end
  12847.     /*
  12848.     ** Validate the resolver procedure for the article - should be either a stored proc or an extended procedure.
  12849.     */
  12850.     if @resolver_info IS NOT NULL
  12851.         begin
  12852.             /*
  12853.             ** Get the distributor info
  12854.             */
  12855.             EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT
  12856.             IF @@error <> 0 OR @retcode <> 0 OR @distributor IS NULL
  12857.                 BEGIN
  12858.                     RAISERROR (20036, 16, -1)
  12859.                     RETURN (1)
  12860.             END
  12861.             select @distproc = RTRIM(@distributor) + '.master.dbo.xp_regread'
  12862.             /* Don't force different resolver than one that was passed in. */
  12863.         end             
  12864.  
  12865.  
  12866.     /*
  12867.     **  Add article to sysmergearticles and update sysobjects category bit.
  12868.     */
  12869.     begin tran
  12870.     save TRAN sp_addmergearticle
  12871.         select @artid = artid from sysmergearticles where objid = OBJECT_ID(@qualified_name)
  12872.         select @statusid = 1  /*default status is inactive */
  12873.         if @artid is NULL
  12874.             begin
  12875.                 set @artid = newid()
  12876.                 if @@ERROR <> 0
  12877.                     goto FAILURE
  12878.                 execute @retcode = dbo.sp_MSgentablenickname @tablenick output, @nickname, @objid
  12879.                 if @@ERROR <> 0 OR @retcode <> 0
  12880.                     goto FAILURE
  12881.             end
  12882.         /* Clone the article properties if article has already been published (in a different pub) */
  12883.         else
  12884.             begin
  12885.             /*
  12886.             ** Parameter Check:  @article, @publication.
  12887.             ** Check if the table already exists in this publication.
  12888.             */
  12889.             if exists (select * from sysmergearticles
  12890.                 where pubid = @pubid AND artid = @artid)
  12891.                 begin
  12892.                     raiserror (14030, 16, -1, @article, @publication)
  12893.                     goto FAILURE
  12894.                 end
  12895.             
  12896.             /* Make sure that coltracking option matches */
  12897.             if exists (select * from sysmergearticles where artid = @artid and
  12898.                          column_tracking <> @column_tracking_id)
  12899.                 begin
  12900.                     raiserror (20030, 16, -1, @article)
  12901.                     goto FAILURE
  12902.                 end
  12903.  
  12904.             /* Reuse the article nickname if article has already been published (in a different pub)*/
  12905.             select @tablenick = nickname from sysmergearticles where artid = @artid
  12906.             if @tablenick IS NULL
  12907.                 goto FAILURE
  12908.                 
  12909.             /* Make sure that @resolver_clsid matches the existing resolver_clsid */
  12910.             select @resolver_clsid_old = resolver_clsid from sysmergearticles where artid = @artid 
  12911.             if ((@resolver_clsid IS NULL AND @resolver_clsid_old IS NOT NULL) OR
  12912.                 (@resolver_clsid IS NOT NULL AND @resolver_clsid_old IS NULL) OR
  12913.                 (@resolver_clsid IS NOT NULL AND @resolver_clsid_old IS NOT NULL AND @resolver_clsid_old <> @resolver_clsid))
  12914.                 begin
  12915.                     raiserror (20037, 16, -1, @article)
  12916.                     goto FAILURE
  12917.                 end
  12918.  
  12919.             /* Insert to articles, copying some stuff from other article row */
  12920.             set rowcount 1
  12921.             insert into sysmergearticles (name, type, objid, sync_objid, artid, description,
  12922.                     pre_creation_command, pubid, nickname, column_tracking, status,
  12923.                     conflict_table, creation_script, conflict_script, article_resolver,
  12924.                     resolver_clsid, ins_conflict_proc, schema_option, 
  12925.                     destination_object, subset_filterclause, view_type, resolver_info, gen_cur)
  12926.                 -- use top 1, distinct could return more than one matching row if status different on partitioned articles
  12927.                 select top 1 @article, type, objid, @sync_objid, @artid, @description, @precmdid,
  12928.                     @pubid, nickname, column_tracking, 1, conflict_table, @creation_script,
  12929.                     conflict_script, article_resolver, resolver_clsid, ins_conflict_proc,
  12930.                     @schema_option, @destination_object, @subset_filterclause, 0, resolver_info, gen_cur
  12931.                     from sysmergearticles where artid = @artid
  12932.             set rowcount 0
  12933.  
  12934.             /* Jump to end of transaction  */
  12935.             goto DONE_TRAN
  12936.             end
  12937.  
  12938.         /* Add the specific GUID based replication columns to sys articles */
  12939.         insert sysmergearticles (name, objid, sync_objid, artid, type, description, pubid, nickname, 
  12940.                 column_tracking, status, schema_option, pre_creation_command, destination_object, 
  12941.                 article_resolver, resolver_clsid, subset_filterclause, view_type, resolver_info)
  12942.         values (@article, @objid, @sync_objid, @artid, @typeid, @description, @pubid, @tablenick, 
  12943.                 @column_tracking_id, @statusid, @schema_option, @precmdid, @destination_object, 
  12944.                 @article_resolver, @resolver_clsid, @subset_filterclause, 0, @resolver_info)
  12945.         if @@ERROR <> 0
  12946.             goto FAILURE
  12947.  
  12948.         exec @retcode = dbo.sp_replupdateschema @qualified_name
  12949.         if @@ERROR <> 0 or @retcode <> 0
  12950.             goto FAILURE
  12951.         update sysobjects set replinfo = (replinfo | @merge_pub_object_bit) where id = @objid
  12952.         if @@ERROR <> 0
  12953.             goto FAILURE
  12954.         /* Make a generation */
  12955.         execute @retcode = dbo.sp_MSmakegeneration 
  12956.         if @@ERROR <> 0 
  12957.             goto FAILURE
  12958.  
  12959.                 /* If the article status is active then publish the user tables */
  12960.         if @status = 'active'
  12961.             begin
  12962.                 /* Get a holdlock on the underlying table */
  12963.                 select @cmd = 'select * into #tab1 from '
  12964.                 select @cmd = @cmd + @qualified_name 
  12965.                 select @cmd = @cmd + '(TABLOCK HOLDLOCK) where 1 = 2 '
  12966.                 execute(@cmd)
  12967.  
  12968.                 /* Add the guid column to the user table */
  12969.                 execute @retcode = dbo.sp_MSaddguidcolumn @source_owner, @source_object
  12970.                 if @@ERROR <> 0 OR  @retcode <> 0  -- NOTE: new change
  12971.                     goto FAILURE
  12972.  
  12973.                 /* Create an index on the rowguid column in the user table */
  12974.                 execute @retcode = dbo.sp_MSaddguidindex @source_owner, @source_object
  12975.                 if @@ERROR <> 0 OR @retcode <> 0
  12976.                     goto FAILURE
  12977.  
  12978.                 /* Create the merge triggers on the base table */
  12979.                 execute @retcode = dbo.sp_MSaddmergetriggers @qualified_name, @column_tracking_id
  12980.                 if @@ERROR <> 0 OR @retcode <> 0
  12981.                     goto FAILURE 
  12982.  
  12983.                 /* Create the merge insert/update stored procedures for the base table */
  12984.                 execute @retcode = dbo.sp_MSsetartprocs @publication, @article
  12985.                 if @@ERROR <> 0 OR @retcode <> 0
  12986.                     goto FAILURE
  12987.  
  12988.                 /* Set the article status to be active so that Snapshot does not do this again */
  12989.                 select @statusid = 2 /* Active article */
  12990.                 update sysmergearticles set status = @statusid where artid = @artid
  12991.                 if @@ERROR <> 0 
  12992.                     goto FAILURE
  12993.             end
  12994.         
  12995. DONE_TRAN:
  12996.         /*
  12997.         ** For articles with subset filter clause - set the pub type to subset
  12998.         */
  12999.         if len(@subset_filterclause) > 0
  13000.             begin
  13001.                 execute @retcode = dbo.sp_MSsubsetpublication @publication
  13002.                 if @@ERROR <> 0 or @retcode<>0
  13003.                     goto FAILURE
  13004.             end                     
  13005.         /*
  13006.         ** Get distribution server information for remote RPC call.
  13007.         */
  13008.         EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  13009.            @distribdb   = @distribdb OUTPUT
  13010.         IF @@ERROR <> 0 or @retcode <> 0
  13011.             BEGIN
  13012.                 goto FAILURE
  13013.             END
  13014.  
  13015.         SELECT @dbname =  DB_NAME()
  13016.         
  13017.         SELECT @distproc = RTRIM(@distributor) + '.' + @distribdb + 
  13018.             '.dbo.sp_MSadd_article'
  13019.         EXECUTE @retcode = @distproc
  13020.             @publisher = @@SERVERNAME,
  13021.             @publisher_db = @dbname,
  13022.             @publication = @publication,
  13023.             @article = @article,
  13024.             @destination_object = @destination_object,
  13025.             @source_owner = @source_owner,
  13026.             @source_object = @source_object,
  13027.             @description = @description
  13028.             -- @article_id = NULL
  13029.         IF @@ERROR <> 0 or @retcode <> 0
  13030.             BEGIN
  13031.                 goto FAILURE
  13032.             END
  13033.  
  13034.         COMMIT TRAN 
  13035.  
  13036.         /* If the article status is active adding the merge triggers to the base table */
  13037.          
  13038.         return (0)
  13039. FAILURE:
  13040.         RAISERROR (20009, 16, -1, @article, @publication)
  13041.         if @@TRANCOUNT > 0
  13042.         begin
  13043.             ROLLBACK TRANSACTION sp_addmergearticle
  13044.             COMMIT TRANSACTION
  13045.         end
  13046.         return (1)
  13047. go
  13048.  
  13049. grant execute on dbo.sp_addmergearticle to public
  13050. go
  13051.  
  13052. --------------------------------------------------------------------------------
  13053. --. sp_changemergearticle
  13054. --------------------------------------------------------------------------------
  13055. if exists (select * from sysobjects    where type = 'P'
  13056.     and name = 'sp_changemergearticle')
  13057.     drop procedure sp_changemergearticle
  13058. go
  13059.  
  13060. raiserror('Creating procedure sp_changemergearticle', 0,1)
  13061. go
  13062.  
  13063. CREATE PROCEDURE sp_changemergearticle (
  13064.     @publication sysname,              /* Publication name */
  13065.     @article sysname,              /* Article name */
  13066.     @property sysname = NULL,          /* The property to change */
  13067.     @value nvarchar(2000) = NULL             /* The new property value */
  13068.     ) AS
  13069.  
  13070.     SET NOCOUNT ON
  13071.  
  13072.     /*
  13073.     ** Declarations.
  13074.     */
  13075.     declare @resolver_info_len    int
  13076.     declare @sp_resolver            sysname
  13077.     declare @db_name            sysname
  13078.     declare @artid              uniqueidentifier
  13079.     declare @pubid              uniqueidentifier
  13080.     declare @artidstr           nvarchar(38)
  13081.     declare @pubidstr           nvarchar(38)
  13082.     declare @object             sysname
  13083.     declare @owner              sysname
  13084.     declare @resolver_clsid     nvarchar(50)
  13085.     declare @article_resolver   nvarchar(255)
  13086.     declare @retcode            int
  13087.     declare @statusid           int
  13088.     declare @precmdid           tinyint
  13089.     declare @regkey             nvarchar(255)
  13090.     declare @distributor        sysname
  13091.     declare @distproc           nvarchar(255)
  13092.     
  13093.     declare @schemaversion      int 
  13094.     declare @schemaguid         uniqueidentifier
  13095.     declare @schematype         int
  13096.     declare @schematext         nvarchar(2000)
  13097.  
  13098.     /*
  13099.     ** Security Check
  13100.     */
  13101.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  13102.     IF @@ERROR <> 0 or @retcode <> 0
  13103.         return (1)
  13104.  
  13105.     /*
  13106.     ** Check to see if the database has been activated for publication.
  13107.     */
  13108.  
  13109.     if (select category & 4
  13110.           FROM master..sysdatabases
  13111.          WHERE name = DB_NAME()) = 0
  13112.  
  13113.     BEGIN
  13114.         RAISERROR (14013, 16, -1)
  13115.         RETURN (1)
  13116.     END
  13117.  
  13118.     select @pubid = pubid from sysmergepublications 
  13119.         where name = @publication and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name()
  13120.     if @pubid is NULL
  13121.         begin
  13122.             raiserror (14027, 11, -1, @publication)
  13123.             return (1)
  13124.         end
  13125.  
  13126.  
  13127.     select @db_name = db_name from sysmergesubscriptions
  13128.         where (pubid=@pubid) and (subid=@pubid)
  13129.         IF @db_name <> db_name()
  13130.         BEGIN
  13131.             RAISERROR (20047, 16, -1)
  13132.             RETURN (1)
  13133.         END
  13134.  
  13135.     /*
  13136.     ** Parameter Check:  @property.
  13137.     ** If the @property parameter is NULL, print the options.
  13138.     */
  13139.  
  13140.     if @property IS NULL
  13141.         BEGIN
  13142.             CREATE TABLE #tab1 (properties sysname)
  13143.             INSERT INTO #tab1 VALUES ('description')
  13144.             INSERT INTO #tab1 VALUES ('pre_creation_command')
  13145.             INSERT INTO #tab1 VALUES ('creation_script')
  13146.             INSERT INTO #tab1 VALUES ('column_tracking')
  13147.             INSERT INTO #tab1 VALUES ('article_resolver')
  13148.             INSERT INTO #tab1 VALUES ('resolver_info')
  13149.             INSERT INTO #tab1 VALUES ('status')
  13150.             INSERT INTO #tab1 VALUES ('subset_filterclause')
  13151.             INSERT INTO #tab1 VALUES ('schema_option')
  13152.  
  13153.             
  13154.             select * FROM #tab1
  13155.             RETURN (0)
  13156.         END
  13157.  
  13158.     /*
  13159.     ** Parameter Check:  @property.
  13160.     ** Check to make sure that @property is a valid property in
  13161.     ** sysmergearticles.
  13162.     */
  13163.     if @property IS NULL OR LOWER(@property) NOT IN ('name',
  13164.                                                      'description',
  13165.                                                      'pre_creation_command',
  13166.                                                      'creation_script',
  13167.                                                      'column_tracking',
  13168.                                                      'article_resolver',    
  13169.                                                      'resolver_info',
  13170.                                                      'status',
  13171.                                                      'subset_filterclause',
  13172.                                                      'schema_option')
  13173.  
  13174.         BEGIN
  13175.             RAISERROR (20019, 16, -1)
  13176.             RETURN (1)
  13177.         END
  13178.  
  13179.  
  13180.     /*
  13181.     ** Parameter Check:  @publication.
  13182.     ** Make sure that the publication exists.
  13183.     */
  13184.  
  13185.     if @publication IS NULL
  13186.         BEGIN
  13187.             RAISERROR (14043, 16, -1, '@publication')
  13188.             RETURN (1)
  13189.         END
  13190.  
  13191.  
  13192.     select @pubid = pubid from sysmergepublications 
  13193.         where name = @publication  and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name()
  13194.     if @pubid IS NULL
  13195.         BEGIN
  13196.             RAISERROR (20026, 16, -1, @publication)
  13197.             RETURN (1)
  13198.         END
  13199.  
  13200.     /*
  13201.     ** Check to see that the article exists in sysmergearticles.
  13202.     ** Fetch the article identification number.
  13203.     */
  13204.  
  13205.     if @article IS NULL
  13206.         BEGIN
  13207.             RAISERROR (14043, 16, -1, '@article')
  13208.             RETURN (1)
  13209.         END
  13210.  
  13211.  
  13212.     select @artid = artid FROM sysmergearticles
  13213.         WHERE name = @article AND pubid = @pubid
  13214.     if @artid IS NULL
  13215.         BEGIN
  13216.             RAISERROR (20027, 16, -1, @article)
  13217.             RETURN (1)
  13218.         END
  13219.  
  13220.     set @artidstr = '''' + convert(nchar(36), @artid) + '''' 
  13221.     set @pubidstr = '''' + convert(nchar(36), @pubid) + '''' 
  13222.     select @sp_resolver = 'Microsoft SQLServer Stored Procedure Resolver'
  13223.  
  13224.     /*
  13225.     ** Change the property.
  13226.     */
  13227.     if LOWER(@property) = 'column_tracking'
  13228.         BEGIN
  13229.             /*
  13230.             ** This property can be modified for articles belonging to publications that are not active.
  13231.             */
  13232.             if EXISTS (select status FROM sysmergearticles WHERE artid = @artid AND status = 2)
  13233.                 BEGIN
  13234.                     RAISERROR (20043, 16, -1, @article)
  13235.                     RETURN (1)
  13236.                 END
  13237.  
  13238.             /*
  13239.             ** Check to make sure that we have a valid type.
  13240.             */
  13241.             if LOWER(@value) NOT IN ('true', 'false')
  13242.                 BEGIN
  13243.                     RAISERROR (14137, 16, -1)
  13244.                     RETURN (1)
  13245.                 END
  13246.  
  13247.             /*
  13248.             ** Update the syssubsetdefintions table with the new column tracking.
  13249.             */
  13250.             if LOWER(@value) = 'true'
  13251.                     update sysmergearticles set column_tracking = 1 where artid=@artid      
  13252.             else
  13253.                     update sysmergearticles set column_tracking = 0 where artid=@artid
  13254.             if @@ERROR <> 0 
  13255.                 RETURN (1)
  13256.  
  13257.         END
  13258.  
  13259.      if LOWER(@property)='description'
  13260.         BEGIN
  13261.         UPDATE sysmergearticles  SET description = @value WHERE artid = @artid and pubid = @pubid
  13262.             AND pubid = @pubid
  13263.         if @@ERROR <> 0 
  13264.                 RETURN (1)
  13265.     END
  13266.  
  13267.     if LOWER(@property) ='creation_script'
  13268.         BEGIN
  13269.             update sysmergearticles set creation_script=@value where artid=@artid and pubid=@pubid
  13270.             if @@ERROR <> 0 
  13271.                 RETURN (1)
  13272.         END
  13273.  
  13274.     if LOWER(@property) = 'subset_filterclause'
  13275.         BEGIN
  13276.             /*
  13277.             ** This property can be modified for articles belonging to publications that are not active.
  13278.             */
  13279.             if EXISTS (select status FROM sysmergearticles WHERE artid = @artid AND pubid = @pubid AND status = 2)
  13280.                 BEGIN
  13281.                     RAISERROR (20043, 16, -1, @article)
  13282.                     RETURN (1)
  13283.                 END
  13284.  
  13285.             update sysmergearticles set subset_filterclause = @value where artid=@artid and pubid=@pubid
  13286.             if @@ERROR<>0 return (1)
  13287.             
  13288.             /*
  13289.             ** set the pub type to subset or full as appropriate
  13290.             */
  13291.             execute @retcode = dbo.sp_MSsubsetpublication @publication
  13292.             if @@ERROR <> 0 OR @retcode <> 0
  13293.                 RETURN (1)
  13294.                 
  13295.         END
  13296.  
  13297.     if LOWER(@property) ='article_resolver'
  13298.         BEGIN
  13299.  
  13300.             if @value IS NULL OR @value = 'default' OR @value = ''
  13301.                 begin
  13302.                     set @article_resolver = NULL
  13303.                     set @resolver_clsid = NULL
  13304.                 end                 
  13305.                     
  13306.             else
  13307.                 begin
  13308.                     EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
  13309.                                       'SOFTWARE\Microsoft\MSSQLServer\Replication\ArticleResolver',
  13310.                                       @value,
  13311.                                       @param = @resolver_clsid OUTPUT
  13312.                     IF @@ERROR <> 0 or @retcode <> 0 or @resolver_clsid IS NULL
  13313.                         BEGIN
  13314.                             RAISERROR (20020, 16, -1)
  13315.                             RETURN (1)
  13316.                         END
  13317.                 end                     
  13318.                     
  13319.             /*
  13320.             ** Update the appropriate column in sysmergearticles with the new article resolver name.
  13321.             ** Note this could affect multiple publication if the same table spans publications
  13322.             */
  13323.  
  13324.             /* NOTE: new change */
  13325.             
  13326.             begin tran
  13327.             save TRANSACTION change_article  
  13328.                 exec @retcode = dbo.sp_MSchangearticleresolver @value, @resolver_clsid, @artid
  13329.                 if @@ERROR <> 0 OR @retcode <> 0
  13330.                     begin
  13331.                         if @@TRANCOUNT > 0 
  13332.                         begin
  13333.                             ROLLBACK TRANSACTION change_article
  13334.                             COMMIT TRANSACTION
  13335.                         end
  13336.                         RETURN (1)                          
  13337.                     end  
  13338.                 
  13339.                 declare one_pub CURSOR LOCAL FAST_FORWARD FOR 
  13340.                     select DISTINCT pubid from sysmergearticles where artid=@artid
  13341.                 FOR READ ONLY
  13342.                 open one_pub
  13343.                 fetch next from one_pub into @pubid
  13344.                  
  13345.                 while (@@fetch_status <> -1)
  13346.                     begin
  13347.                         select @schemaversion = schemaversion from sysmergeschemachange
  13348.                         if (@schemaversion is NULL) set @schemaversion = 1
  13349.                         else  
  13350.                             select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange
  13351.                         set @schemaguid = newid()
  13352.                         set @schematype = 8
  13353.                         if @value is not NULL and @value <> ''
  13354.                             select @schematext = 'exec dbo.sp_MSchangearticleresolver ' + '''' + @value + '''' + ',' + '''' + @resolver_clsid + '''' + ',' + '''' + convert(nchar(36), @artid) + ''''
  13355.                         else
  13356.                             select @schematext = 'exec dbo.sp_MSchangearticleresolver NULL, NULL,' + '''' + convert(nchar(36), @artid) + ''''
  13357.                              
  13358.                         exec @retcode = dbo.sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext 
  13359.                             if @@ERROR <> 0 OR @retcode <> 0
  13360.                                 begin
  13361.                                     if @@TRANCOUNT > 0
  13362.                                     begin
  13363.                                         ROLLBACK TRANSACTION change_article
  13364.                                         COMMIT TRANSACTION
  13365.                                     end
  13366.                                     RETURN (1)                          
  13367.                                 end
  13368.                         fetch next from one_pub into @pubid
  13369.                     end 
  13370.                 close one_pub
  13371.                 deallocate one_pub
  13372.             COMMIT TRANSACTION   
  13373.  
  13374.         END /* for property = 'article_resolver' */
  13375.  
  13376.  
  13377.     if LOWER(@property) ='resolver_info'
  13378.         BEGIN
  13379.             /* allow non-sp's as resolver info; don't change the resolver class */
  13380.             select @article_resolver = article_resolver, @resolver_clsid = resolver_clsid from
  13381.                     sysmergearticles where artid = @artid
  13382.  
  13383.              -- Use empty string for nulls so that schema text won't be null
  13384.              if @article_resolver is null set @article_resolver = ''
  13385.              if @resolver_clsid is null set @resolver_clsid = ''
  13386.              if @value is null set @value = ''
  13387.  
  13388.         if  @article_resolver = @sp_resolver
  13389.             begin
  13390.                 if not exists (select * from sysobjects where id = object_id(@value) and ( type = 'P' or type = 'X'))
  13391.                     begin
  13392.                         select @resolver_info_len = datalength(@value)
  13393.                         raiserror(2812, 16, -1, @resolver_info_len, @value)
  13394.                         return (1)
  13395.                     end
  13396.             end
  13397.                     
  13398.             /*
  13399.             ** Update the appropriate column in sysmergearticles with the new resolver info.
  13400.             ** Note this could affect multiple publication if the same table spans publications
  13401.             */
  13402.             BEGIN TRANSACTION   
  13403.                 exec @retcode = dbo.sp_MSchangearticleresolver @article_resolver, @resolver_clsid, @artid, @value
  13404.                 if @@ERROR <> 0 OR @retcode <> 0
  13405.                     begin
  13406.                         if @@TRANCOUNT > 0
  13407.                         begin
  13408.                             ROLLBACK TRANSACTION change_article
  13409.                             COMMIT TRANSACTION
  13410.                         end
  13411.                         RETURN (1)                          
  13412.                     end         
  13413.                 declare one_pub CURSOR LOCAL FAST_FORWARD FOR 
  13414.                     select DISTINCT pubid from sysmergearticles where artid=@artid
  13415.                 FOR READ ONLY
  13416.                 open one_pub
  13417.                 fetch next from one_pub into @pubid
  13418.                  
  13419.                 while (@@fetch_status <> -1)
  13420.                     begin
  13421.                         select @schemaversion = schemaversion from sysmergeschemachange
  13422.                         if (@schemaversion is NULL) set @schemaversion = 1
  13423.                         else  
  13424.                             select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange
  13425.                         set @schemaguid = newid()
  13426.                         set @schematype = 8
  13427.                         select @schematext = 'exec dbo.sp_MSchangearticleresolver ' + '''' + @article_resolver + '''' + ',' + '''' + @resolver_clsid + '''' + ',' + '''' + convert(nchar(36), @artid) + '''' + ',' + '''' + @value + ''''
  13428.                          
  13429.                         exec @retcode = dbo.sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext 
  13430.                             if @@ERROR <> 0 OR @retcode <> 0
  13431.                                 begin
  13432.                                     if @@TRANCOUNT = 1 
  13433.                                         ROLLBACK TRANSACTION 
  13434.                                     else
  13435.                                         COMMIT TRANSACTION 
  13436.                                     RETURN (1)                          
  13437.                                 end
  13438.                         fetch next from one_pub into @pubid
  13439.                     end 
  13440.                 close one_pub
  13441.                 deallocate one_pub
  13442.             COMMIT TRANSACTION    
  13443.  
  13444.         END /* for property = 'resolver_info' */
  13445.  
  13446.  
  13447.     if LOWER(@property) = 'pre_creation_command'
  13448.         BEGIN
  13449.  
  13450.             /*
  13451.             ** Check to make sure that we have a valid pre_creation_cmd.
  13452.             */
  13453.  
  13454.             if LOWER(@value) NOT IN ('none', 'drop', 'delete', 'truncate')
  13455.                 BEGIN
  13456.                     RAISERROR (14061, 16, -1)
  13457.                     RETURN (1)
  13458.                 END
  13459.  
  13460.             /*
  13461.             ** Determine the integer value for the pre_creation_cmd.
  13462.             */
  13463.  
  13464.             if LOWER(@value) = 'none'
  13465.                 select @precmdid = 0
  13466.             else if LOWER(@value) = 'drop'
  13467.                 select @precmdid = 1
  13468.             else if LOWER(@value) = 'delete'
  13469.                 select @precmdid = 2
  13470.             else if LOWER(@value) = 'truncate'
  13471.                 select @precmdid = 3
  13472.  
  13473.             /*
  13474.             ** Update the article with the new pre_creation_cmd.
  13475.             */
  13476.             UPDATE sysmergearticles
  13477.                 SET pre_creation_command = @precmdid
  13478.                 WHERE artid = @artid
  13479.                 AND pubid = @pubid
  13480.  
  13481.             if @@ERROR <> 0 
  13482.                 RETURN (1)
  13483.  
  13484.         END
  13485.  
  13486.     if LOWER(@property) = 'status'
  13487.         BEGIN
  13488.  
  13489.             /*
  13490.             ** Check to make sure that we have a valid status
  13491.             */
  13492.  
  13493.             if LOWER(@value) NOT IN ('active', 'unsynced')
  13494.                 BEGIN
  13495.                     RAISERROR (20075, 16, -1)
  13496.                     RETURN (1)
  13497.                 END
  13498.  
  13499.             /*
  13500.             ** Determine the integer value for the type.
  13501.             */
  13502.  
  13503.             if LOWER(@value) = 'unsynced'
  13504.                 select @statusid = 1
  13505.             else if LOWER(@value) = 'active'
  13506.                 select @statusid = 2
  13507.  
  13508.             /*
  13509.             ** Update the article with the new type. The same base table might be 
  13510.             ** in multiple publications - so qualify  with pubid.
  13511.             */
  13512.             UPDATE sysmergearticles
  13513.                 SET status = @statusid
  13514.                 WHERE artid = @artid and pubid = @pubid
  13515.  
  13516.             if @@ERROR <> 0 
  13517.                 RETURN (1)
  13518.  
  13519.         END
  13520.  
  13521.     IF LOWER(@property) = 'schema_option'
  13522.         BEGIN
  13523.         
  13524.             IF @value IS NULL
  13525.                 BEGIN
  13526.                     RAISERROR(14146, 16,1)
  13527.                     RETURN (1)
  13528.                 END
  13529.  
  13530.             CREATE TABLE #tab_changearticle (value binary(8) NULL)
  13531.                                  
  13532.             IF @@ERROR <> 0 
  13533.                 BEGIN
  13534.                     RETURN (1)
  13535.                 END
  13536.  
  13537.             EXEC ('insert #tab_changearticle values (' + 
  13538.                     @value +')' )
  13539.                                  
  13540.             IF @@ERROR <> 0 
  13541.                 BEGIN
  13542.                     RETURN (1)
  13543.                 END
  13544.  
  13545.             IF exists (select * from #tab_changearticle where value = 0x0000000000000000)
  13546.             BEGIN
  13547.                 RAISERROR (3217, 16, -1, 'schema_option')
  13548.                 RETURN (1)
  13549.             END
  13550.                       
  13551.             UPDATE sysmergearticles SET schema_option = tab.value from 
  13552.                 #tab_changearticle tab 
  13553.                 WHERE artid = @artid
  13554.                 AND pubid = @pubid
  13555.             if @@ERROR <> 0
  13556.                 BEGIN
  13557.                 DROP TABLE #tab_changearticle 
  13558.                 RETURN (1)
  13559.                 END
  13560.                 
  13561.             DROP TABLE #tab_changearticle 
  13562.                                  
  13563.             IF @@ERROR <> 0 
  13564.                 BEGIN
  13565.                     RETURN (1)
  13566.                 END
  13567.  
  13568.         END
  13569.  
  13570.  
  13571.     /*
  13572.     ** Return succeed.
  13573.     */
  13574.  
  13575.     RETURN (0)
  13576. go
  13577.  
  13578. grant execute on dbo.sp_changemergearticle to public
  13579. go
  13580.  
  13581. --------------------------------------------------------------------------------
  13582. --. sp_addmergepublication
  13583. --------------------------------------------------------------------------------
  13584. if exists (select * from sysobjects    where type = 'P'
  13585.     and name = 'sp_addmergepublication')
  13586.     drop procedure sp_addmergepublication
  13587. go
  13588.  
  13589. raiserror('Creating procedure sp_addmergepublication', 0,1)
  13590. go
  13591.  
  13592. create procedure sp_addmergepublication (
  13593.     @publication            sysname,                /* Publication name */
  13594.     @description            nvarchar(255)= NULL,            /* Publication description */
  13595.     @retention              int         = 60,           /* Retention period of 60 days */
  13596.     @sync_mode              nvarchar(10) = 'native',    /* (bcp)native, (bcp)character */
  13597.     @allow_push             nvarchar(5)  = 'true',          /* Pulication allows push subscriptions */
  13598.     @allow_pull             nvarchar(5)  = 'true',          /* Pulication allows pull subscriptions*/
  13599.     @allow_anonymous        nvarchar(5)  = 'false',         /* Pulication allows anonymous subscriptions */
  13600.     @enabled_for_internet   nvarchar(5)     = 'false',      /* Pulication is enabled for internet */
  13601.     @centralized_conflicts  nvarchar(5)  = 'true',          /* Conflict records stored at publisher : true or false */
  13602.     @dynamic_filters            nvarchar(5) = 'false',           /* Will publication be filtered on dynamic clause? */
  13603.     @keep_partition_changes nvarchar(5) = 'false'        /* Optimized Partition Updates/Deletes */
  13604.     ) as
  13605.  
  13606.     set nocount on
  13607.  
  13608.     /*
  13609.     ** Declarations.
  13610.     */
  13611.     
  13612.     declare @retcode                    int         /* return code value for procedure execution */
  13613.     declare @push                       tinyint     /* subscription type is push */
  13614.     declare @statid                     tinyint     /* status id based on @status */
  13615.     declare @sync_modeid                tinyint     /* sync mode id based on @sync_mode */
  13616.     declare @global                     tinyint     /* subscriber type of loop-back subscription */
  13617.     declare @db_name                    sysname     /* database name */
  13618.     declare @srvid                      int         /* Server ID */
  13619.     declare @nickname                   int         /* replica nickname */
  13620.     declare @tranpublish_bit            smallint    /* online publish bit (flag) in sysdatabases */
  13621.     declare @mergepublish_bit           smallint    /* merge publish bit (flag) in sysdatabases */
  13622.     declare @found                      int         /* flag indicating if publication is found */
  13623.     declare @pubid                      uniqueidentifier    /* Publication identifier */
  13624.     declare @allow_push_id              bit
  13625.     declare @allow_pull_id              bit
  13626.     declare @allow_anonymous_id         bit
  13627.     declare @dynamic_filters_id         bit         
  13628.     DECLARE @enabled_for_internet_id    bit
  13629.     declare @centralized_conflicts_id   bit
  13630.     declare @priority                   real        
  13631.     declare @automatic                  tinyint     
  13632.     declare @false                      bit
  13633.     declare @true                       bit
  13634.     declare @distributor                sysname
  13635.     declare @distproc                   nvarchar(255)
  13636.     declare @distribdb                  sysname
  13637.     declare @distpubid                  int
  13638.     declare @full                       int
  13639.     declare @keep_before_values_int           int
  13640.  
  13641.     /*
  13642.     ** Initializations
  13643.     */
  13644.     select @mergepublish_bit    = 4 
  13645.     select @tranpublish_bit     = 1
  13646.     select @priority            = 100.0
  13647.     select @automatic           = 1     /* Const: synchronization type 'automatic' */
  13648.     select @true                = 1
  13649.     select @false               = 0
  13650.     select @full                = 0     /* Const: publication type 'full' */
  13651.  
  13652.     /*
  13653.     ** Set the status to unsynced (1)
  13654.     */
  13655.     select @statid      = 1
  13656.     select @global      = 1
  13657.     select @push        = 0
  13658.     select @db_name     = DB_NAME()
  13659.  
  13660.     /*
  13661.     ** Security Check
  13662.     */
  13663.  
  13664.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  13665.     IF @@ERROR <> 0 or @retcode <> 0
  13666.         return (1)
  13667.  
  13668.     /*
  13669.     ** Only publisher can call sp_addmergepublication to add its own publications 
  13670.     */
  13671.     if not exists (select * from sysobjects where name = 'sysmergepublications')
  13672.             BEGIN
  13673.                 RAISERROR (20054, 16, -1)
  13674.                 RETURN (1)
  13675.             END
  13676.  
  13677.     /*
  13678.     ** Parameter Check: @publication.
  13679.     ** The @publication name must conform to the rules for identifiers,
  13680.     ** and must not be the keyword 'all'.
  13681.     */
  13682.     if @publication is NULL
  13683.         begin
  13684.             raiserror (14043, 16, -1, '@publication')
  13685.             return (1)
  13686.         end
  13687.  
  13688.     exec @retcode = dbo.sp_MSreplcheck_name @publication
  13689.     if @@ERROR <> 0 or @retcode <> 0
  13690.         return(1)
  13691.        
  13692.     if LOWER (@publication) = 'all'
  13693.         begin
  13694.             raiserror (14034, 16, -1)
  13695.             return (1)
  13696.         end
  13697.  
  13698.     /*
  13699.     ** Parameter Check: @retention.
  13700.     ** Make sure that the maximum retention period is 60 days
  13701.     */
  13702.         
  13703.     if @retention is not NULL and @retention<0 
  13704.         begin
  13705.             raiserror(20050, 16, -1, 0)
  13706.             return(1)
  13707.         end
  13708.  
  13709.     if @retention is NULL
  13710.         select @retention = 0
  13711.  
  13712.     /*
  13713.     ** Parameter Check: @sync_mode.
  13714.     ** Make sure that the sync_mode is one of the following:
  13715.     **
  13716.     **  id  sync_mode
  13717.     **  ==  ==========
  13718.     **   0  (bcp)native
  13719.     **   1  (bcp)character
  13720.     */
  13721.     
  13722.     if LOWER(@sync_mode)='portable' select @sync_mode='character'
  13723.  
  13724.     if LOWER(@sync_mode) is NULL OR LOWER(@sync_mode) NOT IN ('bcp native', 'bcp character', 'native', 'character')
  13725.         begin
  13726.             raiserror (20076, 16, -1)
  13727.             return (1)
  13728.         end
  13729.  
  13730.     if LOWER(@sync_mode) = 'native' or LOWER(@sync_mode)='bcp native' 
  13731.         select @sync_modeid = 0
  13732.     else 
  13733.         select @sync_modeid = 1
  13734.  
  13735.     /*
  13736.     ** Parameter Check:  @allow_push.
  13737.     */
  13738.  
  13739.     if @allow_push IS NULL OR LOWER(@allow_push) NOT IN ('true', 'false')
  13740.         BEGIN
  13741.             RAISERROR (14148, 16, -1, '@allow_push')
  13742.             RETURN (1)
  13743.         END
  13744.  
  13745.     if LOWER(@allow_push) = 'true' 
  13746.         select @allow_push_id = 1
  13747.     else 
  13748.         select @allow_push_id = 0
  13749.  
  13750.     /*
  13751.     ** Parameter Check:  @allow_pull.
  13752.     */
  13753.  
  13754.     if @allow_pull IS NULL OR LOWER(@allow_pull) NOT IN ('true', 'false')
  13755.         BEGIN
  13756.             RAISERROR (14148, 16, -1, '@allow_pull')
  13757.             RETURN (1)
  13758.         END
  13759.     if LOWER(@allow_pull) = 'true' 
  13760.         select @allow_pull_id = 1
  13761.     else 
  13762.         select @allow_pull_id = 0
  13763.  
  13764.     /*
  13765.     ** Parameter Check:  @allow_anonymous.
  13766.     */
  13767.  
  13768.     if @allow_anonymous IS NULL OR LOWER(@allow_anonymous) NOT IN ('true', 'false')
  13769.         BEGIN
  13770.             RAISERROR (14148, 16, -1, '@allow_anonymous')
  13771.             RETURN (1)
  13772.         END
  13773.     if LOWER(@allow_anonymous) = 'true' 
  13774.         select @allow_anonymous_id = 1
  13775.     else 
  13776.         select @allow_anonymous_id = 0
  13777.  
  13778.     /*
  13779.     ** Parameter Check:  @enabled_for_internet.
  13780.     */
  13781.  
  13782.     IF @enabled_for_internet IS NULL OR LOWER(@enabled_for_internet) NOT IN ('true', 'false')
  13783.         BEGIN
  13784.             RAISERROR (14148, 16, -1, '@enabled_for_internet')
  13785.             RETURN (1)
  13786.         END
  13787.  
  13788.     IF LOWER(@enabled_for_internet) = 'true' 
  13789.         SELECT @enabled_for_internet_id = 1
  13790.     ELSE 
  13791.         SELECT @enabled_for_internet_id = 0
  13792.  
  13793.     /*
  13794.     ** Parameter Check:  @centralized_conflicts.
  13795.     */
  13796.  
  13797.     if @centralized_conflicts IS NULL OR LOWER(@centralized_conflicts) NOT IN ('true', 'false')
  13798.         BEGIN
  13799.             RAISERROR (14148, 16, -1, '@centralized_conflicts')
  13800.             RETURN (1)
  13801.         END
  13802.     if LOWER(@centralized_conflicts) = 'true' 
  13803.         select @centralized_conflicts_id = 1
  13804.     else 
  13805.         select @centralized_conflicts_id = 0
  13806.  
  13807.     /*
  13808.     ** Parameter Check:  @dynamic_filter.
  13809.     */
  13810.  
  13811.     IF @dynamic_filters IS NULL OR LOWER(@dynamic_filters) NOT IN ('true', 'false')
  13812.         BEGIN
  13813.             RAISERROR (14148, 16, -1, '@dynamic_filters')
  13814.             RETURN (1)
  13815.         END
  13816.  
  13817.     IF LOWER(@dynamic_filters) = 'true' 
  13818.         SELECT @dynamic_filters_id = 1
  13819.     ELSE 
  13820.         SELECT @dynamic_filters_id = 0
  13821.  
  13822.     /*
  13823.     ** Parameter Check:  @keep_partition_changes.
  13824.     */
  13825.  
  13826.     if LOWER(@keep_partition_changes) NOT IN ('true', 'false')
  13827.         BEGIN
  13828.             RAISERROR (14148, 16, -1, '@keep_partition_changes')
  13829.             RETURN (1)
  13830.         END
  13831.  
  13832.     if LOWER(@keep_partition_changes) = 'true' 
  13833.         set @keep_before_values_int = 1
  13834.     else 
  13835.         set @keep_before_values_int = 0
  13836.  
  13837.  
  13838.     /*
  13839.     ** Check to see if the publication name is already used.
  13840.     ** 1. check merge pubs
  13841.     ** 2. check online publications
  13842.     */
  13843.     if exists (select * from sysmergepublications 
  13844.         where name = @publication  and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name())
  13845.     begin
  13846.         RAISERROR (20025, 16, -1, @publication)
  13847.         RETURN (1)
  13848.     end
  13849.  
  13850.     if (select category & @tranpublish_bit from master..sysdatabases where name = @db_name) <> 0
  13851.     begin
  13852.         EXEC @retcode = dbo.sp_helppublication @publication, @found output
  13853.  
  13854.         if @@ERROR <> 0 OR @retcode <> 0
  13855.         BEGIN
  13856.             RETURN (1)
  13857.         END
  13858.  
  13859.         if @found <> 0 
  13860.         BEGIN
  13861.             RAISERROR (20025, 16, -1, @publication)
  13862.             RETURN (1)
  13863.         END
  13864.     end
  13865.  
  13866.  
  13867.     /*
  13868.     **  Add the publication as the designmaster of the replica set.
  13869.     */
  13870.  
  13871.     /* Generate a guid for the publication ID */
  13872.     set @pubid = newid()
  13873.         
  13874.     /* Select the server's ID as 0 since this is the LOCAL server */
  13875.     select @srvid = 0
  13876.  
  13877.     /* Look for existing nickname from any other subscription */
  13878.     exec @retcode=sp_MSgetreplnick NULL, NULL , NULL,  @nickname out
  13879.     if (@@error <> 0) or @retcode <> 0 
  13880.         begin
  13881.             RETURN(1)
  13882.         end                 
  13883.             
  13884.     /* Generate a new replica nickname from the @pubid */
  13885.     if (@nickname is null)
  13886.     begin
  13887.         execute @retcode = dbo.sp_MSgenreplnickname @pubid, @nickname output
  13888.         IF @@ERROR <>0 OR @retcode <> 0
  13889.         BEGIN
  13890.             RAISERROR (20077, 16, -1)
  13891.             RETURN (1)
  13892.         END
  13893.     end
  13894.     else
  13895.         select @priority=max(priority) from sysmergesubscriptions where db_name=@db_name and srvid = @srvid
  13896.     /*
  13897.     ** A change in design.
  13898.     */
  13899.     if @priority = 0 
  13900.         begin
  13901.             RAISERROR(21087, 16, -1)
  13902.             return (1)
  13903.         end
  13904.  
  13905.     /*
  13906.     ** Get distributor information
  13907.     */
  13908.     EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT, 
  13909.         @distribdb = @distribdb OUTPUT
  13910.         if @@error <> 0 OR @retcode <> 0 or @distributor IS NULL OR @distribdb IS NULL
  13911.         BEGIN
  13912.             RAISERROR (14071, 16, -1)
  13913.             RETURN (1)
  13914.         END
  13915.     
  13916.     /*
  13917.     **  add an entry into sysmergepublications
  13918.     */
  13919.     begin tran
  13920.     save tran sp_addmergepublication
  13921.         /* Add row in the publications table */
  13922.         insert sysmergepublications
  13923.             (pubid, 
  13924.             name, 
  13925.             description, 
  13926.             designmasterid, 
  13927.             retention, 
  13928.             parentid, 
  13929.             sync_mode, 
  13930.             allow_push, 
  13931.             allow_pull, 
  13932.             allow_anonymous, 
  13933.             centralized_conflicts,
  13934.             status,
  13935.             snapshot_ready,
  13936.             enabled_for_internet,
  13937.             publication_type,
  13938.             dynamic_filters,
  13939.             keep_before_values)
  13940.         values
  13941.             (@pubid, 
  13942.             @publication, 
  13943.             @description, 
  13944.             @pubid, 
  13945.             @retention, 
  13946.             @pubid, 
  13947.             @sync_modeid, 
  13948.             @allow_push_id, 
  13949.             @allow_pull_id, 
  13950.             @allow_anonymous_id, 
  13951.             @centralized_conflicts_id,
  13952.             @statid,
  13953.             @false,
  13954.             @enabled_for_internet_id,
  13955.             @full,
  13956.             @dynamic_filters_id,
  13957.             @keep_before_values_int)
  13958.         if @@ERROR <> 0
  13959.             begin
  13960.                 goto FAILURE
  13961.             end
  13962.  
  13963.         /* Add row to represent reciprocal subscription */
  13964.         /* Note that we have overloaded last_updated column of this table for publication */
  13965.         insert sysmergesubscriptions(subid, partnerid, datasource_type, srvid, db_name, status, priority, pubid, subscriber_type, subscription_type, sync_type, login_name, last_validated)
  13966.             values (@pubid, @pubid, 0, @srvid, @db_name, @statid, @priority, @pubid, @global, @push, @automatic, suser_sname(suser_sid()), getdate())
  13967.  
  13968.         if @@ERROR <> 0
  13969.             begin
  13970.                 goto FAILURE
  13971.             end
  13972.         /*
  13973.         **  Add row for merge publication to MSmerge_replinfo.
  13974.         */
  13975.         insert MSmerge_replinfo(repid, replnickname)
  13976.             values (@pubid, @nickname)
  13977.         if @@ERROR <> 0
  13978.             begin
  13979.                 goto FAILURE
  13980.             end
  13981.  
  13982.  
  13983.         /*
  13984.         ** Add the publication to the distributor side
  13985.         */
  13986.         SELECT @distpubid = @nickname
  13987.  
  13988.         select @distproc = RTRIM(@distributor) + '.' + @distribdb + 
  13989.             '.dbo.sp_MSadd_publication'
  13990.         EXECUTE @retcode = @distproc
  13991.             @publisher = @@SERVERNAME,
  13992.             @publisher_db = @db_name,
  13993.             @publication = @publication,
  13994.             --@publication_id = NULL,
  13995.             @publication_type = 2,          -- 0 = Trans, 1 = Snapshot, 2 = Merge
  13996.             @independent_agent = @true,
  13997.             @immediate_sync = @true,
  13998.             @allow_push = @allow_push_id,
  13999.             @allow_pull = @allow_pull_id,
  14000.             @allow_anonymous = @allow_anonymous_id,
  14001.             --@snapshot_agent = NULL,
  14002.             --@logreader_agent = NULL,
  14003.             @description = @description,
  14004.             @retention = @retention
  14005.  
  14006.         IF @@ERROR <> 0 or @retcode <> 0
  14007.             BEGIN
  14008.                 GOTO FAILURE
  14009.             END
  14010.         
  14011.         
  14012.         -- Populate the initial list.
  14013.         exec @retcode = dbo.sp_grant_publication_access 
  14014.             @publication = @publication,
  14015.             @login = null,
  14016.             @reserved = 'init'
  14017.         IF @@error <> 0 OR @retcode <> 0
  14018.             GOTO FAILURE
  14019.     
  14020.     commit tran
  14021.     return (0)
  14022.  
  14023. FAILURE:
  14024.     RAISERROR (14018, 16, -1)
  14025.     /* UNDONE : This code is specific to 6.X nested transaction semantics */
  14026.     if @@TRANCOUNT > 0
  14027.     begin
  14028.         ROLLBACK TRANSACTION sp_addmergepublication
  14029.         COMMIT TRANSACTION
  14030.     end
  14031.     return (1)
  14032. go
  14033.  
  14034. grant execute on dbo.sp_addmergepublication to public
  14035. go
  14036.  
  14037. --------------------------------------------------------------------------------
  14038. --. sp_helpmergepublication
  14039. --------------------------------------------------------------------------------
  14040. if exists (select * from sysobjects    where type = 'P'
  14041.     and name = 'sp_helpmergepublication')
  14042.     drop procedure sp_helpmergepublication
  14043. go
  14044.  
  14045. raiserror('Creating procedure sp_helpmergepublication', 0,1)
  14046. go
  14047.  
  14048. CREATE PROCEDURE sp_helpmergepublication (
  14049.     @publication    sysname = '%',    /* The publication name */
  14050.     @found          int         = NULL  OUTPUT,
  14051.     @publication_id uniqueidentifier = NULL OUTPUT,
  14052.     @reserved       nvarchar(20) = NULL
  14053.     ) AS
  14054.  
  14055.     SET NOCOUNT ON
  14056.  
  14057.     /*
  14058.     ** Declarations.
  14059.     */
  14060.  
  14061.     declare @retcode            int
  14062.     declare @no_row             bit
  14063.     declare @our_srvid          int
  14064.     declare @has_subscription   bit
  14065.     /*
  14066.     ** Initializations.
  14067.     */
  14068.     select @has_subscription = 0
  14069.  
  14070.     if @found is NULL 
  14071.     BEGIN
  14072.         select @no_row=0
  14073.     END
  14074.     else
  14075.     BEGIN
  14076.         select @no_row=1
  14077.     END
  14078.     select @found       = 0
  14079.     select @our_srvid = max(srvid) from master..sysservers where UPPER(srvname) = UPPER(@@SERVERNAME)
  14080.  
  14081.     
  14082.     /*
  14083.     ** Running sp_help is OK from everywhere, whether enabled for publishing or not
  14084.     */
  14085.     
  14086.     IF not exists (select * from sysobjects where name='sysmergesubscriptions')
  14087.         RETURN (0)
  14088.  
  14089.  
  14090.     /*
  14091.     ** Parameter Check:  @publication.
  14092.     ** Check to make sure that there are some publications
  14093.     ** to display.
  14094.     */
  14095.  
  14096.     if @publication IS NULL
  14097.         BEGIN
  14098.             RAISERROR (14043, 16, -1, '@publication')
  14099.             RETURN (1)
  14100.         END
  14101.  
  14102.     IF LOWER(@reserved) = 'internal'
  14103.         GOTO SelectPubs
  14104.     
  14105.     if  NOT EXISTS (select * FROM sysmergepublications pub, sysmergesubscriptions sub
  14106.         WHERE pub.name like @publication  
  14107.             and UPPER(pub.publisher)=UPPER(@@servername) 
  14108.             and pub.publisher_db=db_name() 
  14109.             and sub.pubid = pub.pubid  
  14110.             and sub.srvid = @our_srvid 
  14111.             and sub.db_name = db_name())
  14112.         BEGIN
  14113.             select @found = 0
  14114.             RETURN (0) 
  14115.         END
  14116.     else
  14117.         BEGIN
  14118.             select @found = 1
  14119.             select @publication_id = pubid FROM sysmergepublications 
  14120.                 WHERE name = @publication and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name()
  14121.             if exists (select * from sysmergesubscriptions where pubid<>subid and pubid in 
  14122.                 (select pubid from sysmergepublications where name like @publication and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name()))
  14123.                 select @has_subscription = 1
  14124.             if @no_row <> 0
  14125.                 RETURN(0)
  14126.         END
  14127.  
  14128. SelectPubs:
  14129.     CREATE TABLE #tab1 (
  14130.         id                      int                 identity NOT NULL,
  14131.         name                    sysname             NOT NULL,
  14132.         description             nvarchar(255)       NULL,
  14133.         status                  tinyint             NOT NULL,
  14134.         retention               int                 NULL,
  14135.         sync_mode               tinyint             NULL,
  14136.         allow_push              int                 NOT NULL,
  14137.         allow_pull              int                 NOT NULL,
  14138.         allow_anonymous         int                 NOT NULL,
  14139.         centralized_conflicts   int                 NOT NULL,
  14140.         priority                float(8)            NOT NULL,
  14141.         snapshot_ready          tinyint             NOT NULL,
  14142.         publication_type        int                 NULL,
  14143.         pubid                   uniqueidentifier    NOT NULL,
  14144.         snapshot_jobid          binary(16)          NULL,
  14145.         enabled_for_internet    int                 NULL,
  14146.         dynamic_filters         int                 NULL,
  14147.         has_subscription        bit                 NULL,
  14148.         keep_partition_changes    int                    NULL,
  14149.         snapshot_status            int                    NULL
  14150.         )
  14151.  
  14152.     /* This is valid at all sites - used for decentralized conflicts */
  14153.     IF LOWER(@reserved) = 'internal'
  14154.         begin
  14155.             INSERT into #tab1(name, description, status, retention, sync_mode, 
  14156.                     allow_push, allow_pull, allow_anonymous, centralized_conflicts, 
  14157.                     priority, snapshot_ready, publication_type, pubid, snapshot_jobid, 
  14158.                     enabled_for_internet, 
  14159.                     dynamic_filters, keep_partition_changes, snapshot_status)
  14160.             select  pubs.name, pubs.description, pubs.status, pubs.retention, pubs.sync_mode, 
  14161.                     pubs.allow_push, pubs.allow_pull, pubs.allow_anonymous, pubs.centralized_conflicts, 
  14162.                     subs.priority, pubs.snapshot_ready, 
  14163.                     pubs.publication_type, pubs.pubid, replinfo.snapshot_jobid,
  14164.                     pubs.enabled_for_internet, 
  14165.                     pubs.dynamic_filters,
  14166.                     pubs.keep_before_values,
  14167.                     case when (pubs.retention=0) or (pubs.snapshot_ready=0) or (dateadd(day, pubs.retention, subs.last_validated)>getdate()) 
  14168.                                 then pubs.snapshot_ready
  14169.                          else 3
  14170.                         end
  14171.             FROM    sysmergesubscriptions   subs,
  14172.                     sysmergepublications    pubs,
  14173.                     MSmerge_replinfo        replinfo
  14174.                     WHERE pubs.name LIKE @publication
  14175.                         AND UPPER(pubs.publisher)=UPPER(@@servername) 
  14176.                         AND pubs.publisher_db=db_name()
  14177.                         AND subs.subid = pubs.pubid
  14178.                         AND replinfo.repid = pubs.pubid
  14179.                         AND subs.subscriber_type = 1
  14180.             ORDER BY name
  14181.         end
  14182.     /* This is valid only at publishers and republishers */
  14183.     else
  14184.         begin
  14185.             INSERT into #tab1(name, description, status, retention, sync_mode, 
  14186.                     allow_push, allow_pull, allow_anonymous, centralized_conflicts, 
  14187.                     priority, snapshot_ready,
  14188.                     publication_type, pubid, snapshot_jobid, 
  14189.                     enabled_for_internet,
  14190.                     dynamic_filters, keep_partition_changes, has_subscription, snapshot_status)
  14191.             select  pubs.name, pubs.description, pubs.status, pubs.retention, pubs.sync_mode, 
  14192.                     pubs.allow_push, pubs.allow_pull, pubs.allow_anonymous, pubs.centralized_conflicts, 
  14193.                     subs.priority, pubs.snapshot_ready,  
  14194.                     pubs.publication_type, pubs.pubid, replinfo.snapshot_jobid,
  14195.                     pubs.enabled_for_internet,
  14196.                     pubs.dynamic_filters, pubs.keep_before_values, case when exists (select * from sysmergesubscriptions where pubid<>subid and pubid in 
  14197.                                                 (select in_pubs.pubid from sysmergepublications in_pubs where in_pubs.name = pubs.name 
  14198.                                                     and UPPER(in_pubs.publisher)=UPPER(@@servername) and in_pubs.publisher_db=db_name()))
  14199.                                           then 1
  14200.                                           else 0 end,
  14201.                     case when (pubs.retention=0) or (pubs.snapshot_ready=0) or dateadd(day, pubs.retention, subs.last_validated)>getdate() 
  14202.                                 then pubs.snapshot_ready
  14203.                          else 3
  14204.                     end                  
  14205.             FROM    sysmergesubscriptions   subs,
  14206.                     sysmergepublications    pubs,
  14207.                     MSmerge_replinfo        replinfo
  14208.                     WHERE pubs.name LIKE @publication
  14209.                          and UPPER(pubs.publisher)=UPPER(@@servername) 
  14210.                          and pubs.publisher_db=db_name()
  14211.                         AND subs.subid = pubs.pubid
  14212.                         AND replinfo.repid = pubs.pubid
  14213.                         AND subs.subscriber_type = 1
  14214.                         AND subs.srvid = @our_srvid 
  14215.                         AND subs.db_name = db_name()
  14216.             ORDER BY name
  14217.         end
  14218.     if @@ERROR <> 0 
  14219.         RETURN (1)            
  14220.     select * FROM #tab1
  14221.     RETURN (0)
  14222. go
  14223.  
  14224. grant execute on dbo.sp_helpmergepublication to public
  14225. go
  14226.  
  14227. --------------------------------------------------------------------------------
  14228. --. sp_reinitmergesubscription
  14229. --------------------------------------------------------------------------------
  14230. if exists (select * from sysobjects    where type = 'P'
  14231.     and name = 'sp_reinitmergesubscription')
  14232.     drop procedure sp_reinitmergesubscription
  14233. go
  14234.  
  14235. raiserror('Creating procedure sp_reinitmergesubscription', 0,1)
  14236. go
  14237.  
  14238. create procedure sp_reinitmergesubscription
  14239.     @publication    sysname  = 'all',
  14240.     @subscriber     sysname  = 'all',
  14241.     @subscriber_db  sysname  = 'all'
  14242. AS
  14243.     declare @pubid                  uniqueidentifier
  14244.     declare @subid                  uniqueidentifier
  14245.     declare @subscription_type        int
  14246.     declare @reinit_bit                int
  14247.     declare @publisher                sysname
  14248.     declare @publisher_db            sysname
  14249.     declare @distribdb                sysname
  14250.     declare @distributor            sysname
  14251.     declare @distproc                nvarchar(255)
  14252.     declare @retcode                int
  14253.     declare @subname                sysname
  14254.     declare @subdb                    sysname
  14255.     declare @pubname                sysname
  14256.     declare @subsrvid                int
  14257.     /*
  14258.     ** Replace 'all' with '%'
  14259.     */
  14260.  
  14261.     if LOWER(@publication) = 'all'
  14262.         SELECT @publication = '%'
  14263.  
  14264.     if LOWER(@subscriber) = 'all'
  14265.         SELECT @subscriber = '%'
  14266.  
  14267.     if LOWER(@subscriber_db) = 'all'
  14268.         SELECT @subscriber_db = '%'
  14269.  
  14270.     /*
  14271.     ** At publisher side, publication name is unique
  14272.     */
  14273.     IF NOT EXISTS (SELECT * FROM sysmergepublications 
  14274.         WHERE name LIKE @publication)
  14275.         BEGIN
  14276.         IF @publication = '%'
  14277.                 RAISERROR (14008, 11, -1)
  14278.         ELSE
  14279.                 RAISERROR (20026, 11, -1, @publication)
  14280.         RETURN (1)
  14281.         END
  14282.  
  14283.     EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT, @distribdb   = @distribdb OUTPUT
  14284.         IF @@ERROR <> 0 or @retcode <> 0
  14285.                 return (1)
  14286.  
  14287.     SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSmarkreinit '
  14288.  
  14289.     BEGIN TRAN
  14290.     
  14291.     Declare SYN_CUR CURSOR LOCAL FAST_FORWARD FOR 
  14292.         select subs.subid, subs.subscription_type, pubs.publisher, pubs.publisher_db, pubs.name, subs.srvid, subs.db_name
  14293.             from sysmergepublications pubs, sysmergesubscriptions subs
  14294.                 where pubs.name LIKE  @publication 
  14295.                      and UPPER(pubs.publisher)=UPPER(@@servername) 
  14296.                      and pubs.publisher_db=db_name()
  14297.                     AND pubs.pubid=subs.pubid
  14298.                     AND subs.pubid<>subs.subid
  14299.                     AND db_name like @subscriber_db
  14300.                     AND srvid in (select srvid from master..sysservers where ((@subscriber = N'%') or (UPPER(srvname) = UPPER(@subscriber))))
  14301.     FOR READ ONLY
  14302.     open SYN_CUR
  14303.     fetch SYN_CUR into @subid, @subscription_type, @publisher, @publisher_db, @pubname, @subsrvid, @subdb
  14304.     while (@@fetch_status<>-1)
  14305.     BEGIN   
  14306.     -- Security check 
  14307.         if not exists (select * from sysmergesubscriptions subs1 where
  14308.         (suser_sname(suser_sid()) = subs1.login_name OR 
  14309.         is_member('db_owner')=1 OR 
  14310.         is_srvrolemember('sysadmin') = 1) and
  14311.         subid = @subid)
  14312.         continue        
  14313.  
  14314.         select @subname=srvname from master..sysservers where srvid=@subsrvid
  14315.         
  14316.         if @subscription_type = 0 
  14317.           update MSmerge_replinfo set schemaversion=0, recgen = NULL, recguid=NULL, sentgen=NULL, sentguid = NULL
  14318.               where repid=@subid and schemaversion is NOT NULL
  14319.         else
  14320.              update MSmerge_replinfo set schemaversion= -1, recgen = NULL, recguid=NULL, sentgen=NULL, sentguid = NULL
  14321.                  where repid=@subid and schemaversion is NOT NULL
  14322.             -- 0 for push and -1 for pull
  14323.         exec @distproc @publisher, @publisher_db, @pubname, @subname, @subdb, 1
  14324.         if @@ERROR<>0
  14325.             BEGIN
  14326.                 goto Failure
  14327.             END            
  14328.         fetch next from SYN_CUR into @subid, @subscription_type, @publisher, @publisher_db, @pubname, @subsrvid, @subdb
  14329.     END
  14330.     close SYN_CUR
  14331.     deallocate SYN_CUR
  14332.     commit TRAN
  14333.     return (0)
  14334. Failure:
  14335.     close SYN_CUR
  14336.     deallocate SYN_CUR
  14337.     
  14338.     if @@TRANCOUNT = 1 
  14339.         ROLLBACK TRAN 
  14340.     else
  14341.         COMMIT TRAN
  14342.     return (1)
  14343.  
  14344. GO
  14345.  
  14346. grant execute on dbo.sp_reinitmergesubscription to public
  14347. go
  14348.  
  14349. --------------------------------------------------------------------------------
  14350. --. sp_MSpublicationview
  14351. --------------------------------------------------------------------------------
  14352. if exists (select * from sysobjects    where type = 'P'
  14353.     and name = 'sp_MSpublicationview')
  14354.     drop procedure sp_MSpublicationview
  14355. go
  14356.  
  14357. raiserror('Creating procedure sp_MSpublicationview', 0,1)
  14358. go
  14359.  
  14360. CREATE PROCEDURE sp_MSpublicationview(
  14361.     @publication sysname,
  14362.     @force_flag int = 0
  14363.     ) AS
  14364.     declare     @pubid              uniqueidentifier
  14365.     declare     @artid              uniqueidentifier
  14366.     declare     @join_articlename       nvarchar(270)
  14367.     declare     @join_viewname      nvarchar(270)
  14368.     declare        @join_before_view    sysname
  14369.     declare        @before_name        sysname
  14370.     declare        @before_viewname    sysname
  14371.     declare        @unqual_sourcename    sysname
  14372.     declare     @article            sysname
  14373.     declare     @art_nick           int
  14374.     declare     @join_nick          int
  14375.     declare     @join_filterclause  nvarchar(4000)
  14376.     declare     @bool_filterclause  nvarchar(4000)
  14377.     declare     @view_rule          nvarchar(4000)
  14378.     declare        @before_view_rule    nvarchar(4000)
  14379.     declare        @before_objid        int
  14380.     declare     @article_level      int
  14381.     declare     @progress           int
  14382.     declare     @art                int
  14383.     declare     @viewname           nvarchar(270)
  14384.     declare     @procname           nvarchar(290)
  14385.     declare     @source_objid       int
  14386.     declare     @source_object      nvarchar(258)
  14387.     declare     @sync_objid         int
  14388.     declare     @permanent          int
  14389.     declare     @temporary          int
  14390.     declare     @filter_id          int
  14391.     declare     @filter_id_str      nvarchar(10)
  14392.     declare     @guidstr nvarchar(40)
  14393.     declare     @pubidstr nvarchar(40)
  14394.     declare     @rgcol              sysname
  14395.     declare     @view_type          int
  14396.     declare     @belongsname        sysname
  14397.     declare     @join_nickstr       nvarchar(10)
  14398.     declare     @unqual_jointable   sysname  
  14399.     declare     @retcode            smallint
  14400.     declare     @hasguid            int
  14401.     declare     @join_unique_key    int
  14402.     declare     @simple_join_view   int
  14403.     declare     @join_filterid      int
  14404.     declare     @allhaveguids       int
  14405.     declare     @command            nvarchar(4000)
  14406.     declare     @objid              int
  14407.     declare     @owner              sysname
  14408.     declare        @table                sysname
  14409.     declare     @quoted_view        nvarchar(290)
  14410.     declare     @quoted_pub         nvarchar(290)
  14411.     declare     @quoted_proc        nvarchar(290)
  14412.     declare     @snapshot_ready        int
  14413.     
  14414.     set @progress       = 1
  14415.     set @article_level  = 0
  14416.     set @permanent      = 1
  14417.     set @temporary      = 2
  14418.     set @allhaveguids   = 1
  14419.     /*
  14420.     ** Only legal publisher can run this stored procedure
  14421.     */
  14422.     if not exists (select * from sysobjects where name = 'sysmergepublications')
  14423.         BEGIN
  14424.             RAISERROR (20054, 16, -1)
  14425.             RETURN (1)
  14426.         END
  14427.  
  14428.     select @pubid = pubid, @snapshot_ready = snapshot_ready FROM sysmergepublications 
  14429.         WHERE name = @publication and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name() 
  14430.     IF @pubid IS NULL
  14431.         BEGIN
  14432.             RAISERROR (20026, 11, -1, @publication)
  14433.             RETURN (1)
  14434.         END
  14435.  
  14436.     -- If snapshot is already ready, views are good.  Don't drop and recreate as someone
  14437.     -- might be using them.
  14438.     
  14439.     if @snapshot_ready = 1 and @force_flag = 0
  14440.         return (0)
  14441.         
  14442.     exec @retcode = dbo.sp_MSguidtostr @pubid, @pubidstr out
  14443.     if @@ERROR <>0 OR @retcode <>0 return (1)
  14444.  
  14445.     create table #art(indexcol int identity NOT NULL, art_nick int NOT NULL, article_level int NOT NULL)
  14446.     if @@ERROR <> 0
  14447.         begin
  14448.         goto FAILURE
  14449.         end
  14450.  
  14451.     while @progress > 0
  14452.         BEGIN
  14453.         /*
  14454.         ** Select articles that have either a boolean_filter or atleast one join filter 
  14455.         ** into a temp table in an optimized order.
  14456.         */
  14457.         insert into #art(art_nick, article_level) select nickname, @article_level from sysmergearticles 
  14458.             where pubid=@pubid and nickname not in (select art_nick from #art)
  14459.                 and nickname not in 
  14460.                 (select  art_nickname from sysmergesubsetfilters
  14461.                     where pubid=@pubid and join_nickname not in 
  14462.                         (select art_nick from #art))
  14463.         /*
  14464.         ** NOTENOTE: add error checking here.
  14465.         */
  14466.  
  14467.         set @progress = @@rowcount
  14468.         select @article_level = @article_level + 1
  14469.         END
  14470.  
  14471.     /* Drop the old views and reset sync_objid */
  14472.     select @art_nick = min(nickname) from sysmergearticles where pubid = @pubid and sync_objid <> objid
  14473.     while @art_nick is not null
  14474.         begin
  14475.         /* Drop the old view */
  14476.         select @viewname = OBJECT_NAME (sync_objid), @before_viewname = OBJECT_NAME(before_view_objid) from sysmergearticles where
  14477.             pubid = @pubid and nickname = @art_nick
  14478.         if @viewname IS NOT NULL
  14479.         begin
  14480.             select @quoted_view = QUOTENAME(@viewname)
  14481.             exec ('drop view ' + @quoted_view)
  14482.         end
  14483.         if @before_viewname IS NOT NULL
  14484.         begin
  14485.             exec ('drop view ' + @before_viewname)
  14486.         end
  14487.        
  14488.         /* Update the row in sysmergearticles */
  14489.         update sysmergearticles set view_type = 0, sync_objid = objid where 
  14490.             pubid = @pubid and nickname = @art_nick
  14491.         if @@ERROR <> 0 goto FAILURE
  14492.  
  14493.         /* Find the next one */
  14494.         select @art_nick = min(nickname) from sysmergearticles where pubid = @pubid and sync_objid <> objid
  14495.         end
  14496.         
  14497.     set @art = 0
  14498.     select @art=min(indexcol) from #art where indexcol>@art
  14499.  
  14500.     while (@art is not null)
  14501.         begin
  14502.         select @art_nick=art_nick, @article_level = article_level from #art 
  14503.                 where indexcol = @art
  14504.         select @article = name, @artid = artid,  @source_objid = objid,
  14505.             @sync_objid = sync_objid, @procname = view_sel_proc, @before_objid = before_image_objid from sysmergearticles 
  14506.                 where nickname=@art_nick and pubid = @pubid
  14507.  
  14508.           set @before_name = OBJECT_NAME(@before_objid)
  14509.         if @before_name is not null
  14510.             begin
  14511.             exec @retcode = dbo.sp_MSguidtostr @pubid, @guidstr out
  14512.             set @before_viewname = @before_name + '_v_' + @guidstr
  14513.             end
  14514.         else
  14515.             set @before_viewname = NULL
  14516.           select @quoted_proc = QUOTENAME(@procname)
  14517.         
  14518.         exec @retcode = dbo.sp_MSguidtostr @artid, @guidstr out
  14519.         if @@ERROR <>0 OR @retcode <>0 return (1)
  14520.  
  14521.         select @source_object = QUOTENAME(user_name(uid)) + '.' + QUOTENAME(name) from sysobjects 
  14522.                 where id = @source_objid 
  14523.         select @unqual_sourcename = QUOTENAME(OBJECT_NAME(@source_objid))
  14524.         select @bool_filterclause=subset_filterclause from sysmergearticles 
  14525.                 where name = @article and pubid = @pubid
  14526.                 
  14527.         set @rgcol = NULL
  14528.         select @rgcol = QUOTENAME(name) from syscolumns where id = @source_objid and
  14529.                 ColumnProperty(id, name, 'isrowguidcol') = 1
  14530.         if @rgcol is not NULL
  14531.             set @hasguid = 1
  14532.         else 
  14533.             begin
  14534.             set @hasguid = 0
  14535.             set @allhaveguids = 0
  14536.             end
  14537.  
  14538.         /*
  14539.         ** Process non looping articles that have either a boolean or a join_filter.
  14540.         */
  14541.         if ( @article_level > 0 OR (len(@bool_filterclause) > 0) ) 
  14542.             begin
  14543.             /*
  14544.             ** If the article has a previously generated view, then drop the view before 
  14545.             ** creating the new one.
  14546.             */
  14547.             set @viewname = NULL
  14548.             select @viewname =  name from sysobjects where id = @sync_objid and
  14549.                 ObjectProperty (id, 'IsView') = 1  and
  14550.                 ObjectProperty (id, 'IsMSShipped') = 1 
  14551.             if @viewname IS NOT NULL
  14552.                 begin
  14553.                     select @quoted_view = QUOTENAME(@viewname)
  14554.                     exec ('drop view ' + @quoted_view)
  14555.                     if @@ERROR<>0 return (1)
  14556.                 end
  14557.                 /*
  14558.                 ** Any join filter(s)? If any, process join filter(s)
  14559.             */
  14560.             if (@article_level > 0) 
  14561.                 begin
  14562.                 declare pub1 CURSOR LOCAL FAST_FORWARD FOR select join_filterclause, join_nickname, join_articlename,
  14563.                     join_unique_key, join_filterid from sysmergesubsetfilters where pubid=@pubid and artid=@artid
  14564.                 FOR READ ONLY
  14565.                 open pub1                                       
  14566.                 fetch pub1 into @join_filterclause, @join_nick, @join_articlename, @join_unique_key, @join_filterid
  14567.  
  14568.                 select @unqual_jointable = QUOTENAME(name) from sysobjects 
  14569.                     where id = (select objid from sysmergearticles where name=@join_articlename and pubid=@pubid) 
  14570.                 
  14571.                 select @join_viewname = object_name(sync_objid), @join_before_view = object_name(before_image_objid)
  14572.                     from sysmergearticles where nickname = @join_nick and pubid = @pubid
  14573.                 select @join_viewname = QUOTENAME(@join_viewname)
  14574.  
  14575.                 if (@join_unique_key = 1 and (@bool_filterclause is null or len(@bool_filterclause) = 0) and
  14576.                     not exists (select * from sysmergesubsetfilters where pubid=@pubid and artid=@artid and join_filterid <> @join_filterid))
  14577.                     begin
  14578.                     set @simple_join_view = 1
  14579.                     set @view_rule = 'select ' + @source_object + '.* from ' + @source_object + ', ' +  @join_viewname + ' ' + @unqual_jointable + ' where ' + @join_filterclause
  14580.                     end
  14581.                 else
  14582.                     begin
  14583.                     set @simple_join_view = 0
  14584.                     set @view_rule = 'select ' + @source_object + '.rowguidcol from ' + @source_object + ', ' +  @join_viewname + ' ' + @unqual_jointable + ' where ' + @join_filterclause
  14585.                     end
  14586.                 if @before_name is not null
  14587.                     begin
  14588.                     set @before_view_rule = 'select * from ' + @before_name + ' ' +  @unqual_sourcename + ' where exists (select * from ' +
  14589.                             @join_viewname + ' ' + @unqual_jointable + ' where ' + @join_filterclause + ') or exists (select * from ' +
  14590.                             @join_before_view + ' ' + @unqual_jointable + ' where ' + @join_filterclause + ') '
  14591.                     end
  14592.                 fetch next from pub1 into @join_filterclause, @join_nick, @join_articlename, @join_unique_key, @join_filterid
  14593.                 WHILE (@@fetch_status <> -1)
  14594.                     begin
  14595.                     select @unqual_jointable = name from sysobjects 
  14596.                         where id = ( select objid from sysmergearticles where name=@join_articlename and pubid=@pubid) 
  14597.                 
  14598.                     select @join_viewname = object_name(sync_objid), @join_before_view = object_name(before_image_objid)
  14599.                         from sysmergearticles where nickname = @join_nick and pubid = @pubid
  14600.                     select @join_viewname = QUOTENAME(@join_viewname)
  14601.                     set @view_rule = @view_rule + ' union select ' + @source_object + '.rowguidcol from ' + @source_object + ', ' +  @join_viewname + ' ' + @unqual_jointable + ' where ' + @join_filterclause
  14602.                        if @before_name is not null
  14603.                         set @before_view_rule = @before_view_rule + ' or exists (select * from ' +
  14604.                             @join_viewname + ' ' + @unqual_jointable + ' where ' + @join_filterclause + ') or exists (select * from ' +
  14605.                             @join_before_view + ' ' + @unqual_jointable + ' where ' + @join_filterclause + ') '
  14606.  
  14607.                     fetch next from pub1 into @join_filterclause, @join_nick, @join_articlename, @join_unique_key, @join_filterid
  14608.                     end 
  14609.                 close pub1
  14610.                 deallocate pub1
  14611.                         
  14612.                 if len(@bool_filterclause) > 0
  14613.                     begin
  14614.                     set @view_rule = @view_rule + ' union select ' + @source_object + '.rowguidcol from '+ @source_object + ' where '+ @bool_filterclause
  14615.                     if @before_name is not null
  14616.                         set @before_view_rule = @before_view_rule + ' or ' + @bool_filterclause
  14617.                     end
  14618.  
  14619.                 -- Now do the actual view rule as a semi-join, if not a simple join on unique key
  14620.                 if (@simple_join_view = 0)
  14621.                     set @view_rule = 'select * from ' + @source_object + ' where rowguidcol in (' + @view_rule + ')'
  14622.                 end
  14623.             else  /* boolean filter only */
  14624.                 begin
  14625.                 select @view_rule = ' select *  from '+ @source_object + ' where '+ @bool_filterclause
  14626.                 if @before_name is not null
  14627.                     set @before_view_rule = ' select * from ' + @before_name + ' ' + @unqual_sourcename + ' where ' + @bool_filterclause
  14628.                 end
  14629.                             
  14630.             select @viewname = @publication + '_' + @article + '_VIEW'
  14631.             exec @retcode = dbo.sp_MSuniqueobjectname @viewname , @viewname output
  14632.             select @quoted_view = QUOTENAME(@viewname)
  14633.             
  14634.             if @retcode <> 0 or @@ERROR <> 0 return (1) 
  14635.             /* If we havent generated rowguidcol yet, use dummy rule that doesnt refer to it */
  14636.             if @hasguid = 0
  14637.                 set @view_rule = ' select * from '+ @source_object
  14638.             exec ('create view '+ @quoted_view + ' as '+ @view_rule)
  14639.             /* Mark view as system object */                        
  14640.             execute ('sp_MS_marksystemobject ' + @quoted_view)
  14641.             if @hasguid = 1
  14642.                 begin
  14643.                 if @procname is not null
  14644.                     begin
  14645.                     exec ('drop procedure ' + @quoted_proc)
  14646.                     end
  14647.                 else
  14648.                     begin
  14649.                     set @procname = 'sel_' + substring(@guidstr, 1, 16) + substring(@pubidstr, 1, 16)
  14650.                     exec @retcode = dbo.sp_MSuniqueobjectname @procname , @procname output
  14651.                     if @retcode <> 0 or @@ERROR <> 0
  14652.                             return (1)
  14653.                     end
  14654.                 select @owner = user_name(uid) from sysobjects 
  14655.                     where name = @viewname 
  14656.                 exec dbo.sp_MSmakeviewproc @viewname, @owner, @procname, @rgcol, @source_objid
  14657.                 end
  14658.             update sysmergearticles set sync_objid = OBJECT_ID (@viewname), view_type = @permanent,
  14659.                 view_sel_proc = @procname where artid = @artid and pubid = @pubid 
  14660.             if @before_name is not null
  14661.                 begin
  14662.                 exec @retcode = sp_MScreatebeforetable @source_objid
  14663.                 if @retcode <> 0 or @@ERROR <> 0 return (1) 
  14664.                 exec ('create view ' + @before_viewname + ' as ' + @before_view_rule)
  14665.                 execute sp_MS_marksystemobject @before_viewname
  14666.                 update sysmergearticles set before_view_objid = OBJECT_ID (@before_viewname)
  14667.                     where artid = @artid and pubid = @pubid
  14668.                 end
  14669.  
  14670.             end /* end of view creation for this article */
  14671.         else if @procname is null and @hasguid = 1
  14672.             begin
  14673.             /* still make the select proc, although it selects directly from table */
  14674.  
  14675.             set @procname = 'sel_' + substring(@guidstr, 1, 16) + substring(@pubidstr, 1, 16)
  14676.             exec @retcode = dbo.sp_MSuniqueobjectname @procname , @procname output
  14677.             if @retcode <> 0 or @@ERROR <> 0 return (1) 
  14678.             select @owner = user_name(uid), @viewname = name from sysobjects 
  14679.                 where id = @source_objid 
  14680.             exec dbo.sp_MSmakeviewproc @viewname, @owner, @procname, @rgcol, @source_objid
  14681.             update sysmergearticles set view_sel_proc = @procname
  14682.                 where artid = @artid and pubid = @pubid 
  14683.  
  14684.             end
  14685.         
  14686.         select @art=min(indexcol) from #art where indexcol>@art
  14687.         end
  14688.  
  14689.     /* If there are looping articles, we must use a dynamic publication since no views on temp tables */
  14690.     update sysmergearticles set view_type = @temporary
  14691.         where pubid=@pubid and nickname not in (select art_nick from #art)
  14692.     if @@rowcount > 0
  14693.         begin
  14694.         if not exists (select * from sysmergepublications where dynamic_filters = 1 and pubid = @pubid)
  14695.             begin
  14696.             declare @repl_nick int
  14697.             /* treat these articles as if the publication were dynamic */
  14698.             execute @retcode = dbo.sp_MSgetreplnick @nickname = @repl_nick output
  14699.             if (@@error <> 0) or @retcode <> 0 or @repl_nick IS NULL 
  14700.                 begin
  14701.                 RAISERROR (14055, 11, -1)
  14702.                 RETURN(1)
  14703.                 end                 
  14704.  
  14705.             select @art_nick = min(nickname) from sysmergearticles where
  14706.                 pubid = @pubid and view_type = @temporary
  14707.             while @art_nick is not null
  14708.                 begin
  14709.                 /* Loop over articles with circular filters.  Create dummy view and add rows to contents */
  14710.                 select @article = name, @artid = artid, @source_objid = objid, @sync_objid = sync_objid, @procname = view_sel_proc from sysmergearticles 
  14711.                     where nickname=@art_nick and pubid = @pubid
  14712.                 select @source_object = QUOTENAME(user_name(uid)) + '.' + QUOTENAME(name) from sysobjects 
  14713.                     where id = @source_objid 
  14714.  
  14715.                 set @viewname = NULL
  14716.                 select @viewname =  name from sysobjects where id = @sync_objid and
  14717.                     ObjectProperty (id, 'IsView') = 1  and
  14718.                     ObjectProperty (id, 'IsMSShipped') = 1 
  14719.                 if @viewname IS NOT NULL
  14720.                     begin
  14721.                         select @quoted_view = QUOTENAME(@viewname)
  14722.                         exec ('drop view ' + @quoted_view)
  14723.                         if @@ERROR<>0 return (1)
  14724.                     end
  14725.                 select @viewname = 'SYNC_' + @publication + '_' + @article 
  14726.                 exec @retcode = dbo.sp_MSuniqueobjectname @viewname , @viewname output
  14727.                 if @retcode <> 0 or @@ERROR <> 0 return (1) 
  14728.                 select @quoted_view = QUOTENAME(@viewname)
  14729.                 exec ('create view ' + @quoted_view + ' as select * from ' + @source_object + ' 
  14730.                         where 1 = 0 ')
  14731.                 if @@ERROR<>0 return (1)
  14732.                 update sysmergearticles set sync_objid = OBJECT_ID (@viewname),
  14733.                     view_sel_proc = NULL where artid = @artid and pubid = @pubid 
  14734.                 if @@ERROR<>0 return (1)
  14735.  
  14736.                 select @owner = user_name(uid) from sysobjects where id = @source_objid
  14737.                 set @table = OBJECT_NAME(@source_objid)
  14738.                 exec @retcode = dbo.sp_addtabletocontents @table, @owner
  14739.                 IF @@ERROR <> 0 or @retcode <> 0 return (1)
  14740.                 
  14741.                 select @art_nick = min(nickname) from sysmergearticles where
  14742.                     pubid = @pubid and view_type = @temporary and nickname > @art_nick
  14743.                 end
  14744.             end
  14745.         end
  14746.         
  14747.     drop table #art
  14748.     if @allhaveguids = 1
  14749.         begin
  14750.         declare @dbname sysname
  14751.         set @dbname = db_name()
  14752.         /* create the filter expand procs now */
  14753.         set @filter_id = 0
  14754.         select @filter_id = min(join_filterid) from sysmergesubsetfilters where
  14755.                 pubid = @pubid and join_filterid > @filter_id
  14756.         while @filter_id is not null
  14757.             begin
  14758.             set @filter_id_str = convert(nvarchar(10), @filter_id)
  14759.             select @procname = expand_proc
  14760.                 from sysmergesubsetfilters where pubid = @pubid and join_filterid = @filter_id
  14761.             /* drop old proc, or generate a new procname */
  14762.             select @quoted_proc = QUOTENAME(@procname)
  14763.             if @procname is not null
  14764.                 exec ('drop procedure ' + @quoted_proc)
  14765.             else
  14766.                 begin
  14767.                 set @procname = 'expand_' + @filter_id_str
  14768.                 exec @retcode = dbo.sp_MSuniqueobjectname @procname, @procname output
  14769.                 if @retcode <>0 return (1)
  14770.                 update sysmergesubsetfilters set expand_proc = @procname where  pubid = @pubid and join_filterid = @filter_id
  14771.                 end
  14772.             select @quoted_proc = QUOTENAME(@procname)
  14773.             select @quoted_pub = QUOTENAME(@publication)
  14774.             set @command = 'exec dbo.sp_MSmakeexpandproc ' + @quoted_pub + ' , ' + @filter_id_str + ', ' + @quoted_proc
  14775.             exec @retcode = master..xp_execresultset @command, @dbname
  14776.             if @retcode <> 0 return (1)
  14777.             exec dbo.sp_MS_marksystemobject @quoted_proc
  14778.             exec ('grant execute on ' + @quoted_proc + ' to public ')
  14779.             select @filter_id = min(join_filterid) from sysmergesubsetfilters where
  14780.                 pubid = @pubid and join_filterid > @filter_id
  14781.             end
  14782.         end
  14783.  
  14784.     return (0)
  14785.  
  14786. FAILURE: 
  14787.     return (1)
  14788. go
  14789.  
  14790. grant execute on dbo.sp_MSpublicationview to public
  14791. go
  14792.  
  14793. --------------------------------------------------------------------------------
  14794. --. sp_addmergesubscription
  14795. --------------------------------------------------------------------------------
  14796. if exists (select * from sysobjects    where type = 'P'
  14797.     and name = 'sp_addmergesubscription')
  14798.     drop procedure sp_addmergesubscription
  14799. go
  14800.  
  14801. raiserror('Creating procedure sp_addmergesubscription', 0,1)
  14802. go
  14803.  
  14804. CREATE PROCEDURE sp_addmergesubscription (
  14805.     @publication                    sysname,                    /* Publication name */
  14806.     @subscriber                     sysname = NULL,             /* Subscriber server */
  14807.     @subscriber_db                  sysname = NULL,             /* Subscription database */
  14808.     @subscription_type              nvarchar(15) = 'push',          /* Subscription type - push, pull */ 
  14809.     @subscriber_type                nvarchar(15) = 'local',         /* Subscriber type */ 
  14810.     @subscription_priority          real        = NULL,             /* Subscription priority */
  14811.     @sync_type                      nvarchar(15) = 'automatic',     /* subscription sync type */
  14812.     @frequency_type                 int = NULL,            
  14813.     @frequency_interval             int = NULL,        
  14814.     @frequency_relative_interval    int = NULL,
  14815.     @frequency_recurrence_factor    int = NULL,
  14816.     @frequency_subday               int = NULL,            
  14817.     @frequency_subday_interval      int = NULL,
  14818.     @active_start_time_of_day       int = NULL,
  14819.     @active_end_time_of_day         int = NULL,
  14820.     @active_start_date              int = NULL,
  14821.     @active_end_date                int = NULL,
  14822.     @optional_command_line          nvarchar(4000) = NULL,
  14823.     @description                    nvarchar(255) = NULL,
  14824.     @enabled_for_syncmgr            nvarchar(5) = 'false' /* Enabled for SYNCMGR: true or false */
  14825.     ) AS
  14826.  
  14827.     SET NOCOUNT ON
  14828.  
  14829.     /*
  14830.     ** Declarations.
  14831.     */
  14832.     declare @retcode                int
  14833.     declare @subnickname            int
  14834.     declare @subscriber_srvid       int 
  14835.     declare @publisher_srvid        int 
  14836.     declare @priority               real
  14837.     declare @subid                  uniqueidentifier
  14838.     declare @pubid                  uniqueidentifier    /* Publication id */
  14839.     declare @subscriber_typeid      smallint
  14840.     declare @merge_jobid            binary(16)          /* Scheduler jobid for the merge agent */
  14841.     declare @subscription_type_id   int   
  14842.     declare @distproc               nvarchar(255)
  14843.     declare @command                nvarchar(255)
  14844.     declare @inactive               tinyint
  14845.     declare @subscriber_bit         smallint
  14846.     declare @global                 tinyint     /* subscriber type is global */
  14847.     declare @push                   tinyint     /* subscription type is push */
  14848.     declare @partnerid              uniqueidentifier    /* Partner replica identifier */
  14849.     declare @sync_typeid            tinyint
  14850.     declare @nosync                 tinyint     
  14851.     declare @automatic              tinyint     
  14852.     declare @distributor            sysname
  14853.     declare @distribdb              sysname
  14854.     declare @active                 tinyint
  14855.     declare @publisher              sysname
  14856.     declare @publisher_db           sysname
  14857.     declare @found                  int
  14858.     declare @datasource_type        int
  14859.     declare @datasource_path        sysname
  14860.     DECLARE @platform_nt            binary
  14861.     declare @is_jet                    int
  14862.     declare @Jet_datasource_path    sysname
  14863.     declare @datasrctype            int
  14864.     declare @datasrcpath            sysname
  14865.  
  14866.     
  14867.     /*
  14868.     ** Initializations.
  14869.     */
  14870.     set @datasource_type = 0    /* Default SQL Server */
  14871.     set @datasource_path = NULL 
  14872.     set @datasrctype = 0    /* Default SQL Server */
  14873.     set @datasrcpath = NULL 
  14874.     set @platform_nt = 0x1  
  14875.     SET @nosync             = 2       /* Const: synchronization type 'nosync' */
  14876.     SET @automatic          = 1       /* Const: synchronization type 'automatic' */
  14877.     set @inactive           = 0
  14878.     SET @subscriber_bit     = 4  
  14879.     set @global             = 1
  14880.     set @push               = 0
  14881.     set @pubid              = NULL         
  14882.     set @active             = 1     /* Const: subscription status 'active', 0 for pull subscriptions at publisher side */
  14883.     set @publisher          = @@SERVERNAME
  14884.     set @publisher_db       = DB_NAME()
  14885.     select @found           = 1    /* Any non-NULL value is fine */
  14886.     /*
  14887.     ** Parameter Check: @subscription_type.
  14888.     ** Set subscriber_typeid based on the @subscription_type specified.
  14889.     **
  14890.     **   subscription_type    subscription_type
  14891.     **   =================    ===============
  14892.     **             0            push
  14893.     **             1            pull
  14894.     */
  14895.     if LOWER(@subscription_type) NOT IN ('push', 'pull')
  14896.         BEGIN
  14897.             RAISERROR (14128, 16, -1)
  14898.             RETURN (1)
  14899.         END
  14900.     IF LOWER(@subscription_type) = 'push'
  14901.         set @subscription_type_id = 0
  14902.     else 
  14903.         set @subscription_type_id = 1
  14904.  
  14905.     /*
  14906.     ** Security Check.
  14907.     */
  14908.  
  14909.     IF @subscription_type_id = 0 
  14910.     BEGIN
  14911.         exec @retcode = dbo.sp_MSreplcheck_publish
  14912.         if @@ERROR <> 0 or @retcode <> 0
  14913.             return(1)
  14914.     END
  14915.     ELSE
  14916.     BEGIN
  14917.         exec @retcode = dbo.sp_MSreplcheck_pull @publication
  14918.         if @@ERROR <> 0 or @retcode <> 0
  14919.             return(1)
  14920.     END
  14921.  
  14922.     /* This SP is called through UI with a subscription_type = pull; in this scenario
  14923.     ** the status of the subscription is inactive before merge agent is run
  14924.     */
  14925.     
  14926.     if @subscription_type_id = 1 
  14927.         select @active = 0
  14928.  
  14929.  
  14930.     /*
  14931.     ** Validate that the publisher is a valid server
  14932.     */
  14933.     select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  14934.     IF @publisher_srvid IS NULL
  14935.         BEGIN
  14936.             RAISERROR (14010, 16, -1)
  14937.             RETURN (1)
  14938.         END
  14939.  
  14940.     /*
  14941.     ** Parameter Check: @subscriber
  14942.     ** Check to make sure that the subscriber is defined
  14943.     */
  14944.     IF @subscriber IS NULL
  14945.         BEGIN
  14946.             RAISERROR (14043, 16, -1, '@subscriber')
  14947.             RETURN (1)
  14948.         END
  14949.  
  14950.      IF NOT EXISTS (SELECT * FROM master..sysservers WHERE UPPER(srvname) = UPPER(@subscriber)
  14951.                      AND (srvstatus & @subscriber_bit) <> 0)
  14952.                BEGIN
  14953.                    RAISERROR (14010, 16, -1)
  14954.                    RETURN (1)
  14955.                END
  14956.  
  14957.     IF @subscriber = 'all'
  14958.         BEGIN
  14959.             RAISERROR (14136, 16, -1)
  14960.             RETURN (1)
  14961.         END
  14962.  
  14963.     /*
  14964.     ** Get distribution server information for remote RPC call.
  14965.     */
  14966.     EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  14967.          @distribdb   = @distribdb OUTPUT
  14968.     IF @@ERROR <> 0 or @retcode <> 0
  14969.         BEGIN
  14970.         GOTO FAILURE
  14971.         END
  14972.  
  14973.         SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + 
  14974.             '.dbo.sp_MShelp_subscriber_info '
  14975.     exec @distproc @publisher, @subscriber, @found output
  14976.     if (@found <> 1) 
  14977.         BEGIN
  14978.             RAISERROR (14085, 16, -1)
  14979.             RETURN (1)
  14980.         END
  14981.  
  14982.     select @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '.dbo.sp_MScheck_Jet_Subscriber '
  14983.     exec @retcode = @distproc @subscriber, @is_jet OUTPUT, @Jet_datasource_path OUTPUT
  14984.     if @retcode<>0
  14985.         return (1)
  14986.     
  14987.     IF @is_jet = 1
  14988.     BEGIN
  14989.         select @datasource_type = 2
  14990.         select @datasource_path = @Jet_datasource_path
  14991.     END
  14992.     ELSE
  14993.     BEGIN
  14994.         exec @retcode = dbo.sp_MSget_subtypedatasrc @subscriber, @distributor, @distribdb, @datasrctype OUTPUT, @datasrcpath OUTPUT
  14995.         if @retcode<>0
  14996.             return (1)
  14997.         if (@datasrctype = 4) or (@datasrctype = 5)
  14998.         BEGIN
  14999.             select @datasource_type = @datasrctype
  15000.             select @datasource_path = @datasrcpath
  15001.         END
  15002.     END
  15003.  
  15004.     EXECUTE @retcode = dbo.sp_validname @subscriber
  15005.     IF @@ERROR <> 0 OR @retcode <> 0
  15006.        RETURN (1)
  15007.  
  15008.     /*
  15009.     ** Parameter Check: @subscriber_db
  15010.     */
  15011.     IF @subscriber_db IS NULL
  15012.     BEGIN
  15013.         RAISERROR (14043, 16, -1, '@subscriber_db')
  15014.         RETURN (1)
  15015.     END
  15016.  
  15017.     IF @subscriber_db = 'all'
  15018.     BEGIN
  15019.         RAISERROR (14136, 16, -1)
  15020.         RETURN (1)
  15021.     END
  15022.  
  15023.     /*
  15024.     **  Check to see if system tables exist. If not create them. Since under current
  15025.     **  design every database is qualified for subscribing.
  15026.     */
  15027.     
  15028.     IF not exists (select name from sysobjects where name='sysmergesubscriptions')
  15029.         BEGIN
  15030.             execute @retcode = dbo.sp_MScreate_mergesystables
  15031.                 if @@ERROR <> 0 or @retcode <> 0
  15032.                     begin
  15033.                         return (1)
  15034.                     end
  15035.         END 
  15036.         
  15037.     /*
  15038.     ** Parameter Check: @publication.
  15039.     ** Check to make sure that the publication exists and that it conforms
  15040.     ** to the rules for identifiers.
  15041.     */
  15042.     if NOT EXISTS (select * FROM sysmergepublications 
  15043.         WHERE name = @publication and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name())
  15044.         BEGIN
  15045.             RAISERROR (20026, 16, -1, @publication)
  15046.             RETURN (1)
  15047.         END
  15048.  
  15049.     if @pubid IS NULL
  15050.         select @pubid = pubid FROM sysmergepublications 
  15051.             WHERE name = @publication and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name()
  15052.     if @partnerid IS NULL
  15053.         begin
  15054.             select @partnerid = subid FROM sysmergesubscriptions 
  15055.                 WHERE srvid = @publisher_srvid and db_name = @publisher_db and pubid = @pubid
  15056.         end                     
  15057.  
  15058.     /*
  15059.     ** Parameter Check: @subscriber_type.
  15060.     ** Set subscriber_typeid based on the @subscriber_type specified.
  15061.     **
  15062.     **   subscriber_type     subscriber_type
  15063.     **   =================    ===============
  15064.     **             1            global
  15065.     **             2            local
  15066.     **             3            anonymous
  15067.     **                          Type 'republisher' is taken out for B3. We may want to add this back later.
  15068.     */
  15069.     if LOWER(@subscriber_type) NOT IN ('local', 'global', 'anonymous')
  15070.         BEGIN
  15071.             RAISERROR (20023, 16, -1)
  15072.             RETURN (1)
  15073.         END
  15074.  
  15075.     if LOWER(@subscriber_type) IN ('global')
  15076.         set @subscriber_typeid = 1
  15077.     else if LOWER(@subscriber_type) IN ('local')
  15078.         set @subscriber_typeid = 2
  15079.     else if LOWER(@subscriber_type) IN ('anonymous')       
  15080.         set @subscriber_typeid = 3
  15081.  
  15082.     /* Do not allow anonymous for a PUSH subscription */
  15083.     if @subscriber_typeid = 3 and @subscription_type_id = 0
  15084.         BEGIN
  15085.             RAISERROR (20087, 16, -1)
  15086.             RETURN (1)
  15087.         END
  15088.     
  15089.     /* 
  15090.     ** Assign priority appropriately - choose 0.99 times the minimum priority
  15091.     ** of the global replicas.
  15092.     */
  15093.     if (@subscription_priority >= 100.0 or @subscription_priority < 0.0)
  15094.         BEGIN
  15095.             RAISERROR (20088, 16, -1)
  15096.             RETURN (1)
  15097.         END
  15098.     if (@subscription_priority IS NULL)
  15099.         begin
  15100.             select @priority = 0.99 * min(priority) from sysmergesubscriptions where subscriber_type = 1
  15101.             if (@priority IS NOT NULL)
  15102.                 select @subscription_priority = @priority
  15103.             if (@subscription_priority IS NULL) 
  15104.                 select @subscription_priority = 0.0
  15105.         end
  15106.     /*
  15107.     ** For local and anonymous subscriptions the priority is 0.0
  15108.     */
  15109.     if LOWER(@subscriber_type) IN ('local', 'anonymous')
  15110.         select @subscription_priority = 0.0
  15111.     
  15112.     /*
  15113.     ** Validate that the subscriber is a valid server
  15114.     */
  15115.     select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  15116.     IF @subscriber_srvid IS NULL
  15117.         BEGIN
  15118.             RAISERROR (14010, 16, -1)
  15119.             RETURN (1)
  15120.         END
  15121.  
  15122.     IF exists (select * from sysobjects where name= 'syssubscriptions')
  15123.     begin
  15124.         if exists (select name from sysmergearticles where pubid=@pubid and objid in
  15125.             (select objid from sysarticles where artid in
  15126.                 (select artid from syssubscriptions where dest_db=@subscriber_db and srvid=@subscriber_srvid)))
  15127.         begin
  15128.             RAISERROR(20084, 16, -1, @publication, @subscriber_db)
  15129.             RETURN (1)
  15130.         end
  15131.     end
  15132.  
  15133.     /*
  15134.     ** Making it possible for a deleted subscription to come back.
  15135.     ** UNDONE : This disallows second pull subscription from being added unless the previous 
  15136.     ** subscription was initial synced.
  15137.     */
  15138.     if EXISTS (select db_name, srvid
  15139.             FROM sysmergesubscriptions
  15140.             WHERE db_name = @subscriber_db
  15141.             AND srvid = @subscriber_srvid                          
  15142.             AND pubid = @pubid AND status <>2) --We can definitely add back subscriptions that were deleted.
  15143.         BEGIN
  15144.             RAISERROR (14058, 16, -1)
  15145.             RETURN (1)
  15146.         END
  15147.         
  15148.     IF EXISTS (select db_name, srvid FROM sysmergesubscriptions 
  15149.         WHERE db_name = @subscriber_db AND srvid = @subscriber_srvid AND pubid = @pubid AND status = 2) 
  15150.             BEGIN
  15151.                 select @subid = subid from sysmergesubscriptions 
  15152.                     WHERE db_name = @subscriber_db AND srvid = @subscriber_srvid AND pubid = @pubid
  15153.                 delete  from sysmergesubscriptions where subid = @subid
  15154.                 delete from MSmerge_replinfo where repid = @subid
  15155.             END
  15156.     select @subid = newid()    
  15157.     
  15158.    /*
  15159.    ** Parameter Check: @sync_type.
  15160.    ** Set sync_typeid based on the @sync_type specified.
  15161.    **
  15162.    **   sync_typeid     sync_type
  15163.    **   ===========     =========
  15164.    **             1     automatic
  15165.    **             2     nosync
  15166.    */
  15167.  
  15168.  
  15169.    IF LOWER(@sync_type) NOT IN ('automatic', 'none')
  15170.        BEGIN
  15171.            RAISERROR (14052, 16, -1)
  15172.            RETURN (1)
  15173.        END
  15174.  
  15175.  
  15176.     /*
  15177.     ** If current publication contains an article without rowguidcol, do not allow no-sync subscription
  15178.     */
  15179.    IF LOWER(@sync_type) = 'automatic'
  15180.    BEGIN
  15181.         SET @sync_typeid = @automatic
  15182.    END
  15183.    ELSE
  15184.    BEGIN
  15185.         if exists (select * from sysmergearticles a where pubid=@pubid and 
  15186.             not exists (select * from syscolumns c where c.id = a.objid and ColumnProperty(c.id, c.name, 'IsRowGuidCol') = 1))
  15187.             
  15188.             BEGIN
  15189.                 Raiserror(20086, 16, -1, @publication)
  15190.                 RETURN (1)
  15191.             END
  15192.         else 
  15193.             SET @sync_typeid = @nosync
  15194.    END
  15195.  
  15196.  
  15197.     /*
  15198.     ** UNDONE: Validate that the publisher is of type "republisher"
  15199.     */
  15200.     begin tran
  15201.     save TRAN addmergesubscription
  15202.         /* Generate a guid for the Subscriber ID */
  15203.     
  15204.         /* Look for existing nickname from any other subscription */
  15205.         exec @retcode = dbo.sp_MSgetreplnick @subscriber, @subscriber_db , NULL,  @subnickname out
  15206.         if (@@error <> 0) or @retcode <> 0 
  15207.             GOTO FAILURE
  15208.             
  15209.         /* Generate a new replica nickname from the @subid */
  15210.         if (@subnickname is null)
  15211.         begin
  15212.             EXECUTE dbo.sp_MSgenreplnickname @subid, @subnickname output
  15213.             if @@ERROR<>0 
  15214.                 GOTO FAILURE
  15215.         end
  15216.             
  15217.         /*
  15218.         ** The subscription doesn't exist, so let's add it to sysmergesubscriptions 
  15219.         */
  15220.         INSERT sysmergesubscriptions (subid, 
  15221.                                       partnerid,
  15222.                                       datasource_type, 
  15223.                                       datasource_path, 
  15224.                                       srvid, 
  15225.                                       db_name, 
  15226.                                       pubid,
  15227.                                       status, 
  15228.                                       subscriber_type,
  15229.                                       subscription_type,
  15230.                                       priority, 
  15231.                                       sync_type, 
  15232.                                       description,
  15233.                                       login_name)
  15234.                         VALUES (@subid,
  15235.                             @partnerid,
  15236.                             @datasource_type,
  15237.                             @datasource_path,
  15238.                             @subscriber_srvid,
  15239.                             @subscriber_db,
  15240.                             @pubid,
  15241.                             @active,
  15242.                             @subscriber_typeid,
  15243.                             @subscription_type_id,
  15244.                             @subscription_priority,
  15245.                             @sync_typeid,
  15246.                             @description,
  15247.                             suser_sname(suser_sid()))          
  15248.         if @@ERROR <> 0
  15249.             BEGIN
  15250.                 GOTO FAILURE
  15251.             END
  15252.                 
  15253.         /*
  15254.         ** Get distribution server information for remote RPC call.
  15255.         */
  15256.         EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  15257.            @distribdb   = @distribdb OUTPUT
  15258.         IF @@ERROR <> 0 or @retcode <> 0
  15259.             BEGIN
  15260.                 GOTO FAILURE
  15261.             END
  15262.  
  15263.         SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + 
  15264.             '.dbo.sp_MSadd_merge_subscription'
  15265.         EXEC @retcode = @distproc 
  15266.             @publisher = @@SERVERNAME, 
  15267.             @publisher_db = @publisher_db, 
  15268.             @publication = @publication,
  15269.             @subscriber = @subscriber, 
  15270.             @subscriber_db = @subscriber_db, 
  15271.             @subscription_type = @subscription_type_id,
  15272.             @sync_type = @sync_typeid, 
  15273.             @status = @active,
  15274.             @frequency_type = @frequency_type,
  15275.             @frequency_interval = @frequency_interval,
  15276.             @frequency_relative_interval = @frequency_relative_interval,
  15277.             @frequency_recurrence_factor = @frequency_recurrence_factor,
  15278.             @frequency_subday = @frequency_subday,
  15279.             @frequency_subday_interval = @frequency_subday_interval,
  15280.             @active_start_time_of_day = @active_start_time_of_day,
  15281.             @active_end_time_of_day = @active_end_time_of_day,
  15282.             @active_start_date = @active_start_date,
  15283.             @active_end_date = @active_end_date,
  15284.             @optional_command_line = @optional_command_line,
  15285.             @merge_jobid = @merge_jobid OUTPUT 
  15286.         IF @@ERROR <> 0 OR @retcode <> 0
  15287.             begin   
  15288.                 goto FAILURE
  15289.             end
  15290.             
  15291.         /*
  15292.         **  Add row for subscription in MSmerge_replinfo.
  15293.         */
  15294.         insert MSmerge_replinfo(repid, replnickname, merge_jobid)
  15295.                 values (@subid, @subnickname, @merge_jobid)
  15296.         if @@ERROR <> 0
  15297.             BEGIN
  15298.                 GOTO FAILURE
  15299.             END
  15300.  
  15301.         /* Conditional support for MobileSync */
  15302.         if LOWER(@enabled_for_syncmgr) = 'true'
  15303.         BEGIN
  15304.  
  15305.             /* MobileSync Support */
  15306.             declare @distributor_server                 sysname
  15307.             declare @distributor_security_mode          int
  15308.             declare @distributor_login                  sysname
  15309.             declare @distributor_password               sysname
  15310.  
  15311.             /* 
  15312.             ** The registry entry needs to be created only for push subscriptions -  
  15313.             ** i.e - need not be called when a pull subscription is created at the 
  15314.             ** subscriber and sp_addmergesubscription is being called then.
  15315.             */
  15316.             
  15317.             IF @subscription_type_id = 0 
  15318.             BEGIN
  15319.                 EXECUTE @retcode = dbo.sp_helpdistributor
  15320.                     @distributor = @distributor_server OUTPUT               /* Distributor RPC server name */
  15321.                 IF @@ERROR <> 0 or @retcode <> 0
  15322.                     BEGIN
  15323.                         GOTO FAILURE
  15324.                     END
  15325.  
  15326.                 -- Always use integrated security on winNT
  15327.                 if (@platform_nt = platform() & @platform_nt )
  15328.                     begin
  15329.                         set @distributor_security_mode = 1
  15330.                     end
  15331.                 -- For Win9x the dist publisher and distributor are the same machine                
  15332.                 else
  15333.                     begin
  15334.                         select  @distributor_security_mode = 0,
  15335.                             @distributor_login  = login,
  15336.                             @distributor_password = password
  15337.                         from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername)
  15338.                     end
  15339.  
  15340.                 /* Call sp_MSregistersubscription so that the subscription can be synchronized via Onestop etc. */
  15341.                 exec @retcode = dbo.sp_MSregistersubscription @replication_type = 2,
  15342.                                     @publisher = @@SERVERNAME,
  15343.                                     @publisher_db = @publisher_db,
  15344.                                     @publication = @publication,
  15345.                                     @subscriber = @subscriber,
  15346.                                     @subscriber_db = @subscriber_db,
  15347.                                     @distributor = @distributor,
  15348.                                     @distributor_security_mode = @distributor_security_mode,
  15349.                                     @distributor_login = @distributor_login,
  15350.                                     @distributor_password = @distributor_password,
  15351.                                     @subscription_id = @subid,
  15352.                                     @subscription_type = @subscription_type_id
  15353.                 IF @@error <> 0 OR @retcode <> 0
  15354.                     BEGIN
  15355.                         GOTO FAILURE
  15356.                     END
  15357.  
  15358.             END                                    
  15359.         END     
  15360.     COMMIT TRAN
  15361.     return (0)
  15362.  
  15363. FAILURE:
  15364.     RAISERROR (14057, 16, -1)
  15365.     /* UNDONE : This code is specific to 6.X nested transaction semantics */
  15366.     if @@TRANCOUNT > 0
  15367.     begin
  15368.         ROLLBACK TRANSACTION addmergesubscription
  15369.         COMMIT TRANSACTION
  15370.     end
  15371.     RETURN (1)
  15372.  
  15373. go
  15374.  
  15375. grant execute on dbo.sp_addmergesubscription to public
  15376. go
  15377.  
  15378. --------------------------------------------------------------------------------
  15379. --. sp_dropmergesubscription
  15380. --------------------------------------------------------------------------------
  15381. if exists (select * from sysobjects    where type = 'P'
  15382.     and name = 'sp_dropmergesubscription')
  15383.     drop procedure sp_dropmergesubscription
  15384. go
  15385.  
  15386. raiserror('Creating procedure sp_dropmergesubscription', 0,1)
  15387. go
  15388.  
  15389. CREATE PROCEDURE sp_dropmergesubscription(
  15390.     @publication        sysname = NULL,             /* Publication name */
  15391.     @subscriber         sysname = NULL,             /* Subscriber server */
  15392.     @subscriber_db      sysname = NULL,             /* Subscription database */
  15393.     @subscription_type  nvarchar(15) = 'push',          /* Subscription type - push, pull, both */ 
  15394.     @ignore_distributor bit = 0,
  15395.     @reserved             bit = 0
  15396.     )AS
  15397.  
  15398.     SET NOCOUNT ON
  15399.  
  15400.     /*
  15401.     ** Declarations.
  15402.     */
  15403.     declare @retcode                int
  15404.     declare @subscriber_bit         smallint
  15405.     declare @subscriber_type        smallint
  15406.     declare @subscriber_srvid       int
  15407.     declare @publisher_srvid        int
  15408.     declare @pubid                  uniqueidentifier
  15409.     declare @subid                  uniqueidentifier
  15410.     declare @partnerid              uniqueidentifier
  15411.     declare @subscription_type_id   int   
  15412.     declare @found_subscription     int   
  15413.     declare @local_server           sysname
  15414.     declare @local_db               sysname
  15415.     declare @cmd                    nvarchar(290)
  15416.     declare @distributor            sysname
  15417.     declare @distribdb              sysname
  15418.     declare @distproc               nvarchar(512)
  15419.     declare @pubidstr               nvarchar(38)
  15420.     declare @publisher              sysname
  15421.     declare @publisher_db           sysname
  15422.  
  15423.     declare @implicit_transaction    int
  15424.     declare @close_cursor_at_commit int
  15425.  
  15426.     select @close_cursor_at_commit = 0
  15427.     select @implicit_transaction = 0
  15428.  
  15429.     /*
  15430.     ** Save setting values first before changing them
  15431.     */
  15432.     IF (@reserved = 0)
  15433.     BEGIN
  15434.         SELECT @implicit_transaction = @@options & 2
  15435.         SELECT @close_cursor_at_commit = @@options & 4
  15436.         SET IMPLICIT_TRANSACTIONS OFF
  15437.         SET CURSOR_CLOSE_ON_COMMIT OFF
  15438.     END
  15439.  
  15440.      /*
  15441.     ** Initializations.
  15442.     */
  15443.     set @subscriber_bit     = 4
  15444.     set @subscription_type_id = -1
  15445.     set @found_subscription = 0                     
  15446.     set @local_db           = DB_NAME()
  15447.     set @local_server       = @@SERVERNAME
  15448.     set @publisher          = @@SERVERNAME
  15449.     set @publisher_db       = DB_NAME()
  15450.  
  15451.     /*
  15452.     **  Check to see if current database is enabled for publishing/subscribing
  15453.     */
  15454.     IF not exists (select name from sysobjects where name='sysmergesubscriptions')
  15455.         BEGIN
  15456.             RAISERROR (14055, 16, -1)
  15457.             RETURN (1)
  15458.         END
  15459.  
  15460.     /*
  15461.     ** Parameter Check: @subscription_type.
  15462.     ** Set subscription_typeid based on the @subscription_type specified.
  15463.     **
  15464.     **   subscription_type    subscription_type
  15465.     **   =================    ===============
  15466.     **             0            push
  15467.     **             1            pull
  15468.     */
  15469.     if LOWER(@subscription_type) NOT IN ('both', 'push', 'pull')
  15470.         BEGIN
  15471.             RAISERROR (14128, 16, -1)
  15472.             RETURN (1)
  15473.         END
  15474.     IF LOWER(@subscription_type) = 'both'
  15475.         begin
  15476.             EXECUTE @retcode = dbo.sp_dropmergesubscription @publication = @publication,
  15477.                             @subscriber = @subscriber,
  15478.                             @subscriber_db = @subscriber_db,
  15479.                             @subscription_type = 'push',
  15480.                             @ignore_distributor = @ignore_distributor,
  15481.                             @reserved = 1
  15482.             if @retcode<>0 or @@ERROR<>0
  15483.                 return (1)
  15484.             EXECUTE @retcode = dbo.sp_dropmergesubscription @publication = @publication,
  15485.                             @subscriber = @subscriber,
  15486.                             @subscriber_db = @subscriber_db,
  15487.                             @subscription_type = 'pull',
  15488.                             @ignore_distributor = @ignore_distributor,
  15489.                             @reserved = 1
  15490.             if @retcode<>0 or @@ERROR<>0
  15491.                 return (1)
  15492.  
  15493.             RETURN (0)
  15494.         end 
  15495.     IF LOWER(@subscription_type) = 'push'
  15496.         set @subscription_type_id = 0
  15497.     else 
  15498.         set @subscription_type_id = 1
  15499.  
  15500.     /*
  15501.     ** Parameter validation (different for push and pull modes)
  15502.     */
  15503.  
  15504.     IF LOWER(@subscription_type) = 'push'
  15505.         begin
  15506.             /*
  15507.             ** Assign parameter values appropriately
  15508.             */
  15509.             if @publisher IS NULL
  15510.                 set @publisher = @@SERVERNAME
  15511.             if (@publisher_db IS NULL)
  15512.                 set @publisher_db = DB_NAME()
  15513.  
  15514.             /*
  15515.             ** Parameter Check: @subscriber
  15516.             ** Check to make sure that the subscriber is defined
  15517.             */
  15518.             IF @subscriber IS NULL
  15519.             BEGIN
  15520.                 RAISERROR (14043, 16, -1, '@subscriber')
  15521.                 RETURN (1)
  15522.             END
  15523.  
  15524.             /*
  15525.             ** Parameter Check: @subscriber_db
  15526.             */
  15527.             IF @subscriber_db IS NULL
  15528.             BEGIN
  15529.                 select @subscriber_db = 'all'
  15530.             END
  15531.                 
  15532.         end
  15533.     else
  15534.         begin
  15535.             /*
  15536.             ** Assign parameter values appropriately
  15537.             */
  15538.             if @subscriber IS NULL
  15539.                 set @subscriber = @@SERVERNAME
  15540.             if @subscriber_db IS NULL
  15541.                 set @subscriber_db = DB_NAME()
  15542.  
  15543.             /*
  15544.             ** Parameter Check: @publisher
  15545.             ** Check to make sure that the publisher is defined
  15546.             */
  15547.             IF @publisher IS NULL
  15548.             BEGIN
  15549.                 RAISERROR (14043, 16, -1, '@publisher')
  15550.                 RETURN (1)
  15551.             END
  15552.  
  15553.             EXECUTE @retcode = dbo.sp_validname @publisher
  15554.             IF @@ERROR <> 0 OR @retcode <> 0
  15555.                RETURN (1)
  15556.  
  15557.             /*
  15558.             ** Parameter Check: @publisher_db
  15559.             */
  15560.             IF @publisher_db IS NULL
  15561.             BEGIN
  15562.                 RAISERROR (14043, 16, -1, '@publisher_db')
  15563.                 RETURN (1)
  15564.             END
  15565.  
  15566.         end     
  15567.  
  15568.     /*
  15569.     ** Parameter Check:  @publication.
  15570.     ** If the publication name is specified, check to make sure that it
  15571.     ** conforms to the rules for identifiers and that the publication
  15572.     ** actually exists.  Disallow NULL.
  15573.     */
  15574.     if @publication IS NULL
  15575.         BEGIN
  15576.             RAISERROR (14043, 16, -1, '@publication')
  15577.             RETURN (1)
  15578.         END
  15579.  
  15580.     IF LOWER(@publication) = 'all'
  15581.         BEGIN
  15582.             declare hC1 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT name FROM sysmergepublications 
  15583.                 where UPPER(publisher)=UPPER(@@SERVERNAME) and publisher_db=db_name() 
  15584.                 FOR READ ONLY
  15585.             
  15586.             OPEN hC1
  15587.             FETCH hC1 INTO @publication
  15588.             WHILE (@@fetch_status <> -1)
  15589.                 BEGIN
  15590.                     EXECUTE dbo.sp_dropmergesubscription @publication = @publication,
  15591.                                                 @subscriber = @subscriber,
  15592.                                                 @subscriber_db = @subscriber_db,
  15593.                                                 @subscription_type = @subscription_type,
  15594.                                                 @ignore_distributor = @ignore_distributor,
  15595.                                                 @reserved = 1
  15596.                     FETCH hC1 INTO @publication
  15597.                 END
  15598.             CLOSE hC1
  15599.             DEALLOCATE hC1
  15600.             RETURN (0)
  15601.         END
  15602.         
  15603.     if NOT EXISTS (select * FROM sysmergepublications 
  15604.         WHERE name = @publication and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name())
  15605.         BEGIN
  15606.             RAISERROR (20026, 16, -1, @publication)
  15607.             RETURN (1)
  15608.         END
  15609.     select @pubid = pubid from sysmergepublications 
  15610.         where name = @publication and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name()
  15611.     set @pubidstr = '''' + convert(nchar(36), @pubid) + ''''
  15612.     if @pubid is null
  15613.         BEGIN
  15614.             RAISERROR (20026, 16, -1, @publication)
  15615.             RETURN (1)
  15616.         END
  15617.  
  15618.        
  15619.     IF LOWER(@subscriber) = 'all'
  15620.         BEGIN
  15621.             declare hC2 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT srvname 
  15622.             FROM master..sysservers 
  15623.             WHERE (srvstatus & 4 <> 0) FOR READ ONLY
  15624.     
  15625.             OPEN hC2
  15626.             FETCH hC2 INTO @subscriber
  15627.             WHILE (@@fetch_status <> -1)
  15628.                 BEGIN
  15629.                     EXECUTE dbo.sp_dropmergesubscription @publication = @publication,
  15630.                                                 @subscriber = @subscriber,
  15631.                                                 @subscriber_db = @subscriber_db,
  15632.                                                 @subscription_type = @subscription_type,
  15633.                                                 @ignore_distributor = @ignore_distributor,
  15634.                                                 @reserved = 1
  15635.                     FETCH hC2 INTO @subscriber
  15636.                 END
  15637.             CLOSE hC2
  15638.             DEALLOCATE hC2
  15639.             RETURN (0)
  15640.         END
  15641.  
  15642.     /*
  15643.     ** Validate that the subscriber is a valid server
  15644.     */
  15645.     select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber)
  15646.     IF @subscriber_srvid IS NULL
  15647.         BEGIN
  15648.             --RAISERROR (14010, 16, -1)
  15649.             RETURN (1)
  15650.         END
  15651.  
  15652.     /*
  15653.     ** NOTE: remove this batch
  15654.     */
  15655.     IF LOWER(@subscriber_db) = 'all'
  15656.         BEGIN
  15657.                 declare hC3 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT db_name FROM sysmergesubscriptions
  15658.                 WHERE srvid =  @subscriber_srvid 
  15659.                     AND subid <> pubid 
  15660.                     AND sysmergesubscriptions.pubid = @pubid
  15661.                     AND sysmergesubscriptions.subscription_type = @subscription_type_id
  15662.                 FOR READ ONLY       
  15663.  
  15664.             OPEN hC3
  15665.             FETCH hC3 INTO @subscriber_db
  15666.             WHILE (@@fetch_status <> -1)
  15667.                 BEGIN
  15668.                     EXECUTE dbo.sp_dropmergesubscription @publication = @publication,
  15669.                                                 @subscriber = @subscriber,
  15670.                                                 @subscriber_db = @subscriber_db,
  15671.                                                 @subscription_type = @subscription_type,
  15672.                                                 @ignore_distributor = @ignore_distributor,
  15673.                                                 @reserved = 1
  15674.  
  15675.                     FETCH hC3 INTO @subscriber_db
  15676.                 END
  15677.             CLOSE hC3
  15678.             DEALLOCATE hC3
  15679.             RETURN (0)
  15680.         END
  15681.  
  15682.     /*
  15683.     ** Validate that the publisher is a valid server
  15684.     */
  15685.     select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher)
  15686.     IF @publisher_srvid IS NULL
  15687.         BEGIN
  15688.             --RAISERROR (14010, 16, -1)
  15689.             RETURN (1)
  15690.         END
  15691.  
  15692.     select @pubid=pubid from sysmergepublications where name=@publication and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name()
  15693.     if @pubid is NULL return (0)
  15694.     
  15695.     if exists (select * from sysmergesubscriptions where subid=@pubid 
  15696.         and pubid=@pubid and db_name<>db_name())
  15697.     RETURN (0)
  15698.     
  15699.     /*
  15700.     ** Get subscriptions from either local replicas or global replicas
  15701.     */
  15702.     select @subid = subs1.subid, @partnerid = subs2.subid, @subscriber_type = subs1.subscriber_type from
  15703.         sysmergesubscriptions   subs1,
  15704.         sysmergesubscriptions   subs2,
  15705.         sysmergepublications        pubs
  15706.         where subs1.srvid = @subscriber_srvid
  15707.             and subs1.db_name = @subscriber_db
  15708.             and subs2.srvid = @publisher_srvid
  15709.             and subs2.db_name = @publisher_db
  15710.             and subs1.pubid = subs2.subid
  15711.             and subs2.pubid = pubs.pubid
  15712.             and pubs.name = @publication
  15713.             and UPPER(pubs.publisher)=UPPER(@@servername)
  15714.             and pubs.publisher_db=db_name()
  15715.             and subs1.subscription_type = @subscription_type_id
  15716.             and (suser_sname(suser_sid()) = subs1.login_name OR is_member('db_owner')=1 OR is_srvrolemember('sysadmin') = 1)
  15717.  
  15718.     if @subid IS NULL
  15719.         begin
  15720.             -- raiserror (14050, 16, -1) 
  15721.             RETURN (0)
  15722.         end                 
  15723.  
  15724.     begin tran
  15725.     save TRAN dropmergesubscription
  15726.  
  15727.         /*
  15728.         ** Do not drop the subscription corresponding to the loopback subscription 
  15729.         */
  15730.         if (@subid <> @partnerid) 
  15731.             begin
  15732.                 /*
  15733.                 ** global/republisher subscriptions have to stay for a while even after being
  15734.                 ** dropped so that they won't regain lives for themselves. They would be cleanup eventually.
  15735.                 */
  15736.                 
  15737.                 if (@subscriber_type<>1) 
  15738.                     begin
  15739.                         delete from sysmergesubscriptions where subid = @subid
  15740.                         IF @@ERROR <> 0
  15741.                             GOTO FAILURE        
  15742.                         delete MSmerge_replinfo WHERE repid = @subid 
  15743.                         IF @@ERROR <> 0
  15744.                             GOTO FAILURE
  15745.                     end
  15746.                 else
  15747.                     begin
  15748.                         update sysmergesubscriptions set status=2 where subid=@subid
  15749.                         IF @@ERROR<>0
  15750.                             GOTO FAILURE
  15751.                     end 
  15752.  
  15753.                 /* 
  15754.                 ** The MobileSync registry entry needs to be dropped only for push subscriptions -  
  15755.                 ** i.e - need not be called when a pull subscription is created at the 
  15756.                 ** subscriber and sp_addmergesubscription is being called then.
  15757.                 */
  15758.                 IF LOWER(@subscription_type) = 'push'
  15759.                 begin
  15760.                     /* Call sp_MSunregistersubscription so that the reg entries get deleted */
  15761.                     exec @retcode = dbo.sp_MSunregistersubscription @publisher = @@SERVERNAME,
  15762.                                     @publisher_db = @publisher_db,
  15763.                                     @publication = @publication,
  15764.                                     @subscriber = @subscriber,
  15765.                                     @subscriber_db = @subscriber_db
  15766.                     IF @retcode<>0 or @@ERROR<>0
  15767.                         GOTO FAILURE
  15768.  
  15769.                 END             
  15770.             end     
  15771.  
  15772.         /*
  15773.         ** if @ignore_distributor = 1, we are in bruteforce cleanup mode, don't do RPC.
  15774.         */
  15775.         if @ignore_distributor = 0
  15776.         begin
  15777.             /*
  15778.             ** Get distribution server information for remote RPC call.
  15779.             */
  15780.             EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  15781.                @distribdb   = @distribdb OUTPUT
  15782.             IF @@ERROR <> 0 or @retcode <> 0
  15783.                 BEGIN
  15784.                     GOTO FAILURE
  15785.                 END
  15786.  
  15787.             SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + 
  15788.                 '.dbo.sp_MSdrop_merge_subscription'
  15789.  
  15790.             EXEC @retcode = @distproc 
  15791.                 @@SERVERNAME, 
  15792.                 @publisher_db, 
  15793.                 @publication,
  15794.                 @subscriber, 
  15795.                 @subscriber_db,
  15796.                 @subscription_type
  15797.             IF @@ERROR <> 0 OR @retcode <> 0
  15798.                 begin   
  15799.                     goto FAILURE
  15800.                 end 
  15801.         end 
  15802.  
  15803.         /* 
  15804.         ** If last subscription is dropped and the DB is not enabled for publishing,
  15805.         ** then remove the merge system tables
  15806.         */
  15807.  
  15808.         IF (not exists (select * from sysmergesubscriptions )) 
  15809.             AND (select category & 4 FROM master..sysdatabases WHERE name = DB_NAME())=0
  15810.             BEGIN
  15811.                 execute @retcode = dbo.sp_MSdrop_mergesystables
  15812.                 if @@ERROR <> 0 or @retcode <> 0
  15813.                     begin
  15814.                         return (1)
  15815.                     end
  15816.             END         
  15817.  
  15818.     COMMIT TRAN
  15819.     /*
  15820.     ** Set back original settings
  15821.     */    
  15822.     IF @reserved = 0
  15823.     BEGIN
  15824.         IF @implicit_transaction <>0 
  15825.             SET IMPLICIT_TRANSACTIONS ON
  15826.         IF @close_cursor_at_commit <>0 
  15827.             SET CURSOR_CLOSE_ON_COMMIT ON
  15828.     END
  15829.     RETURN(0)       
  15830.  
  15831. FAILURE:
  15832.     /* UNDONE : This code is specific to 6.X nested transaction semantics */
  15833.     RAISERROR (14056, 16, -1)
  15834.     if @@TRANCOUNT > 0
  15835.     begin
  15836.         ROLLBACK TRANSACTION dropmergesubscription
  15837.         COMMIT TRANSACTION
  15838.     end
  15839.     /*
  15840.     ** Set back original settings
  15841.     */    
  15842.     IF @reserved = 0
  15843.     BEGIN
  15844.         IF @implicit_transaction <>0 
  15845.             SET IMPLICIT_TRANSACTIONS ON
  15846.         IF @close_cursor_at_commit <>0 
  15847.             SET CURSOR_CLOSE_ON_COMMIT ON
  15848.     END
  15849.     return (1)
  15850. go
  15851.  
  15852. grant execute on dbo.sp_dropmergesubscription to public
  15853. go
  15854.  
  15855. --------------------------------------------------------------------------------
  15856. --. sp_changemergefilter
  15857. --------------------------------------------------------------------------------
  15858. if exists (select * from sysobjects    where type = 'P'
  15859.     and name = 'sp_changemergefilter')
  15860.     drop procedure sp_changemergefilter
  15861. go
  15862.  
  15863. raiserror('Creating procedure sp_changemergefilter', 0,1)
  15864. go
  15865.  
  15866. create procedure sp_changemergefilter(
  15867.     @publication            sysname,
  15868.     @article                sysname,
  15869.     @filtername             sysname,
  15870.     @property               sysname,
  15871.     @value                  nvarchar(2000)
  15872.     )AS
  15873.  
  15874.     set nocount on
  15875.  
  15876.     declare @db_name        sysname
  15877.     declare @pubid          uniqueidentifier
  15878.     declare @artid          uniqueidentifier
  15879.     declare @retcode        int
  15880.     declare @join_filterid  int
  15881.     declare @join_objid     int
  15882.     declare @join_nickname  int
  15883.  
  15884.     /*
  15885.     ** Security Check.
  15886.     ** Only the System Administrator (SA) or the Database Owner (dbo) can
  15887.     ** call this procedure
  15888.     */
  15889.     exec @retcode = dbo.sp_MSreplcheck_publish
  15890.     if @@ERROR <> 0 or @retcode <> 0
  15891.         return(1)
  15892.  
  15893.     /*
  15894.     ** Parameter Check: @join_articlename.
  15895.     ** The join_articlename cannot be NULL 
  15896.     */
  15897.     if @filtername is NULL
  15898.         begin
  15899.             raiserror (14043, 11, -1, '@filtername')
  15900.             return (1)
  15901.         end
  15902.  
  15903.     if @value is NULL or @value = ''
  15904.         begin
  15905.             raiserror (14043, 11, -1, '@value')
  15906.             return (1)
  15907.         end
  15908.  
  15909.     /*
  15910.     ** Parameter Check: @publication.
  15911.     ** The @publication id cannot be NULL and must conform to the rules
  15912.     ** for identifiers.
  15913.     */
  15914.     if @publication is NULL
  15915.         begin
  15916.             raiserror (14043, 11, -1, '@publication')
  15917.             return (1)
  15918.         end
  15919.     /*
  15920.     ** Get the pubid and make sure the publication exists
  15921.     */
  15922.     select @pubid = pubid from sysmergepublications where 
  15923.         name = @publication and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name()
  15924.     if @pubid is NULL
  15925.         begin
  15926.             raiserror (20026, 16, -1, @publication)
  15927.             return (1)
  15928.         end
  15929.     /* This can only be done at the publisher */
  15930.     exec @retcode = dbo.sp_MScheckatpublisher  @pubid
  15931.     if @retcode <> 0 or @@ERROR <> 0
  15932.         return (1)
  15933.  
  15934.     /*
  15935.     ** This can be done for articles that are not active.
  15936.     */
  15937.     if EXISTS (select status FROM sysmergearticles WHERE pubid = @pubid AND status = 2)
  15938.         BEGIN
  15939.            RAISERROR (20043, 16, -1, @article)
  15940.            RETURN (1)
  15941.         END
  15942.  
  15943.     select @db_name = db_name from sysmergesubscriptions
  15944.         where (pubid=@pubid) and (subid=@pubid)
  15945.         IF @db_name <> db_name()
  15946.         BEGIN
  15947.             RAISERROR (20047, 16, -1)
  15948.             RETURN (1)
  15949.         END
  15950.  
  15951.     /*
  15952.     ** Parameter Check: @article.
  15953.     ** Check to see that the @article is valid and does exist 
  15954.     */
  15955.     if @article is NULL
  15956.         begin
  15957.             raiserror (20045, 16, -1)
  15958.             return (1)
  15959.         end
  15960.         
  15961.     select @artid = artid from sysmergearticles where name = @article and pubid = @pubid  
  15962.     if @artid is NULL
  15963.         begin
  15964.             raiserror (20046, 16, -1)
  15965.             return (1)
  15966.         end
  15967.  
  15968.     
  15969.     select @join_filterid=join_filterid from sysmergesubsetfilters
  15970.         where pubid=@pubid and artid=@artid and filtername=@filtername
  15971.  
  15972.     if @join_filterid is null
  15973.         begin
  15974.             raiserror (14028, 16, -1) 
  15975.             return (1)
  15976.         end
  15977.  
  15978.      IF @property IS NULL
  15979.         BEGIN
  15980.             CREATE TABLE #temp (properties sysname)
  15981.             INSERT INTO #temp VALUES ('filtername')
  15982.             INSERT INTO #temp VALUES ('join_filterclause')
  15983.             INSERT INTO #temp VALUES ('join_articlename')
  15984.             INSERT INTO #temp VALUES ('join_unique_key')
  15985.             select * FROM #tab1
  15986.             RETURN (0)
  15987.         END 
  15988.  
  15989.  
  15990.     if @value is null
  15991.         begin
  15992.             raiserror (14028, 16, -1) 
  15993.             return (1)
  15994.         end
  15995.  
  15996.     IF LOWER(@property)='join_unique_key'
  15997.     BEGIN
  15998.         IF LOWER(@value) NOT IN ('true','false')
  15999.             BEGIN
  16000.                   RAISERROR(14137,16,-1)
  16001.                   RETURN(1)
  16002.              END
  16003.         if LOWER(@value) = 'true'
  16004.             update sysmergesubsetfilters set join_unique_key=1 where join_filterid=@join_filterid
  16005.         else
  16006.             update sysmergesubsetfilters set join_unique_key=0 where join_filterid=@join_filterid
  16007.         if @@ERROR <> 0 or @retcode<>0
  16008.             goto FAILURE
  16009.     END
  16010.  
  16011.  
  16012.     IF LOWER(@property)='join_filterclause'
  16013.         BEGIN
  16014.             update sysmergesubsetfilters set join_filterclause=@value
  16015.                 where join_filterid=@join_filterid
  16016.             execute @retcode = dbo.sp_MSsubsetpublication @publication
  16017.             if @@ERROR <> 0 or @retcode<>0
  16018.                 goto FAILURE
  16019.         END
  16020.  
  16021.     IF LOWER(@property)='filtername'
  16022.         BEGIN
  16023.             update sysmergesubsetfilters set filtername=@value
  16024.                 where join_filterid=@join_filterid
  16025.         END
  16026.  
  16027.     IF LOWER(@property)='join_articlename'
  16028.         BEGIN
  16029.             select @join_objid = objid from sysmergearticles where name = @value and pubid = @pubid
  16030.             
  16031.             IF @join_objid is NULL
  16032.             BEGIN
  16033.                 raiserror (14027, 11, -1, @value)
  16034.                 return (1)
  16035.             END
  16036.  
  16037.             select @join_nickname = nickname from sysmergearticles where pubid = @pubid AND objid = @join_objid 
  16038.             if @join_nickname is NULL
  16039.             begin
  16040.                 raiserror (20001, 11, -1, @article, @publication)
  16041.                 return (1)
  16042.             end
  16043.             
  16044.             update sysmergesubsetfilters set join_articlename=@value, join_nickname=@join_nickname
  16045.                 where join_filterid=@join_filterid
  16046.         END
  16047.  
  16048.     return(0)
  16049.  
  16050. FAILURE:
  16051.     RAISERROR (20038, 16, -1, @article, @publication)
  16052.     return(1)
  16053.  
  16054. go
  16055.  
  16056. grant execute on dbo.sp_changemergefilter to public
  16057. go
  16058.  
  16059. --------------------------------------------------------------------------------
  16060. --. sp_MSmakeexpandproc
  16061. --------------------------------------------------------------------------------
  16062. if exists (select * from sysobjects    where type = 'P'
  16063.     and name = 'sp_MSmakeexpandproc')
  16064.     drop procedure sp_MSmakeexpandproc
  16065. go
  16066.  
  16067. raiserror('Creating procedure sp_MSmakeexpandproc', 0,1)
  16068. go
  16069.  
  16070. create procedure sp_MSmakeexpandproc
  16071.     @pubname        sysname,
  16072.     @filterid       int,
  16073.     @procname       sysname
  16074.     AS
  16075.     /* Declare additional variables */
  16076.     declare @pubid  uniqueidentifier
  16077.     declare @base_nick int
  16078.     declare @join_nick int
  16079.     declare @base_nickstr nvarchar(10)
  16080.     declare @join_nickstr nvarchar(10)
  16081.     declare @filterid_str nvarchar(10)
  16082.     declare @base_objid int
  16083.     declare @join_objid int
  16084.     declare @base_table sysname
  16085.     declare    @before_viewname    sysname
  16086.     declare @join_table sysname
  16087.     declare @base_owner sysname
  16088.     declare @join_owner sysname
  16089.     declare @join_clause nvarchar(4000)
  16090.     declare @retcode    int
  16091.     declare @must_check int
  16092.     declare @view_type  int
  16093.     declare @guidcolname    sysname
  16094.     declare @joinguidname     sysname
  16095.     declare @view_objid int
  16096.     declare @view_name  sysname
  16097.     declare @cmd_piece  nvarchar(4000)
  16098.  
  16099.     select @pubid = pubid from sysmergepublications where name = @pubname and 
  16100.         UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name()
  16101.  
  16102.     -- this procedure is to be called by xp_execresultset, so
  16103.     -- we create a temp table, put command pieces into it, and select them out
  16104.     
  16105.     -- create temp table to select the command text out of
  16106.     create table #tempcmd (step int identity NOT NULL, cmdtext nvarchar(4000) NULL)
  16107.  
  16108.     /* Figure out base table, join table for this join filter */
  16109.     select @base_nick = art_nickname, @join_nick = join_nickname,
  16110.         @join_clause = join_filterclause
  16111.         from sysmergesubsetfilters where pubid = @pubid and join_filterid = @filterid
  16112.     select @base_objid = objid, @view_type = view_type, @view_objid = sync_objid from sysmergearticles where pubid = @pubid and nickname = @base_nick
  16113.     select @join_objid = objid, @before_viewname = object_name(before_view_objid)  from sysmergearticles where pubid = @pubid and nickname = @join_nick
  16114.     select @base_table = QUOTENAME(name), @base_owner = QUOTENAME(user_name(uid)) from sysobjects where id = @base_objid
  16115.     select @join_table = QUOTENAME(name), @join_owner = QUOTENAME(user_name(uid)) from sysobjects where id = @join_objid
  16116.     select @guidcolname = name from syscolumns where id = @base_objid and 
  16117.             columnproperty (id, name, 'isrowguidcol')=1
  16118.     select @joinguidname = name from syscolumns where id = @join_objid and 
  16119.             columnproperty (id, name, 'isrowguidcol')=1
  16120.     select @view_name = object_name(@view_objid)
  16121.     -- Quote the viewname.  It is made from pub name which may have odd characters.
  16122.     set @view_name = QUOTENAME(@view_name)
  16123.     set @base_nickstr = convert(nchar(10), @base_nick)
  16124.     set @join_nickstr = convert(nchar(10), @join_nick)
  16125.     set @filterid_str = convert(nchar(10), @filterid)
  16126.     
  16127.     set @cmd_piece = 'create procedure ' + @procname + ' 
  16128.         @belong int 
  16129.         AS 
  16130.             '
  16131.     insert into #tempcmd(cmdtext) values (@cmd_piece)
  16132.     set @cmd_piece = 'if @belong = 1
  16133.             begin
  16134.             /* Do a bulk insert to expand #belong */
  16135.             update #belong set flag = ' + @filterid_str + ' where flag < ' + @filterid_str + ' 
  16136.             insert into #belong (tablenick, rowguid, flag) select ' + @base_nickstr +
  16137.             ', ' + @base_table + '.rowguidcol, 0 from ' + @base_owner + '.' + @base_table + ', ' +
  16138.             @join_owner + '.' + @join_table + ', #belong b where (' + @join_clause + ') and ' + 
  16139.             @join_table + '.rowguidcol = b.rowguid and b.tablenick = ' + @join_nickstr
  16140.     insert into #tempcmd(cmdtext) values (@cmd_piece)
  16141.     set @cmd_piece = '  
  16142.         if @@ERROR <>0 return (1)
  16143.         /* Delete duplicates */
  16144.         delete from #belong where skippedexpand = 1 and rowguid in
  16145.              (select rowguid from #belong where flag = 0)
  16146.         delete from #belong where flag = 0 and rowguid in
  16147.              (select rowguid from #belong where flag <> 0)
  16148.         end '
  16149.         insert into #tempcmd(cmdtext) values (@cmd_piece)
  16150.         
  16151.     /* Will we have to check rows that we add to #notbelong? */
  16152.     if exists (select * from sysmergearticles where pubid = @pubid and nickname = @join_nick and
  16153.         len(subset_filterclause) > 0)
  16154.         set @must_check = 1
  16155.     else if exists (select * from sysmergesubsetfilters where pubid = @pubid and join_filterid = @filterid and
  16156.         join_unique_key <> 1)
  16157.         set @must_check = 1
  16158.     else if not exists (select * from sysmergesubsetfilters where pubid = @pubid and  art_nickname = @base_nick
  16159.             and join_filterid <> @filterid)
  16160.         set @must_check = 0
  16161.     
  16162.     set @cmd_piece = '
  16163.         else 
  16164.         begin
  16165.         update #notbelong set flag = ' + @filterid_str + ' where flag < ' + @filterid_str + ' 
  16166.         /* Do a bulk insert to expand #notbelong */
  16167.         insert into #notbelong (tablenick, rowguid, flag) select ' + @base_nickstr +
  16168.             ', ' + @base_table + '.rowguidcol, -1 from ' + @base_owner + '.' + @base_table + ', ' +
  16169.             @join_owner + '.' + @join_table + ', #notbelong nb where (' + @join_clause + ') and ' + 
  16170.             @join_table + '.rowguidcol = nb.rowguid
  16171.             /* Remove duplicates */
  16172.             delete from #notbelong where flag = -1 and rowguid in
  16173.                 (select rowguid from #notbelong where flag <> -1)
  16174.             '
  16175.     if @before_viewname  is not null
  16176.     set @cmd_piece = @cmd_piece + '
  16177.         insert into #notbelong (tablenick, rowguid, flag) select ' + @base_nickstr +
  16178.             ', ' + @base_table + '.rowguidcol, -1 from ' + @base_owner + '.' + @base_table + ', ' +
  16179.             @before_viewname + ' ' + @join_table + ', #notbelong nb where (' + @join_clause + ') and ' + 
  16180.             @join_table + '.' + @joinguidname + ' = nb.rowguid
  16181.             /* Remove duplicates */
  16182.             delete from #notbelong where flag = -1 and rowguid in
  16183.                 (select rowguid from #notbelong where flag <> -1)
  16184.             '
  16185.  
  16186.         
  16187.     if @must_check = 0
  16188.         begin
  16189.         insert into #tempcmd(cmdtext) values (@cmd_piece)
  16190.         set @cmd_piece = ' update #notbelong set flag = 0 where flag = -1 
  16191.             end '
  16192.         insert into #tempcmd(cmdtext) values (@cmd_piece)
  16193.         end
  16194.     else if @view_type = 1
  16195.         begin
  16196.         insert into #tempcmd(cmdtext) values (@cmd_piece)
  16197.         set @cmd_piece =  '     -- We can do our check with a bulk delete, bulk update
  16198.             delete from #notbelong where flag = -1 and rowguid in
  16199.                 (select ' + @guidcolname + ' from ' + @view_name + ')
  16200.             update #notbelong set flag = 0 where flag = -1
  16201.             end '
  16202.         insert into #tempcmd(cmdtext) values (@cmd_piece)
  16203.         end
  16204.     -- else we don't bother expanding #notbelong for this filter since there are cyclic
  16205.     -- join filters and this is not a unique key join.  The cursored calls to sp_belongs
  16206.     -- are unacceptably slow, and there would still be cases where orphaned rows could occur.
  16207.  
  16208. -- Now we select out the command text pieces in proper order so that our caller,
  16209. -- xp_execresultset will execute the command that creates the stored procedure.
  16210.  
  16211. select cmdtext from #tempcmd order by step
  16212.  
  16213. GO
  16214.  
  16215. --------------------------------------------------------------------------------
  16216. --. sp_deletemergeconflictrow
  16217. --------------------------------------------------------------------------------
  16218. if exists (select * from sysobjects    where type = 'P'
  16219.     and name = 'sp_deletemergeconflictrow')
  16220.     drop procedure sp_deletemergeconflictrow
  16221. go
  16222.  
  16223. raiserror('Creating procedure sp_deletemergeconflictrow', 0,1)
  16224. go
  16225.  
  16226. CREATE PROCEDURE sp_deletemergeconflictrow(
  16227.     @conflict_table         sysname = '%',
  16228.     @source_object          nvarchar(386) = NULL,
  16229.     @rowguid                uniqueidentifier,
  16230.     @origin_datasource      varchar(255),
  16231.     @drop_table_if_empty    varchar(10) = 'false')
  16232. as
  16233.     declare @retcode        smallint
  16234.     declare @cmd            nvarchar(4000)  
  16235.     declare @rowguidstr     nvarchar(40)
  16236.     declare @object         sysname  
  16237.     declare @owner          sysname  
  16238.     declare @tablenick      int
  16239.     declare @tablenickstr   nvarchar(11)
  16240.  
  16241.  
  16242.     set @rowguidstr = convert(nchar(36), @rowguid)
  16243.  
  16244.     /* Delete conflict from Conflict_<Table> */
  16245.     if @conflict_table <> '%'
  16246.         begin
  16247.             select @cmd = 'delete from '
  16248.             select @cmd = @cmd + @conflict_table 
  16249.             select @cmd = @cmd + ' where origin_datasource = '''
  16250.             select @cmd = @cmd + @origin_datasource 
  16251.             select @cmd = @cmd + ''' and rowguidcol = '''
  16252.             select @cmd = @cmd + @rowguidstr
  16253.             select @cmd = @cmd + ''''
  16254.             -- DEBUG select 'Delete conflict_table query' = @cmd
  16255.             exec (@cmd)
  16256.             if @@ERROR<>0 return (1)
  16257.  
  16258.             select @cmd = 'if not exists (select 1 from ' 
  16259.             select @cmd = @cmd + @conflict_table 
  16260.             select @cmd = @cmd + ')'
  16261.             select @cmd = @cmd + ' update sysmergearticles set ins_conflict_proc = NULL, conflict_table = NULL where conflict_table = '''
  16262.             select @cmd = @cmd + @conflict_table
  16263.             select @cmd = @cmd + ''''
  16264.             -- DEBUG select "Update conflict_table query" = @cmd
  16265.             exec (@cmd)
  16266.             if @@ERROR<>0 return (1)
  16267.  
  16268.             if LOWER(@drop_table_if_empty) = 'true'
  16269.                 begin
  16270.                     select @cmd = 'if not exists (select 1 from ' 
  16271.                     select @cmd = @cmd + @conflict_table 
  16272.                     select @cmd = @cmd + ')'
  16273.                     select @cmd = @cmd + ' drop table '
  16274.                     select @cmd = @cmd + @conflict_table
  16275.                     select @cmd = @cmd + ''
  16276.                     -- DEBUG select "Drop conflict_table query" = @cmd
  16277.                     exec (@cmd)
  16278.                     if @@ERROR<>0 return (1)
  16279.                 end
  16280.         end
  16281.     /* Delete conflict from MSmerge_delete_conflicts */
  16282.     else
  16283.         begin
  16284.             select @object = PARSENAME(@source_object, 1)
  16285.             select @owner = PARSENAME(@source_object, 2)
  16286.             execute @retcode=sp_MStablenickname @owner, @object, @tablenick output
  16287.         
  16288.             if @tablenick IS NULL or @@ERROR<>0 or @retcode<>0
  16289.                 BEGIN
  16290.                     raiserror (20003, 11, -1, @object)
  16291.                     RETURN (1)
  16292.                 END
  16293.  
  16294.             set @tablenickstr = convert(nchar, @tablenick)
  16295.  
  16296.             
  16297.             select @cmd = 'delete from MSmerge_delete_conflicts'
  16298.             select @cmd = @cmd + ' where origin_datasource = '''
  16299.             select @cmd = @cmd + @origin_datasource 
  16300.             select @cmd = @cmd + ''' and tablenick = '
  16301.             select @cmd = @cmd + @tablenickstr
  16302.             select @cmd = @cmd + ' and rowguid = '''
  16303.             select @cmd = @cmd + @rowguidstr
  16304.             select @cmd = @cmd + ''''
  16305.             -- DEBUG select 'MSMerge_Delete conflict_table query' = @cmd
  16306.             exec (@cmd)
  16307.             if @@ERROR<>0 return (1)
  16308.  
  16309.         end
  16310.  
  16311. go
  16312.  
  16313. --------------------------------------------------------------------------------
  16314. --. sp_MSget_subtypedatasrc
  16315. --------------------------------------------------------------------------------
  16316. if exists (select * from sysobjects    where type = 'P'
  16317.     and name = 'sp_MSget_subtypedatasrc')
  16318.     drop procedure sp_MSget_subtypedatasrc
  16319. go
  16320.  
  16321. raiserror('Creating procedure sp_MSget_subtypedatasrc', 0,1)
  16322. go
  16323.  
  16324. CREATE PROCEDURE sp_MSget_subtypedatasrc
  16325. @subscriber                sysname,
  16326. @distributor            sysname,
  16327. @distribdb                sysname,
  16328. @datasrctype            int OUTPUT,
  16329. @datasrc                sysname OUTPUT
  16330. AS
  16331.     SET NOCOUNT ON
  16332.  
  16333.     DECLARE @provider_name        sysname
  16334.     DECLARE @jet_subscriber     tinyint
  16335.     DECLARE @oledb_subscriber   tinyint
  16336.     DECLARE @oracle_subscriber  tinyint
  16337.     DECLARE @distproc           nvarchar(255)
  16338.     DECLARE @cmd                 nvarchar(512)
  16339.     
  16340.     set @jet_subscriber = 2   
  16341.     set @oledb_subscriber = 3 
  16342.     set @oracle_subscriber = 5 
  16343.     
  16344.     create table #subtype
  16345.     (
  16346.         type tinyint not null,   
  16347.     )
  16348.  
  16349.     SELECT @distproc = RTRIM(@distributor) + '.' +
  16350.         RTRIM(@distribdb) + '.dbo.sp_executesql'
  16351.  
  16352.     SELECT @cmd = 'select type from MSsubscriber_info where UPPER(subscriber) = ''' + UPPER(@subscriber) + ''' and UPPER(publisher) = ''' + @@servername + ''''
  16353.     
  16354.     insert into #subtype exec @distproc @cmd
  16355.     if (@@error <> 0 or @@rowcount <> 1)
  16356.     begin
  16357.         drop table #subtype
  16358.         raiserror(14085, 16, -1)
  16359.         return 1
  16360.     end
  16361.     
  16362.     select @datasrctype = type from #subtype
  16363.  
  16364.     create table #server_info 
  16365.     (
  16366.         providername nvarchar(256) null,
  16367.         datasource nvarchar(3750) null,    -- this is nvarchar(4000) in sysservers, but we want to 
  16368.                                         -- avoid sev 10 info msg on create table with > 8060 bytes
  16369.     )
  16370.     
  16371.     SELECT @cmd = 'select providername, datasource from master..sysservers where UPPER(srvname) = ''' + UPPER(@subscriber) + ''''
  16372.     
  16373.     insert into #server_info exec @distproc @cmd
  16374.     if (@@error <> 0 or @@rowcount <> 1)
  16375.     begin
  16376.         drop table #subtype
  16377.         drop table #server_info
  16378.         raiserror(14085, 16, -1)
  16379.         return 1
  16380.     end
  16381.     
  16382.     select @datasrc = datasource, @provider_name =  providername from #server_info
  16383.     
  16384.     /*
  16385.     ** Jet and Oracle subscribers are actually added to MSsubscriber_info as OLE DB subscribers,
  16386.     ** since they can be used in transactional replication also.
  16387.     ** Map the type to Jet or Oracle based on OLE DB provider name.
  16388.     */
  16389.     
  16390.     if (@datasrctype = @oledb_subscriber) 
  16391.     BEGIN
  16392.         if (upper(@provider_name) = 'MICROSOFT.JET.OLEDB.4.0')
  16393.             select @datasrctype = @jet_subscriber
  16394.         else if (upper(@provider_name) = 'MSDAORA')
  16395.             select @datasrctype = @oracle_subscriber
  16396.     END
  16397.     
  16398.     drop table #subtype
  16399.     drop table #server_info
  16400.  
  16401.     return 0
  16402. GO
  16403.  
  16404. grant exec on dbo.sp_MSget_subtypedatasrc to public
  16405. go
  16406.  
  16407. --------------------------------------------------------------------------------
  16408. --.    Merge repl objects (rlcore.sql)
  16409. --------------------------------------------------------------------------------
  16410. dump tran master with no_log
  16411. go
  16412.  
  16413. --------------------------------------------------------------------------------
  16414. --. sp_MSaddguidindex
  16415. --------------------------------------------------------------------------------
  16416. if exists (select * from sysobjects    where type = 'P'
  16417.     and name = 'sp_MSaddguidindex')
  16418.     drop procedure sp_MSaddguidindex
  16419. go
  16420.  
  16421. raiserror('Creating procedure sp_MSaddguidindex', 0,1)
  16422. go
  16423.  
  16424. create procedure sp_MSaddguidindex
  16425.     @source_owner    sysname,
  16426.     @source_table     sysname        
  16427. as
  16428.     set nocount on
  16429.     declare @indexname     nvarchar(270)
  16430.     declare @colname    sysname
  16431.     declare @retcode int
  16432.     declare @qualified_name nvarchar(258)
  16433.  
  16434.   
  16435.    select @qualified_name = QUOTENAME(@source_owner) + '.' + QUOTENAME(@source_table)
  16436.    
  16437.     select @indexname = 'index_' + convert(nvarchar(36), object_id(@qualified_name))
  16438.  
  16439.     /* Make sure index name is unique */
  16440.     exec @retcode = dbo.sp_MSuniqueobjectname @indexname, @indexname output
  16441.     if @retcode <>0 return (1)
  16442.     
  16443.  
  16444.     select @colname=name from syscolumns where id=object_id(@qualified_name) and columnproperty(object_id(@qualified_name), name, 'isrowguidcol')=1
  16445.     if (@colname is null)
  16446.         return (1)
  16447.         
  16448.     /* Alter the source table to add a rowguid column */
  16449.     if (not exists (select * from sysindexes
  16450.         where id = object_id(@qualified_name) and
  16451.             @colname = index_col(object_name(id), indid, 1)
  16452.             and indexproperty(id, name, 'IsUnique') = 1 and 
  16453.             index_col(object_name(id), indid, 2) is null))
  16454.         begin
  16455.             select @colname = QUOTENAME(@colname)
  16456.             exec ('create unique index ' + @indexname  + ' on ' + @qualified_name + ' (' +  @colname + ')')
  16457.             if @@ERROR <>0 return (1) 
  16458.         end
  16459.     return (0)
  16460. go
  16461.  
  16462. grant exec on dbo.sp_MSaddguidindex to public
  16463. go
  16464.  
  16465. -------------------------------------------------------------------------------
  16466. --. sp_MStablenamefromnick
  16467. --------------------------------------------------------------------------------
  16468. if exists (select * from sysobjects    where type = 'P'
  16469.     and name = 'sp_MStablenamefromnick')
  16470.     drop procedure sp_MStablenamefromnick
  16471. go
  16472.  
  16473. raiserror('Creating procedure sp_MStablenamefromnick', 0,1)
  16474. go
  16475.  
  16476. create procedure sp_MStablenamefromnick
  16477.     @nick int,
  16478.     @tablename nvarchar(258) output,
  16479.     @pubid uniqueidentifier = NULL
  16480. as
  16481.     declare @owner sysname
  16482.     declare @table sysname
  16483.     if (@pubid is null)
  16484.         select @table = name, @owner = user_name(uid) from sysobjects where id in (select 
  16485.             objid from sysmergearticles where nickname = @nick)
  16486.     else
  16487.         select @table = name, @owner = user_name(uid) from sysobjects where id in (select 
  16488.             objid from sysmergearticles where nickname = @nick and pubid = @pubid)
  16489.             
  16490.     select @tablename = QUOTENAME(@owner) + '.' + QUOTENAME(@table)
  16491.     if (@table is NULL) or (@owner is NULL) 
  16492.     begin
  16493.         raiserror(21124, 16, -1, @nick)
  16494.         return (1) 
  16495.     end
  16496.     return (0)
  16497. go
  16498.  
  16499. --------------------------------------------------------------------------------
  16500. --. sp_MSmakegeneration
  16501. --------------------------------------------------------------------------------
  16502. if exists (select * from sysobjects    where type = 'P'
  16503.     and name = 'sp_MSmakegeneration')
  16504.     drop procedure sp_MSmakegeneration
  16505. go
  16506.  
  16507. raiserror('Creating procedure sp_MSmakegeneration', 0,1)
  16508. go
  16509.  
  16510. create procedure sp_MSmakegeneration
  16511.     @rowcount int = 0
  16512.     as
  16513.     declare @gen int
  16514.     declare @nick int
  16515.     declare @genguid uniqueidentifier
  16516.     declare @dt datetime
  16517.     declare @dt2 datetime
  16518.     declare @art_nick int
  16519.     declare @first_ts int
  16520.     declare @makenewrow int
  16521.     declare @retcode smallint
  16522.     declare @guidnull uniqueidentifier
  16523.     
  16524.     set nocount on
  16525.     set rowcount @rowcount
  16526.     set @guidnull = '00000000-0000-0000-0000-000000000000'
  16527.     
  16528.     /*
  16529.     ** Check to see if current publication has permission
  16530.     */
  16531.     exec @retcode=sp_MSreplcheck_connection
  16532.     if @retcode<>0 or @@ERROR<>0 return (1)
  16533.     
  16534.     set @genguid = newid()
  16535.     exec @retcode=sp_MSgetreplnick @nickname = @nick out
  16536.     if @retcode<>0 or @@error<>0 return (1)
  16537.     set @dt = getdate()
  16538.  
  16539.     -- If someone else is making generations / has just made one, exit so
  16540.     -- that we won't deadlock
  16541.     select @dt2 = max(coldate) from MSmerge_genhistory where guidsrc = guidlocal
  16542.     if datediff(dd, @dt2, @dt) = 0
  16543.         begin
  16544.         if 500 > datediff(ms, @dt2, @dt) and 0 < datediff(ms, @dt2, @dt)
  16545.             return 0
  16546.         end
  16547.  
  16548.     -- check for holes 
  16549.     set @dt2 =  DATEADD(day, -2, @dt)
  16550.     select @gen = max(generation) from MSmerge_genhistory
  16551.     if exists (select * from MSmerge_genhistory where guidlocal = @guidnull and generation < @gen - 100 and
  16552.                 coldate < @dt2 and     generation not in (select gen_cur from sysmergearticles))
  16553.         begin
  16554.         -- before we delete the holes, move contents rows to generation 0 so they don't get forgotten
  16555.  
  16556.         if exists (select * from MSmerge_contents (readpast readcommitted) where generation in (select generation from MSmerge_genhistory where guidlocal = @guidnull and generation < @gen - 100 and
  16557.                     coldate < @dt2 and     generation not in (select gen_cur from sysmergearticles)))
  16558.                 begin
  16559.                 update MSmerge_contents set generation = 0 where generation in (select generation from MSmerge_genhistory where guidlocal = @guidnull and generation < @gen - 100 and
  16560.                         generation not in (select gen_cur from sysmergearticles))
  16561.                 if (@@error <> 0)
  16562.                     begin
  16563.                     goto FAILURE
  16564.                     end    
  16565.                 end
  16566.         if exists (select * from MSmerge_tombstone (readpast readcommitted) where generation in (select generation from MSmerge_genhistory where guidlocal = @guidnull and generation < @gen - 100 and
  16567.                     coldate < @dt2 and generation not in (select gen_cur from sysmergearticles)))
  16568.                 begin
  16569.                 update MSmerge_tombstone set generation = 0 where generation in (select generation from MSmerge_genhistory where guidlocal = @guidnull and generation < @gen - 100 and
  16570.                     coldate < @dt2 and generation not in (select gen_cur from sysmergearticles))
  16571.                 if (@@error <> 0)
  16572.                     begin
  16573.                     goto FAILURE
  16574.                     end    
  16575.                 end
  16576.         delete from MSmerge_genhistory where guidlocal = @guidnull and generation < @gen - 100 and
  16577.                     coldate < @dt2 and generation not in (select gen_cur from sysmergearticles)
  16578.         if (@@error <> 0)
  16579.             begin
  16580.             goto FAILURE
  16581.             end    
  16582.         end
  16583.     /*
  16584.     ** If there are no zero generation tombstones or rows, add a dummy row in there. 
  16585.     */
  16586.        if not exists (select * from MSmerge_genhistory where guidlocal <> @guidnull)
  16587.         begin
  16588.         begin tran
  16589.            insert into MSmerge_genhistory (guidsrc, guidlocal, generation, art_nick, nicknames, coldate) values
  16590.             (@genguid, @genguid, 1, 0, @nick, @dt)
  16591.         
  16592.         if (@@error <> 0)
  16593.             begin
  16594.             goto FAILURE
  16595.             end    
  16596.         commit tran
  16597.         end
  16598.  
  16599.     select @art_nick = min(nickname) from sysmergearticles
  16600.     while @art_nick is not null
  16601.         begin
  16602.         begin tran
  16603.         select @gen = max(gen_cur) from sysmergearticles (updlock holdlock) where nickname = @art_nick and gen_cur is not null
  16604.  
  16605.         if @gen is null
  16606.             begin
  16607.             set @genguid = newid()
  16608.             insert into MSmerge_genhistory (guidsrc, guidlocal, generation, art_nick, nicknames, coldate) 
  16609.                 select @genguid, @guidnull, COALESCE(1 + max(generation), 1), @art_nick, @nick, @dt from MSmerge_genhistory (updlock)
  16610.             if (@@error <> 0)
  16611.                 begin
  16612.                 goto FAILURE
  16613.                 end    
  16614.             select @gen =  generation from MSmerge_genhistory where guidsrc = @genguid
  16615.             update sysmergearticles set gen_cur = @gen where nickname = @art_nick
  16616.             if (@@error <> 0)
  16617.                 begin
  16618.                 goto FAILURE
  16619.                 end    
  16620.             end
  16621.  
  16622.         -- these updates should be hitting zero rows...
  16623.         if exists (select * from MSmerge_contents (readpast readcommitted) where generation = 0 and tablenick = @art_nick)
  16624.             begin
  16625.             update MSmerge_contents set generation = @gen, partchangegen = @gen, joinchangegen = @gen
  16626.                  where generation = 0 and partchangegen = 0 and tablenick = @art_nick
  16627.             if (@@error <> 0)
  16628.                 begin
  16629.                 goto FAILURE
  16630.                 end    
  16631.             update MSmerge_contents set generation = @gen, joinchangegen = @gen
  16632.                  where generation = 0 and joinchangegen = 0 and tablenick = @art_nick
  16633.             if (@@error <> 0)
  16634.                 begin
  16635.                 goto FAILURE
  16636.                 end    
  16637.             update MSmerge_contents set generation = @gen where generation = 0 and tablenick = @art_nick
  16638.             if (@@error <> 0)
  16639.                 begin
  16640.                 goto FAILURE
  16641.                 end
  16642.             end
  16643.             
  16644.         if exists (select * from MSmerge_tombstone (readpast readcommitted) where generation = 0 and tablenick = @art_nick)
  16645.             begin
  16646.             update MSmerge_tombstone set generation = @gen where generation = 0 and tablenick = @art_nick
  16647.             if (@@error <> 0)
  16648.                 begin
  16649.                 goto FAILURE
  16650.                 end
  16651.             end
  16652.         if not exists (select * from MSmerge_contents where tablenick = @art_nick and
  16653.                         generation = @gen) and
  16654.            not exists (select * from MSmerge_tombstone where tablenick = @art_nick and
  16655.                         generation = @gen)
  16656.             begin
  16657.             select @dt2 = coldate from MSmerge_genhistory where generation = @gen
  16658.             if datediff(dd, @dt2, @dt) = 0 and not exists (select * from MSmerge_genhistory
  16659.                     where generation > 100 + @gen)
  16660.                 begin
  16661.                 set @makenewrow = 0
  16662.                 end
  16663.             else
  16664.                 begin
  16665.                 set @makenewrow = 1
  16666.                 delete from MSmerge_genhistory where generation = @gen
  16667.                 if (@@error <> 0)
  16668.                     begin
  16669.                     goto FAILURE
  16670.                     end    
  16671.                 end
  16672.                 
  16673.             if (@@error <> 0)
  16674.                 begin
  16675.                 goto FAILURE
  16676.                 end    
  16677.             end
  16678.         else
  16679.             begin
  16680.             set @makenewrow = 1
  16681.             set @genguid = newid()
  16682.             update MSmerge_genhistory set guidsrc = @genguid, guidlocal = @genguid, coldate = @dt
  16683.                 where generation = @gen
  16684.             if (@@error <> 0)
  16685.                 begin
  16686.                 goto FAILURE
  16687.                 end    
  16688.             update MSmerge_replinfo set recgen = @gen, recguid = @genguid, 
  16689.                 sentgen = @gen, sentguid = @genguid where replnickname = @nick
  16690.             if (@@error <> 0)
  16691.                 begin
  16692.                 goto FAILURE
  16693.                 end    
  16694.             end
  16695.  
  16696.         if (@makenewrow = 1)
  16697.             begin
  16698.             /* reset next generation for this article */
  16699.             set @genguid = newid()
  16700.             insert into MSmerge_genhistory (guidsrc, guidlocal, generation, art_nick, nicknames, coldate) 
  16701.                 select @genguid, @guidnull, COALESCE(1 + max(generation), 1), @art_nick, @nick, @dt from MSmerge_genhistory (updlock)
  16702.             if (@@error <> 0)
  16703.                 begin
  16704.                 goto FAILURE
  16705.                 end    
  16706.             select @gen =  generation  from MSmerge_genhistory where guidsrc = @genguid
  16707.             update sysmergearticles set gen_cur = @gen where nickname = @art_nick
  16708.             if (@@error <> 0)
  16709.                 begin
  16710.                 goto FAILURE
  16711.                 end    
  16712.             end
  16713.         commit transaction        
  16714.  
  16715.         -- set up for next time through the loop
  16716.         select @art_nick = min(nickname) from sysmergearticles where nickname > @art_nick
  16717.         
  16718.         set @dt = getdate()
  16719.         end
  16720.     return 0
  16721. FAILURE:
  16722.     /* UNDONE : This code is specific to 6.X nested transaction semantics */
  16723.     if @@TRANCOUNT = 1 
  16724.         ROLLBACK TRANSACTION makegeneration
  16725.     else
  16726.         COMMIT TRANSACTION
  16727.     return (1)    
  16728. go
  16729.  
  16730. grant exec on dbo.sp_MSmakegeneration to public
  16731. go
  16732.  
  16733. -------------------------------------------------------------------------------
  16734. --. sp_MSaddupdatetrigger
  16735. --------------------------------------------------------------------------------
  16736. if exists (select * from sysobjects    where type = 'P'
  16737.     and name = 'sp_MSaddupdatetrigger')
  16738.     drop procedure sp_MSaddupdatetrigger
  16739. go
  16740.  
  16741. raiserror('Creating procedure sp_MSaddupdatetrigger', 0,1)
  16742. go
  16743.  
  16744. CREATE PROCEDURE sp_MSaddupdatetrigger 
  16745.     @source_table        nvarchar(258),        /* source table name */
  16746.     @owner                sysname,            /* Owner name of source table */
  16747.     @object             sysname,            /* Object name */
  16748.     @artid                uniqueidentifier,    /* Article id */
  16749.     @column_tracking        int,
  16750.     @viewname            sysname             /* name of view on syscontents */
  16751.     
  16752. AS
  16753.     declare @command1 nvarchar(4000)
  16754.     declare @command2 nvarchar(4000)
  16755.     declare @command3 nvarchar(4000)
  16756.     declare @inscommand nvarchar(2000)
  16757.     declare @tablenick int    
  16758.     declare @nickname int
  16759.     declare @trigname sysname
  16760.     declare @ext nvarchar(10)
  16761.     declare @gstr sysname
  16762.     declare @tablenickchar nvarchar(11)
  16763.     declare @ccols int
  16764.     declare @guidstr    nvarchar(32)
  16765.     declare @colid smallint
  16766.     declare @colordinal        smallint
  16767.     declare @colordstr        varchar(4)
  16768.  
  16769.     declare @colname sysname
  16770.     declare @colpat nvarchar(34)
  16771.     declare @colchar nvarchar(5)
  16772.     declare @piece nvarchar(400)
  16773.  
  16774.     declare @retcode int
  16775.     declare @ifcol nvarchar(4000)
  16776.     declare @ccolchar nvarchar(5)
  16777.     declare @partchangecnt int
  16778.     declare @joinchangecnt int
  16779.     declare @partchangecnt2 int
  16780.     declare @cvstr1    nvarchar(500)
  16781.     declare @cvstr2 nvarchar(500)
  16782.     declare @flag smallint
  16783.     declare @missingbm varbinary(500)
  16784.     declare @missingcolid int
  16785.     declare @maxcolid int
  16786.     declare @missingbmstr varchar(1000)
  16787.     declare @objid int
  16788.     declare @partchbm varbinary(500)
  16789.     declare @joinchbm varbinary(500)
  16790.     declare @partchstr varchar(1002)
  16791.     declare @joinchstr varchar(1002)
  16792.     
  16793.     set @ifcol = ''
  16794.     
  16795.     select @flag = 0
  16796.     set @objid = OBJECT_ID(@source_table)
  16797.     select @ccols =  count(*) from syscolumns where id = @objid and iscomputed <> 1
  16798.     select @ccolchar = convert(nchar, @ccols)
  16799.     set @colordinal = 0
  16800.     
  16801.     execute @retcode=sp_MStablenickname @owner, @object, @tablenick output
  16802.     if @@ERROR<>0 or @retcode<>0 return (1)
  16803.     set @tablenickchar = convert(nchar, @tablenick)
  16804.     set @joinchbm = 0x0
  16805.     set @partchbm = 0x0
  16806.     
  16807.     declare col_cursor CURSOR LOCAL FAST_FORWARD for select name, colid from syscolumns where
  16808.         id = @objid  and iscomputed <> 1 order by colid
  16809.     FOR READ ONLY
  16810.     
  16811.     /* Try to set the ifcol pieces of the trigger */
  16812.     open col_cursor
  16813.     fetch next from col_cursor into @colname, @colid
  16814.     while (@@fetch_status <> -1)
  16815.         begin
  16816.         set @colordinal = @colordinal + 1
  16817.         set @colpat = '%' + @colname + '%'
  16818.         /* Don't let them update the rowguid column */
  16819.         if columnproperty( @objid, @colname , 'isrowguidcol')=1
  16820.             set @ifcol = 'if update(' + QUOTENAME(@colname) +    ')
  16821.             begin
  16822.             if @@trancount > 0
  16823.                 rollback tran
  16824.                 
  16825.             RAISERROR (20062, 16, -1)
  16826.             end
  16827.                 '
  16828.         /* does updating this column change membership in a partial replica? */
  16829.         select @partchangecnt = count(*) from sysmergearticles 
  16830.             where nickname = @tablenick and subset_filterclause like @colpat
  16831.         select @partchangecnt2 = count(*) from sysmergesubsetfilters
  16832.             where art_nickname = @tablenick and join_filterclause like @colpat
  16833.         select @joinchangecnt = count(*) from sysmergesubsetfilters
  16834.              where join_nickname = @tablenick and join_filterclause like @colpat
  16835.         if @partchangecnt > 0 or @partchangecnt2 > 0
  16836.             exec dbo.sp_MSsetbit @partchbm out, @colid
  16837.         else if @joinchangecnt > 0
  16838.             exec dbo.sp_MSsetbit @joinchbm out, @colid
  16839.         /* Repeat the loop with next column */
  16840.         fetch next from col_cursor into @colname, @colid
  16841.         end
  16842.     close col_cursor
  16843.     deallocate col_cursor
  16844.  
  16845.     -- Initialize string for inserting to before_image table
  16846.     exec sp_MSgetbeforetableinsert @objid, @inscommand output
  16847.  
  16848.     /* Make strings to initialize variables for partchange, joinchange bitmaps */
  16849.     exec master..xp_varbintohexstr @partchbm, @partchstr out
  16850.     exec master..xp_varbintohexstr @joinchbm, @joinchstr out
  16851.  
  16852.     /* Figure out if there are any holes in the colid sequence */
  16853.     select @maxcolid = max(colid) from syscolumns where id = @objid
  16854.     if @maxcolid = @ccols
  16855.         set @missingbmstr = '0x00'
  16856.     else
  16857.         begin
  16858.         set @missingcolid = 1
  16859.         set @missingbm = 0x00
  16860.         while (@missingcolid <= @maxcolid)
  16861.             begin
  16862.             if not exists (select * from syscolumns where colid = @missingcolid and
  16863.                     id = OBJECT_ID(@source_table) and iscomputed <> 1)
  16864.             exec dbo.sp_MSsetbit @missingbm out, @missingcolid
  16865.             set @missingcolid = @missingcolid + 1
  16866.             end
  16867.         exec master..xp_varbintohexstr @missingbm, @missingbmstr out
  16868.         end
  16869.  
  16870.     execute @retcode=sp_MSgetreplnick @nickname = @nickname output
  16871.     if @retcode<>0 or @@error<>0 return (1)
  16872.     set @ext = 'upd_'
  16873.  
  16874.     exec @retcode=sp_MSguidtostr @artid, @guidstr out
  16875.     if @retcode<>0 or @@error<>0 return (1)
  16876.  
  16877.     set @trigname =  @ext + @guidstr 
  16878.  
  16879.     /* Make sure trigger name is unique */
  16880.     exec @retcode=sp_MSuniqueobjectname @trigname, @trigname output
  16881.     if @retcode<>0 or @@error<>0 return (1)
  16882.     if @column_tracking <> 0
  16883.         begin
  16884.         /* Set cv pieces appropriately */
  16885.         set @cvstr1 = ' 
  16886.             set @lineage = { fn UPDATELINEAGE(0x0, @nick) }
  16887.             set @lineage = { fn UPDATELINEAGE(@lineage, @nick) }
  16888.             set @cv = { fn INITCOLVS(@ccols, @nick) }
  16889.             if (@@error <> 0)
  16890.                 begin
  16891.                 goto FAILURE
  16892.                 end
  16893.             set @cv = { fn UPDATECOLVBM(@cv, @nick, @bm, @missingbm) }
  16894.         '
  16895.         set @cvstr2 = ' colv1 = { fn UPDATECOLVBM(colv1, @nick, @bm, @missingbm) } '
  16896.         end
  16897.     else
  16898.         begin
  16899.         set @cvstr1 = '   set @lineage = { fn UPDATELINEAGE(0x0, @nick) }
  16900.             set @lineage = { fn UPDATELINEAGE(@lineage, @nick) }
  16901.             set @cv = NULL
  16902.      '
  16903.         set @cvstr2 = ' colv1 = NULL '
  16904.         end
  16905.     /* UNDONE maybe remove null guid checks in SQL SERVER 7.0 */
  16906.     select @command1 = 'create trigger ' + @trigname + ' on ' + @source_table +
  16907.     ' FOR UPDATE AS
  16908.     /* Declare variables */
  16909.     declare @bm varbinary(500)
  16910.     declare @missingbm varbinary(500)
  16911.     declare @tablenick int
  16912.     declare @rowguid uniqueidentifier
  16913.     declare @lineage varbinary(255)
  16914.     declare @cv varbinary(2048)
  16915.     declare @ver int
  16916.     declare @nick int
  16917.     declare @ccols int
  16918.     declare @partchange int
  16919.     declare @joinchange int
  16920.     declare @partgen int
  16921.     declare @joingen int
  16922.     declare    @partchangebm varbinary(500)
  16923.     declare @joinchangebm varbinary(500)
  16924.     declare @newgen int
  16925.  
  16926.     set nocount on
  16927.     select @newgen = gen_cur from sysmergearticles where nickname = ' + @tablenickchar + '
  16928.     if @newgen is null
  16929.         set @newgen = 0
  16930.     /* Use intrinsic funtion to set bits for updated columns */
  16931.     set @bm = columns_updated()
  16932.     set @missingbm = ' 
  16933.     
  16934.     select @command2 = '  
  16935.  
  16936.     /* See if the partition might have changed */
  16937.     if @partchangebm = 0x0
  16938.         set @partchange = 0
  16939.     else
  16940.         set @partchange= { fn INTERSECTBITMAPS (@bm, @partchangebm) }
  16941.     
  16942.     /* See if a column used in a join filter changed */
  16943.     if @joinchangebm = 0x0
  16944.         set @joinchange = 0
  16945.     else
  16946.         set @joinchange= { fn INTERSECTBITMAPS (@bm, @joinchangebm) }
  16947.     
  16948.     select @tablenick = ' + @tablenickchar + '
  16949.     exec dbo.sp_MSgetreplnick @nickname = @nick output
  16950.     select @ccols = ' + @ccolchar + '
  16951.     ' + @cvstr1 + '
  16952.     if @joinchange = 1
  16953.         begin
  16954.         update ' + @viewname + ' set lineage = { fn UPDATELINEAGE(lineage, @nick) }, generation = @newgen, joinchangegen = @newgen, ' + @cvstr2 + ' 
  16955.             FROM inserted as I JOIN ' + @viewname + ' as V ON (I.rowguidcol=V.rowguid)
  16956.             where tablenick = @tablenick 
  16957.         if @@error <> 0
  16958.             GOTO FAILURE 
  16959.             ' + @inscommand     
  16960.     set @command3 = '
  16961.         set @joingen = @newgen
  16962.         set @partgen = @newgen
  16963.         end
  16964.     else if @partchange = 1
  16965.         begin
  16966.         set @partgen = @newgen
  16967.         set @joingen = NULL
  16968.         update ' + @viewname + ' set lineage = { fn UPDATELINEAGE(lineage, @nick) }, generation = @newgen, partchangegen = @newgen, ' + @cvstr2 + ' 
  16969.             FROM inserted as I JOIN ' + @viewname + ' as V ON (I.rowguidcol=V.rowguid)
  16970.             where tablenick = @tablenick 
  16971.         if @@error <> 0
  16972.             GOTO FAILURE
  16973.             ' + @inscommand + '
  16974.         end
  16975.     else    
  16976.         begin
  16977.         set @partgen = NULL
  16978.         set @joingen = NULL
  16979.         update ' + @viewname + ' set lineage = { fn UPDATELINEAGE(lineage, @nick) }, generation = @newgen, ' + @cvstr2 + ' 
  16980.             FROM inserted as I JOIN ' +  @viewname + ' as V ON (I.rowguidcol=V.rowguid)
  16981.             where tablenick = @tablenick 
  16982.             
  16983.         if @@error <> 0
  16984.             GOTO FAILURE
  16985.         end
  16986.         
  16987.     insert into ' + @viewname + ' (tablenick, rowguid, lineage, colv1, generation, partchangegen, joinchangegen) 
  16988.         select @tablenick, rowguidcol, @lineage, @cv, @newgen, @partgen, @joingen from inserted where
  16989.             rowguidcol not in (select rowguid from ' + @viewname + ' where tablenick = @tablenick)
  16990.  
  16991.     if @@error <> 0
  16992.         GOTO FAILURE
  16993.     return
  16994. FAILURE:
  16995.                 if @@trancount > 0
  16996.                     rollback tran
  16997.                 raiserror (20041, 16, -1)
  16998.                 return
  16999.                     '
  17000.     execute (@command1 + @missingbmstr + '
  17001.         set @partchangebm = ' + @partchstr + '
  17002.         set @joinchangebm = ' + @joinchstr + '
  17003.             ' + @ifcol +  
  17004.             @command2 + @command3)
  17005.     if @@ERROR <> 0 
  17006.         begin
  17007.             raiserror(20064, 16, -1)
  17008.             return (1)
  17009.         end
  17010.     
  17011.     execute ('sp_MS_marksystemobject ''' + @trigname + '''')    
  17012. GO
  17013.  
  17014. --------------------------------------------------------------------------------
  17015. --. sp_MSaddmergetriggers
  17016. --------------------------------------------------------------------------------
  17017. if exists (select * from sysobjects    where type = 'P'
  17018.     and name = 'sp_MSaddmergetriggers')
  17019.     drop procedure sp_MSaddmergetriggers
  17020. go
  17021.  
  17022. raiserror('Creating procedure sp_MSaddmergetriggers', 0,1)
  17023. go
  17024.  
  17025. CREATE PROCEDURE sp_MSaddmergetriggers 
  17026.     @source_table         sysname,        /* was type varchar(92), table name */
  17027.     @column_tracking     int = NULL                /* Is column tracking on - default is FALSE */
  17028. AS
  17029.     set nocount on
  17030.     declare @command        nvarchar(4000)
  17031.     declare @command2 nvarchar(4000)
  17032.     declare @inscommand nvarchar(2000)
  17033.     declare @ifcoltracking     nvarchar(255)
  17034.     declare @tablenick         int    
  17035.     declare @nickname         int
  17036.     declare @artid             uniqueidentifier
  17037.     declare @guidstr        nvarchar(32)
  17038.     declare @owner             sysname
  17039.     declare @site             sysname
  17040.     declare @db             sysname
  17041.     declare @object         sysname
  17042.     declare @updtrigname         sysname
  17043.     declare @instrigname         sysname
  17044.     declare @deltrigname         sysname
  17045.     declare @ext             nvarchar(10)
  17046.     declare @ext2             nvarchar(10)
  17047.     declare @tablenickchar     nvarchar(11)
  17048.     declare @ccols             int
  17049.     declare @ccolchar         nvarchar(5)
  17050.     declare @retcode         int
  17051.     declare @objid            int
  17052.     declare @bitmap         varbinary(40)
  17053.     declare @missing_count    int
  17054.     declare @viewname        sysname
  17055.     declare @tsview            sysname
  17056.     
  17057.     set @bitmap = 0x0
  17058.     set @missing_count = 0
  17059.  
  17060.     -- PARSENAME VARS
  17061.     declare      @UnqualName      sysname  --rightmost name node
  17062.     declare      @QualName1       sysname  
  17063.     -- END PARSENAME VARS
  17064.  
  17065.  
  17066.     execute @retcode=sp_MSgetreplnick @nickname = @nickname output
  17067.     if @retcode<>0 or @@ERROR<>0 return (1)
  17068.  
  17069.     select @ext = 'ins_'
  17070.     select @ext2 = 'del_'
  17071.     set @objid =  OBJECT_ID(@source_table)
  17072.  
  17073.     -- set up the before image table if one is desired
  17074.     exec dbo.sp_MScreatebeforetable @objid
  17075.  
  17076.     -- Initialize string for inserting to before_image table
  17077.     exec sp_MSgetbeforetableinsert @objid, @inscommand output
  17078.  
  17079.     select @ccols =  count(*) from syscolumns where id = @objid  and iscomputed <> 1
  17080.     select @ccolchar = convert(nchar, @ccols)
  17081.  
  17082.     select @UnqualName = PARSENAME(@source_table, 1)
  17083.     select @QualName1 = PARSENAME(@source_table, 2)
  17084.     if @UnqualName IS NULL
  17085.          return 1
  17086.  
  17087.     if @QualName1 is NULL
  17088.          select @QualName1 = user_name(uid) from sysobjects where id = object_id(@UnqualName)
  17089.  
  17090.     -- fixup for variable length differences.  remove when vars expanded
  17091.     -- to new SQL SERVER 7.0 lengths
  17092.  
  17093.     select @owner = @QualName1
  17094.     select @object = @UnqualName
  17095.         
  17096.     execute @retcode=sp_MStablenickname @owner, @object, @tablenick output
  17097.     if @retcode<>0 or @@ERROR<>0 return (1)
  17098.     select @artid = artid from sysmergearticles 
  17099.         where objid = @objid
  17100.         
  17101.     /* If column tracking wasn't passed in, just figure it out */
  17102.     if @column_tracking is null
  17103.         select @column_tracking = column_tracking from sysmergearticles 
  17104.         where artid = @artid
  17105.         
  17106.     select @tablenickchar = convert(nchar, @tablenick)
  17107.     exec @retcode=sp_MSguidtostr @artid, @guidstr out
  17108.     if @retcode<>0 or @@ERROR<>0 return (1)
  17109.  
  17110.     /* Drop the article's replication triggers if they preexist */
  17111.     exec dbo.sp_MSdroparticletriggers @source_table
  17112.     if @@ERROR <> 0
  17113.         return 1
  17114.     
  17115.     -- owner name removed
  17116.     set @instrigname = @ext + @guidstr 
  17117.     set @deltrigname = @ext2 + @guidstr
  17118.     set @updtrigname = 'upd_' + @guidstr
  17119.     set @viewname = 'ctsv_' + @guidstr
  17120.     set @tsview = 'tsvw_' + @guidstr
  17121.     
  17122.     /* Make sure trigger name is unique */
  17123.     exec @retcode=sp_MSuniqueobjectname @instrigname, @instrigname output
  17124.     if @retcode<>0 or @@ERROR<>0 return (1)
  17125.     exec @retcode=sp_MSuniqueobjectname @deltrigname, @deltrigname output
  17126.     if @retcode<>0 or @@ERROR<>0 return (1)
  17127.     exec @retcode=sp_MSuniqueobjectname @updtrigname, @updtrigname output
  17128.     if @retcode<>0 or @@ERROR<>0 return (1)
  17129.  
  17130.     /* Create the view if it doesn't already exist. */
  17131.     if not exists (select * from sysobjects where type = 'V' and name = @viewname)
  17132.         begin
  17133.         exec @retcode=sp_MSuniqueobjectname @viewname, @viewname output
  17134.         if @retcode<>0 or @@ERROR<>0 return (1)
  17135.         set @command = 'create view dbo.' + @viewname + ' as
  17136.             select * from MSmerge_contents where
  17137.                 trigger_nestlevel(OBJECT_ID(''' + QUOTENAME(@owner) + '.'  + QUOTENAME(@instrigname) + ''')) > 0 or
  17138.                 trigger_nestlevel(OBJECT_ID(''' + QUOTENAME(@owner) + '.'  + QUOTENAME(@updtrigname) + ''')) > 0 or
  17139.                 trigger_nestlevel(OBJECT_ID(''' + QUOTENAME(@owner) + '.'  + QUOTENAME(@deltrigname) + ''')) > 0
  17140.                 with check option'
  17141.         execute (@command)
  17142.         if @@ERROR<>0 return (1)
  17143.         set @command = 'grant update, insert, select, delete on ' + @viewname + ' to public'
  17144.         execute (@command)
  17145.         if @@ERROR<>0 return (1)
  17146.         execute ('sp_MS_marksystemobject ''' + @viewname + '''')    
  17147.         if @@ERROR<>0 return (1)    
  17148.         end
  17149.  
  17150.     /* Create the view if it doesn't already exist. */
  17151.     if not exists (select * from sysobjects where type = 'V' and name = @tsview)
  17152.         begin
  17153.         exec @retcode=sp_MSuniqueobjectname @tsview, @tsview output
  17154.         if @retcode<>0 or @@ERROR<>0 return (1)
  17155.         set @command = 'create view dbo. ' + @tsview + ' as
  17156.             select * from MSmerge_tombstone where
  17157.                 trigger_nestlevel(OBJECT_ID(''' + QUOTENAME(@owner) + '.'  + QUOTENAME(@instrigname) + ''')) > 0 or
  17158.                 trigger_nestlevel(OBJECT_ID(''' + QUOTENAME(@owner) + '.'  + QUOTENAME(@updtrigname) + ''')) > 0 or
  17159.                 trigger_nestlevel(OBJECT_ID(''' + QUOTENAME(@owner) + '.'  + QUOTENAME(@deltrigname) + ''')) > 0
  17160.                 with check option'
  17161.         execute (@command)
  17162.         if @@ERROR<>0 return (1)
  17163.         set @command = 'grant update, insert, select, delete on ' + @tsview + ' to public'
  17164.         execute (@command)
  17165.         if @@ERROR<>0 return (1)        
  17166.         execute ('sp_MS_marksystemobject ''' + @tsview + '''')    
  17167.         if @@ERROR<>0 return (1)    
  17168.         end
  17169.         
  17170.     /* If column tracking is on, construct the string to initialize colv's */
  17171.     if (@column_tracking <> 0)
  17172.         -- select @ifcoltracking = '    execute master..xp_initcolvs @ccols, @nickname, @colv1 output'
  17173.         select @ifcoltracking = '    set @colv1 = { fn INITCOLVS(@ccols, @nickname) }'
  17174.     else
  17175.         select @ifcoltracking = '    set @colv1 = NULL'
  17176.         
  17177.     /* UNDONE maybe remove null guid checks in SQL SERVER 7.0 */
  17178.     select @command = 'create trigger ' + @instrigname + ' on ' + @source_table +
  17179.     ' for insert as 
  17180.     /* Declare variables */
  17181.     declare @tablenick int 
  17182.     declare @nickname int
  17183.     declare @lineage varbinary(255) 
  17184.     declare @colv1 varbinary(2048)
  17185.     declare @ccols int
  17186.     declare @retcode smallint
  17187.     declare @newgen int
  17188.     declare @version int
  17189.     declare @curversion int
  17190.     
  17191.     set nocount on
  17192.     set @tablenick = ' + @tablenickchar + '
  17193.     select @ccols = ' + @ccolchar + '
  17194.     set @lineage = 0x0
  17195.     set @retcode = 0
  17196.     select @newgen = gen_cur from sysmergearticles where nickname = @tablenick
  17197.     if @newgen is null
  17198.         set @newgen = 0
  17199.         
  17200.     execute dbo.sp_MSgetreplnick @nickname = @nickname output
  17201.     if (@@error <> 0)
  17202.         begin
  17203.         goto FAILURE
  17204.         end
  17205.     set @lineage = { fn UPDATELINEAGE (0x0, @nickname) }
  17206.     ' + @ifcoltracking + '
  17207.     if (@@error <> 0)
  17208.         begin
  17209.         goto FAILURE
  17210.         end
  17211.  
  17212.     select @version = max(convert(int, substring(lineage, 5, 1)) + 256 * 
  17213.         (convert(int, substring(lineage, 6, 1)) +  256 *
  17214.          (convert(int, substring(lineage, 7, 1)) + 256 *
  17215.           (convert(int, substring(lineage, 8, 1)))))) from ' + @tsview + ' where tablenick = @tablenick and rowguid in
  17216.         (select rowguidcol from inserted)
  17217.  
  17218.     if @version is not null
  17219.         begin
  17220.         -- reset lineage and colv to higher version...
  17221.         set @curversion = 0
  17222.         while (@curversion <= @version)
  17223.             begin
  17224.             set @lineage = { fn UPDATELINEAGE (@lineage, @nickname) }
  17225.             if (@colv1 IS NOT NULL)
  17226.                 set @colv1 = { fn UPDATECOLVBM(@colv1, @nickname, 0x01, 0x00) }
  17227.             set @curversion = @curversion + 1
  17228.             end
  17229.         
  17230.         delete from ' + @tsview + ' where tablenick = @tablenick and rowguid in
  17231.             (select rowguidcol from inserted)
  17232.         end
  17233.         
  17234.     insert into ' + @viewname + ' (tablenick, rowguid, lineage, colv1, generation, joinchangegen) select
  17235.         @tablenick, rowguidcol, @lineage, @colv1, @newgen, @newgen from inserted where rowguidcol not in
  17236.             (select rowguid from ' + @viewname + ' where tablenick = @tablenick)
  17237.     if @@error <> 0 
  17238.         goto FAILURE
  17239.     return
  17240. FAILURE:
  17241.                 if @@trancount > 0
  17242.                     rollback tran
  17243.                 raiserror (20041, 16, -1)
  17244.                 return
  17245.                     '
  17246.     execute (@command)
  17247.     if @@ERROR <> 0 
  17248.         begin
  17249.             raiserror(20065, 16, -1)
  17250.             return (1)
  17251.         end
  17252.     
  17253.     execute ('sp_MS_marksystemobject ''' + @instrigname + '''')    
  17254.  
  17255.     /* Call separate routine to add update trigger */
  17256.     exec @retcode=sp_MSaddupdatetrigger @source_table, @owner, @object, @artid, @column_tracking, @viewname
  17257.     if @retcode<>0 or @@ERROR<>0 return (1)
  17258.  
  17259.     /* Now make the delete trigger */
  17260.     -- NOTE: owner name removed
  17261.  
  17262.     /* Make sure trigger name is unique */
  17263.     exec @retcode = dbo.sp_MSuniqueobjectname @deltrigname, @deltrigname output
  17264.     if @retcode<>0 or @@ERROR<>0 return (1)
  17265.  
  17266.     set @command = 'create trigger ' + @deltrigname + ' on ' + @source_table +
  17267.     ' FOR DELETE AS
  17268.     /* Declare variables */
  17269.     declare @tablenick int
  17270.     declare @retcode smallint
  17271.     declare @reason nvarchar(255)
  17272.     declare @nickname int
  17273.     declare @lineage varbinary(255) 
  17274.     declare @newgen int
  17275.     
  17276.     set nocount on
  17277.     select @tablenick = ' + @tablenickchar + '
  17278.     select @newgen = gen_cur from sysmergearticles where nickname = @tablenick
  17279.     if @newgen is null
  17280.         set @newgen = 0
  17281.  
  17282.     select @reason = ''user delete''
  17283.     execute dbo.sp_MSgetreplnick @nickname = @nickname output
  17284.     if (@@error <> 0)
  17285.         begin
  17286.         goto FAILURE
  17287.         end
  17288.     '
  17289.     set @command2 = '
  17290.     set @lineage = { fn UPDATELINEAGE(0x0, @nickname) }
  17291.     
  17292.     insert into ' + @tsview + ' (rowguid, tablenick, type, lineage, generation, reason)
  17293.         select rowguidcol, @tablenick, 1, { fn UPDATELINEAGE(COALESCE(c.lineage, @lineage), @nickname) }, @newgen, @reason from 
  17294.             deleted d left outer join ' + @viewname + ' c on c.tablenick = @tablenick and c.rowguid = d.rowguidcol
  17295.     if @@error <> 0
  17296.         GOTO FAILURE
  17297.             
  17298.             
  17299.     delete from ' + @viewname + ' where tablenick = @tablenick and rowguid in 
  17300.         (select rowguidcol from deleted) 
  17301.     if @@error <> 0
  17302.         GOTO FAILURE
  17303.     return
  17304. FAILURE:
  17305.                 if @@trancount > 0
  17306.                     rollback tran
  17307.                 raiserror (20041, 16, -1)
  17308.                 return
  17309.                 '
  17310.         
  17311.     execute (@command + @inscommand + @command2)
  17312.     if @@ERROR <> 0 
  17313.         begin
  17314.             raiserror(20066, 16, -1)
  17315.             return (1)
  17316.         end
  17317.     execute ('sp_MS_marksystemobject ''' + @deltrigname + '''')    
  17318.  
  17319.     update sysmergearticles set missing_col_count = @missing_count,
  17320.         missing_cols = @bitmap where artid = @artid
  17321.     if @@ERROR<>0 return (1)    
  17322.     return (0)
  17323. GO
  17324.  
  17325. grant exec on dbo.sp_MSaddmergetriggers to public
  17326. go
  17327.  
  17328. --------------------------------------------------------------------------------
  17329. --.    Merge repl objects (rlrecon.sql)
  17330. --------------------------------------------------------------------------------
  17331. dump tran master with no_log
  17332. go
  17333. --------------------------------------------------------------------------------
  17334. --. sp_MSdrop_rlrecon
  17335. --------------------------------------------------------------------------------
  17336. if exists (select * from sysobjects    where type = 'P'
  17337.     and name = 'sp_MSdrop_rlrecon')
  17338.     drop procedure sp_MSdrop_rlrecon
  17339. go
  17340.  
  17341. raiserror('Creating procedure sp_MSdrop_rlrecon', 0,1)
  17342. go
  17343.  
  17344. create procedure sp_MSdrop_rlrecon
  17345. as
  17346.  
  17347.     if exists (select * from sysobjects
  17348.     where type = 'P'
  17349.         and name = 'sp_MSaddinitialpublication')
  17350.     drop procedure sp_MSaddinitialpublication
  17351.  
  17352.     if exists (select * from sysobjects
  17353.     where type = 'P'
  17354.         and name = 'sp_MSaddinitialsubscription')
  17355.     drop procedure sp_MSaddinitialsubscription
  17356.  
  17357.     if exists (select * from sysobjects
  17358.         where type = 'P'
  17359.             and name = 'sp_MSdropconstraints')
  17360.     drop procedure sp_MSdropconstraints
  17361.  
  17362.     if exists (select * from sysobjects
  17363.             where type = 'P'
  17364.                 and name = 'sp_MSexclause')
  17365.         drop procedure sp_MSexclause
  17366.     if exists (select * from sysobjects
  17367.             where type = 'P'
  17368.                 and name = 'sp_MSmakectsview')
  17369.         drop procedure sp_MSmakectsview
  17370.     if exists (select * from sysobjects
  17371.                 where type = 'P' and
  17372.                 name = 'sp_MSmakeinsertproc')
  17373.         drop procedure sp_MSmakeinsertproc
  17374.         
  17375.     if exists (select * from sysobjects
  17376.                 where type = 'P' and
  17377.                 name = 'sp_MSmakeupdateproc')
  17378.         drop procedure sp_MSmakeupdateproc 
  17379.         
  17380.     if exists (select * from sysobjects
  17381.                 where type = 'P' and
  17382.                 name = 'sp_MSmakeselectproc')
  17383.         drop procedure sp_MSmakeselectproc 
  17384.         
  17385.     if exists (select * from sysobjects
  17386.                 where type = 'P' and
  17387.                 name = 'sp_MSinitdynamicsubscriber')
  17388.         drop procedure sp_MSinitdynamicsubscriber 
  17389.  
  17390.     if exists (select * from sysobjects
  17391.             where type = 'P '
  17392.             and name = 'sp_MSinsertschemachange')
  17393.         drop procedure sp_MSinsertschemachange
  17394.  
  17395.     if exists (select * from sysobjects
  17396.             where type = 'P'
  17397.             and name = 'sp_MSaddinitialarticle')
  17398.         drop procedure sp_MSaddinitialarticle
  17399.         
  17400.         
  17401.     if exists (select * from sysobjects
  17402.                 where type = 'P' and
  17403.                 name = 'sp_MSmakearticleprocs')
  17404.         drop procedure sp_MSmakearticleprocs
  17405.  
  17406.     if exists (select * from sysobjects
  17407.         where type = 'P'
  17408.             and name = 'sp_MSupdatesysmergearticles')
  17409.         drop procedure sp_MSupdatesysmergearticles        
  17410.  
  17411.     if exists (select * from sysobjects
  17412.         where type = 'P'
  17413.             and name = 'sp_MSdroparticletombstones')
  17414.         drop procedure sp_MSdroparticletombstones        
  17415.  
  17416.     if exists (select * from sysobjects
  17417.         where type = 'P'
  17418.             and name = 'sp_MSproxiedmetadata')
  17419.         drop procedure sp_MSproxiedmetadata        
  17420.     
  17421.     if exists (select * from sysobjects
  17422.                 where type = 'P' and
  17423.                 name = 'sp_MShelpmergearticles')
  17424.         drop procedure sp_MShelpmergearticles
  17425.  
  17426.     if exists (select * from sysobjects
  17427.                 where type = 'P' and
  17428.                 name = 'sp_MScreateretry')
  17429.         drop procedure sp_MScreateretry
  17430.  
  17431.     if exists (select * from sysobjects
  17432.                 where type = 'P' and
  17433.                 name = 'sp_MSdropretry')
  17434.         drop procedure sp_MSdropretry
  17435.  
  17436.     if exists (select * from sysobjects
  17437.                 where type = 'P' and
  17438.                 name = 'sp_MSenumretries')
  17439.         drop procedure sp_MSenumretries
  17440.  
  17441.     if exists (select * from sysobjects
  17442.                 where type = 'P' and
  17443.                 name = 'sp_MSdeleteretry')
  17444.         drop procedure sp_MSdeleteretry
  17445.  
  17446.     if exists (select * from sysobjects
  17447.                 where type = 'P' and
  17448.                 name = 'sp_MSgetonerow')
  17449.         drop procedure sp_MSgetonerow
  17450.  
  17451.     if exists (select * from sysobjects
  17452.                 where type = 'P' and
  17453.                 name = 'sp_MSchangearticleresolver')
  17454.            drop procedure sp_MSchangearticleresolver
  17455.  
  17456.     if exists (select * from sysobjects
  17457.                 where type = 'P' and
  17458.                 name = 'sp_MSgetlastrecgen')
  17459.         drop procedure sp_MSgetlastrecgen
  17460.  
  17461.     if exists (select * from sysobjects
  17462.                 where type = 'P' and
  17463.                 name = 'sp_MSgetlastsentgen')
  17464.         drop procedure sp_MSgetlastsentgen
  17465.  
  17466.     if exists (select * from sysobjects
  17467.                 where type = 'P' and
  17468.                 name = 'sp_MSsetlastrecgen')
  17469.         drop procedure sp_MSsetlastrecgen
  17470.  
  17471.     if exists (select * from sysobjects
  17472.                 where type = 'P' and
  17473.                 name = 'sp_MSbelongs')
  17474.         drop procedure sp_MSbelongs
  17475.  
  17476.     if exists (select * from sysobjects
  17477.                 where type = 'P' and
  17478.                 name = 'sp_MSsetupbelongs')
  17479.         drop procedure sp_MSsetupbelongs
  17480.  
  17481.     if exists (select * from sysobjects
  17482.                 where type = 'P' and
  17483.                 name = 'sp_MSexpandbelongs')
  17484.         drop procedure sp_MSexpandbelongs
  17485.  
  17486.     if exists (select * from sysobjects
  17487.                 where type = 'P' and
  17488.                 name = 'sp_MSexpandnotbelongs')
  17489.         drop procedure sp_MSexpandnotbelongs
  17490.  
  17491.     if exists (select * from sysobjects
  17492.                 where type = 'P' and
  17493.                 name = 'sp_MSenumpartialdeletes')
  17494.         drop procedure sp_MSenumpartialdeletes
  17495.  
  17496.     if exists (select * from sysobjects
  17497.                 where type = 'P' and
  17498.                 name = 'sp_MSsetlastsentgen')
  17499.         drop procedure sp_MSsetlastsentgen
  17500.  
  17501.     if exists (select * from sysobjects
  17502.                 where type = 'P' and
  17503.                 name = 'sp_MSdummyupdate')
  17504.         drop procedure sp_MSdummyupdate 
  17505.  
  17506.     if exists (select * from sysobjects
  17507.                 where type = 'P' and
  17508.                 name = 'sp_MSdeletepushagent')
  17509.         drop procedure sp_MSdeletepushagent
  17510.         
  17511.     if exists (select * from sysobjects
  17512.                 where type = 'P' and
  17513.                 name = 'sp_MScleanuptask')
  17514.         drop procedure sp_MScleanuptask
  17515.  
  17516.     if exists (select * from sysobjects
  17517.                 where type = 'P' and
  17518.                 name = 'sp_MSenumgenerations')
  17519.         drop procedure sp_MSenumgenerations
  17520.  
  17521.     if exists (select * from sysobjects
  17522.                 where type = 'P' and
  17523.                 name = 'sp_MScheckexistsgeneration')
  17524.         drop procedure sp_MScheckexistsgeneration
  17525.  
  17526.     if exists (select * from sysobjects
  17527.                 where type = 'P' and
  17528.                 name = 'sp_MSenumreplicas')
  17529.         drop procedure sp_MSenumreplicas
  17530.  
  17531.     if exists (select * from sysobjects
  17532.                 where type = 'P' and
  17533.                 name = 'sp_MSenumdeletesmetadata')
  17534.         drop procedure sp_MSenumdeletesmetadata
  17535.  
  17536.     if exists (select * from sysobjects
  17537.                 where type = 'P' and
  17538.                 name = 'sp_MSenumchanges')
  17539.         drop procedure sp_MSenumchanges
  17540.     
  17541.     if exists (select * from sysobjects
  17542.                 where type = 'P' and
  17543.                 name = 'sp_MSenumpartialchanges')
  17544.         drop procedure sp_MSenumpartialchanges
  17545.  
  17546.  
  17547.     if exists (select * from sysobjects
  17548.                 where type = 'P' and
  17549.                 name = 'sp_MSgetrowmetadata')
  17550.         drop procedure sp_MSgetrowmetadata
  17551.     if exists (select * from sysobjects
  17552.                 where type = 'P' and
  17553.                 name = 'sp_MSgetmetadatabatch')
  17554.         drop procedure sp_MSgetmetadatabatch
  17555.  
  17556.     if exists (select * from sysobjects
  17557.                 where type = 'P' and
  17558.                 name = 'sp_MSsetrowmetadata')
  17559.         drop procedure sp_MSsetrowmetadata
  17560.  
  17561.     if exists (select * from sysobjects
  17562.                 where type = 'P' and
  17563.                 name = 'sp_MSinsertgenhistory')
  17564.         drop procedure sp_MSinsertgenhistory
  17565.  
  17566.     if exists (select * from sysobjects
  17567.                 where type = 'P' and
  17568.                 name = 'sp_MSupdategenhistory')
  17569.         drop procedure sp_MSupdategenhistory
  17570.  
  17571.     if exists (select * from sysobjects
  17572.                 where type = 'P' and
  17573.                 name = 'sp_MSenumschemachange')
  17574.         drop procedure sp_MSenumschemachange
  17575.  
  17576.     if exists (select * from sysobjects
  17577.                 where type = 'P' and
  17578.                 name = 'sp_MSupdateschemachange')
  17579.         drop procedure sp_MSupdateschemachange
  17580.  
  17581.     if exists (select * from sysobjects
  17582.             where type = 'P'
  17583.                 and name = 'sp_MSadd_mergereplcommand')
  17584.         drop procedure sp_MSadd_mergereplcommand
  17585.  
  17586.     if exists (select * from sysobjects
  17587.                 where type = 'P' and
  17588.                 name = 'sp_MSsetreplicainfo')
  17589.         drop procedure sp_MSsetreplicainfo
  17590.  
  17591.     if exists (select * from sysobjects
  17592.                 where type = 'P' and
  17593.                 name = 'sp_MSsetreplicastatus')
  17594.         drop procedure sp_MSsetreplicastatus
  17595.  
  17596.     if exists (select * from sysobjects
  17597.         where type = 'P'
  17598.             and name = 'sp_MScreateglobalreplica')
  17599.         drop procedure sp_MScreateglobalreplica
  17600.  
  17601.     if exists (select * from sysobjects
  17602.             where type = 'P'
  17603.                 and name = 'sp_MSsetconflictscript')
  17604.         drop procedure sp_MSsetconflictscript
  17605.  
  17606.     if exists (select * from sysobjects
  17607.             where type = 'P'
  17608.                 and name = 'sp_MSsetconflicttable')
  17609.         drop procedure sp_MSsetconflicttable
  17610.  
  17611.     if exists (select * from sysobjects
  17612.                 where type = 'P' and
  17613.                 name = 'sp_MSmakeconflictinsertproc')
  17614.         drop procedure sp_MSmakeconflictinsertproc
  17615.  
  17616.     if exists (select * from sysobjects
  17617.                 where type = 'P' and
  17618.                 name = 'sp_MSmaketempinsertproc')
  17619.         drop procedure sp_MSmaketempinsertproc
  17620.  
  17621.     if exists (select * from sysobjects
  17622.             where type = 'P'
  17623.                 and name = 'sp_MSgetconflictinsertproc')
  17624.         drop procedure sp_MSgetconflictinsertproc
  17625.  
  17626.     if exists (select * from sysobjects
  17627.                 where type = 'P' and
  17628.                 name = 'sp_MSinsertdeleteconflict')
  17629.         drop procedure sp_MSinsertdeleteconflict
  17630.  
  17631.     if exists (select * from sysobjects
  17632.                 where type = 'P' and
  17633.                 name = 'sp_MScheckmetadatamatch')
  17634.         drop procedure sp_MScheckmetadatamatch
  17635.  
  17636.     if exists (select * from sysobjects
  17637.                 where type = 'P' and
  17638.                 name = 'sp_MSdelrow')
  17639.         drop procedure sp_MSdelrow 
  17640.  
  17641.     if exists (select * from sysobjects
  17642.                 where type = 'P' and
  17643.                 name = 'sp_MSsetartprocs')
  17644.         drop procedure sp_MSsetartprocs
  17645.  
  17646.     if exists (select * from sysobjects
  17647.             where type = 'P'
  17648.                 and name = 'sp_MSmakesystableviews')
  17649.         drop procedure sp_MSmakesystableviews
  17650.  
  17651.     if exists (select * from sysobjects
  17652.             where type = 'P'
  17653.                 and name = 'sp_MSgetchangecount')
  17654.         drop procedure sp_MSgetchangecount
  17655.  
  17656.     if exists (select * from sysobjects
  17657.             where type = 'P'
  17658.                 and name = 'sp_MSuplineageversion')
  17659.         drop procedure sp_MSuplineageversion
  17660.  
  17661.     if exists (select * from sysobjects
  17662.             where type = 'P'
  17663.                 and name = 'sp_MSvalidatearticle')
  17664.         drop procedure sp_MSvalidatearticle
  17665.     if exists (select * from sysobjects
  17666.             where type = 'P'
  17667.                 and name = 'sp_MSsubscriptionvalidated')
  17668.         drop procedure sp_MSsubscriptionvalidated
  17669.         
  17670.     if exists (select * from sysobjects
  17671.             where type = 'P'
  17672.                 and name = 'sp_MSdelsubrows')
  17673.         drop procedure sp_MSdelsubrows
  17674.  
  17675.     if exists (select * from sysobjects
  17676.             where type = 'P'
  17677.                 and name = 'sp_MScontractsubsnb')
  17678.         drop procedure sp_MScontractsubsnb
  17679.  
  17680.     if exists (select * from sysobjects
  17681.             where type = 'P'
  17682.                 and name = 'sp_MSexpandsubsnb')
  17683.         drop procedure sp_MSexpandsubsnb
  17684.  
  17685.     if exists (select * from sysobjects
  17686.             where type = 'P'
  17687.                 and name = 'sp_MSmakeviewproc')
  17688.         drop procedure sp_MSmakeviewproc
  17689.  
  17690.     if exists (select * from sysobjects
  17691.             where type = 'P' and
  17692.                 name = 'sp_MScreatebeforetable')
  17693.         drop procedure sp_MScreatebeforetable 
  17694.  
  17695.     if exists (select * from sysobjects
  17696.             where type = 'P' and
  17697.                 name = 'sp_MShelpcreatebeforetable')
  17698.         drop procedure sp_MShelpcreatebeforetable 
  17699.  
  17700.     if exists (select * from sysobjects
  17701.             where type = 'P' and
  17702.                 name = 'sp_MShelpalterbeforetable')
  17703.         drop procedure sp_MShelpalterbeforetable 
  17704.  
  17705.     if exists (select * from sysobjects
  17706.             where type = 'P' and
  17707.                 name = 'sp_MSgetbeforetableinsert')
  17708.         drop procedure sp_MSgetbeforetableinsert 
  17709.  
  17710.     if exists (select * from sysobjects
  17711.             where type = 'P'
  17712.                 and name = 'sp_MSfixlineagemismatch')
  17713.         drop procedure sp_MSfixlineagemismatch
  17714.  
  17715.     if exists (select * from sysobjects
  17716.             where type = 'P' and
  17717.                 name = 'sp_MSinsertgenerationschemachanges')
  17718.         drop procedure sp_MSinsertgenerationschemachanges 
  17719.  
  17720. go
  17721.  
  17722. --------------------------------------------------------------------------------
  17723. --. sp_changemergepublication
  17724. --------------------------------------------------------------------------------
  17725. if exists (select * from sysobjects
  17726.     where type = 'P '
  17727.             and name = 'sp_changemergepublication')
  17728.     drop procedure sp_changemergepublication
  17729. GO
  17730.  
  17731. raiserror('Creating procedure sp_changemergepublication', 0,1)
  17732. GO
  17733.  
  17734. CREATE PROCEDURE sp_changemergepublication (
  17735.     @publication sysname,              /* Publication name */
  17736.     @property sysname = NULL,          /* The property to change */
  17737.     @value nvarchar(255) = NULL             /* The new property value */
  17738.     ) AS
  17739.  
  17740.     SET NOCOUNT ON
  17741.  
  17742.     /*
  17743.     ** Declarations.
  17744.     */
  17745.  
  17746.     declare @cmd                nvarchar(255)
  17747.     declare @pubid              uniqueidentifier
  17748.     declare @pubidstr           nvarchar(38)
  17749.     declare @retcode            int
  17750.     declare @retention          int
  17751.     declare @statusid           tinyint
  17752.     declare @sync_modeid        tinyint
  17753.     declare @distributor        sysname
  17754.     declare @distproc           nvarchar(255)
  17755.     declare @value_bit          bit
  17756.     declare @subscribed         int
  17757.     declare @dbname             sysname
  17758.     declare @distribdb          sysname
  17759.  
  17760.     declare @schemaversion      int 
  17761.     declare @schemaguid         uniqueidentifier
  17762.     declare @schematype         int
  17763.     declare @schematext         nvarchar(2000)
  17764.     declare @artid                uniqueidentifier
  17765.  
  17766.     /*
  17767.     ** Initializations
  17768.     */
  17769.     select @subscribed = 1
  17770.  
  17771.     /*
  17772.     ** Security Check
  17773.     */
  17774.  
  17775.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  17776.     IF @@ERROR <> 0 or @retcode <> 0
  17777.         return (1)
  17778.  
  17779.     /* 
  17780.     ** Check if current DB is enabled for publication/subscription
  17781.     */
  17782.     
  17783.     if not exists (select * from sysobjects where name = 'sysmergepublications')
  17784.             BEGIN
  17785.                 RAISERROR (20054, 16, -1)
  17786.                 RETURN (1)
  17787.             END
  17788.             
  17789.     /*
  17790.     ** Parameter Check:  @property.
  17791.     ** If the @property parameter is NULL, print the options.
  17792.     */
  17793.     if @property IS NULL
  17794.         BEGIN
  17795.             CREATE TABLE #tab1 (properties sysname)
  17796.             INSERT INTO #tab1 VALUES ('description')
  17797.             INSERT INTO #tab1 VALUES ('status')
  17798.             INSERT INTO #tab1 VALUES ('retention')
  17799.             INSERT INTO #tab1 VALUES ('sync_mode')
  17800.             INSERT INTO #tab1 VALUES ('allow_push')
  17801.             INSERT INTO #tab1 VALUES ('allow_pull')
  17802.             INSERT INTO #tab1 VALUES ('allow_anonymous')
  17803.             INSERT INTO #tab1 VALUES ('enabled_for_internet')
  17804.             INSERT INTO #tab1 VALUES ('centralized_conflicts')
  17805.             INSERT INTO #tab1 VALUES ('snapshot_ready')
  17806.             select * FROM #tab1
  17807.             RETURN (0)
  17808.         END
  17809.  
  17810.     if @value is NULL and LOWER(@property) not in ('description', 'retention')
  17811.         begin
  17812.             RAISERROR (20081, 16, -1, @property)
  17813.             RETURN (1)
  17814.         end
  17815.  
  17816.     /*
  17817.     ** Parameter Check:  @publication.
  17818.     ** Make sure that the publication exists.
  17819.     */
  17820.  
  17821.     if @publication IS NULL
  17822.         BEGIN
  17823.             RAISERROR (14043, 16, -1, '@publication')
  17824.             RETURN (1)
  17825.         END
  17826.  
  17827.     select @pubid = pubid FROM sysmergepublications 
  17828.         WHERE name = @publication  and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name()
  17829.     set @pubidstr = '''' + convert(nchar(36), @pubid) + ''''
  17830.  
  17831.     if @pubid IS NULL
  17832.         BEGIN
  17833.             RAISERROR (20026, 16, -1, @publication)
  17834.             RETURN (1)
  17835.         END
  17836.     else
  17837.  
  17838.     /*
  17839.     ** Parameter Check:  @property.
  17840.     ** Check to make sure that @property is a valid property in
  17841.     ** sysmergepublications.
  17842.     */
  17843.     if LOWER(@property) NOT IN ('description', 'status', 'retention', 'sync_mode', 'allow_push', 
  17844.         'allow_pull', 'allow_anonymous', 'enabled_for_internet', 'centralized_conflicts', 'snapshot_ready')
  17845.         BEGIN
  17846.             RAISERROR (21053, 16, -1)
  17847.             RETURN (1)
  17848.         END
  17849.  
  17850.     BEGIN TRAN sp_changemergepublication    
  17851.  
  17852.     /*
  17853.     ** Change the property.
  17854.     */
  17855.  
  17856.     if LOWER(@property) IN ('description')
  17857.         BEGIN
  17858.             UPDATE sysmergepublications  SET description = @value WHERE pubid = @pubid
  17859.             if @@ERROR <> 0 GOTO UNDO
  17860.         END
  17861.  
  17862.   
  17863.     if LOWER(@property) = 'status'
  17864.         BEGIN
  17865.  
  17866.             /*
  17867.             ** Check to make sure that we have a valid status.
  17868.             */
  17869.  
  17870.             if LOWER(@value) NOT IN ('active', 'inactive')
  17871.                 BEGIN
  17872.                     RAISERROR (14012, 16, -1)
  17873.                     GOTO UNDO
  17874.                 END
  17875.  
  17876.             /*
  17877.             ** Determine the integer value for the status.
  17878.             */
  17879.  
  17880.             if LOWER(@value) = 'active'
  17881.                 select @statusid = 1
  17882.             else
  17883.                 select @statusid = 0
  17884.  
  17885.             /*
  17886.             ** Update the publication with the new status.
  17887.             */
  17888.  
  17889.             UPDATE sysmergepublications SET status = @statusid WHERE pubid = @pubid
  17890.  
  17891.             if @@ERROR <> 0 GOTO UNDO
  17892.  
  17893.             /*
  17894.             ** If setting to inactive, allow articles / join filters to be altered, and
  17895.             ** clear the snapshot ready bit as well.
  17896.             */
  17897.             if @statusid = 0
  17898.                 begin
  17899.                 UPDATE sysmergepublications SET snapshot_ready = 0 WHERE pubid = @pubid
  17900.                 if @@ERROR <> 0 GOTO UNDO
  17901.                 UPDATE sysmergearticles SET status = 1 WHERE pubid = @pubid
  17902.                 if @@ERROR <> 0 GOTO UNDO
  17903.                 end
  17904.         END
  17905.  
  17906.  
  17907.     if LOWER(@property) = 'retention'
  17908.         BEGIN
  17909.         /*
  17910.         ** Update the publication with the new replication frequency.
  17911.         */
  17912.  
  17913.         select @retention = CONVERT(int, @value)
  17914.  
  17915.         if @retention is NULL 
  17916.             select @retention = 0
  17917.  
  17918.            if @retention < 0
  17919.                begin
  17920.                    raiserror(20050, 16, -1, 0)
  17921.                    GOTO UNDO
  17922.                end
  17923.  
  17924.         UPDATE sysmergepublications SET retention = @retention WHERE pubid = @pubid
  17925.         if @@ERROR <> 0 
  17926.             GOTO UNDO
  17927.  
  17928.         select @schemaversion = schemaversion from sysmergeschemachange
  17929.         if (@schemaversion is NULL)
  17930.             set @schemaversion = 1
  17931.         else
  17932.             select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange
  17933.             
  17934.         set @schemaguid = newid()
  17935.         set @artid = newid()
  17936.         set @schematype = 9 /* change retention */
  17937.         select @schematext = 'exec dbo.sp_MSchange_retention '+ '''' + convert(nchar(36),@pubid) + '''' + ',' + '''' + @value + ''''          
  17938.         exec @retcode=sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext
  17939.             if @@ERROR<>0 or @retcode<>0 goto UNDO    
  17940.         END
  17941.  
  17942.  
  17943.     if LOWER(@property) = 'sync_mode'
  17944.         BEGIN
  17945.  
  17946.             /*
  17947.             ** Check for a valid synchronization method.
  17948.             */
  17949.  
  17950.             if LOWER(@value) NOT IN ('native', 'character', 'bcp native', 'bcp character')
  17951.                 begin
  17952.                 raiserror (20076, 16, -1)
  17953.                 GOTO UNDO
  17954.                 end
  17955.  
  17956.             /*
  17957.             ** Determine the integer value for the sync_mode.
  17958.             */
  17959.             if LOWER(@value) IN ('native', 'bcp native')
  17960.                 select @sync_modeid = 0
  17961.             else if LOWER(@value) IN ('character', 'bcp character')
  17962.                 select @sync_modeid = 1
  17963.  
  17964.             /*
  17965.             ** Update the publication with the new synchronization method.
  17966.             */
  17967.  
  17968.             UPDATE sysmergepublications
  17969.                SET sync_mode = @sync_modeid
  17970.              WHERE pubid = @pubid
  17971.  
  17972.             if @@ERROR <> 0 GOTO UNDO
  17973.         END
  17974.  
  17975.     if LOWER(@property) IN ('allow_push', 'allow_pull', 'allow_anonymous', 'enabled_for_internet',
  17976.         'centralized_conflicts', 'snapshot_ready')
  17977.     BEGIN
  17978.  
  17979.         /*
  17980.         ** Check for a valid  value.
  17981.         */
  17982.  
  17983.         if LOWER(@value) NOT IN ('true', 'false')
  17984.         BEGIN
  17985.             RAISERROR (14137, 16, -1)
  17986.             GOTO UNDO
  17987.         END
  17988.  
  17989.         /*
  17990.         ** set value bit
  17991.         */
  17992.         if LOWER(@value) = 'true'
  17993.             select @value_bit = 1
  17994.         else 
  17995.             select @value_bit = 0
  17996.  
  17997.  
  17998.         if LOWER(@property) = 'allow_anonymous'
  17999.         BEGIN
  18000.             /* Update the allow_anonymous column */
  18001.             UPDATE sysmergepublications 
  18002.                 SET allow_anonymous = @value_bit
  18003.                 WHERE pubid = @pubid
  18004.             if @@error <> 0
  18005.             BEGIN
  18006.                GOTO UNDO
  18007.             END
  18008.  
  18009.         END
  18010.  
  18011.         if LOWER(@property) = 'allow_push'
  18012.         BEGIN
  18013.             /* Update the allow_push column */
  18014.             UPDATE sysmergepublications 
  18015.                 SET allow_push = @value_bit
  18016.                 WHERE pubid = @pubid
  18017.             if @@error <> 0
  18018.             BEGIN
  18019.                GOTO UNDO
  18020.             END
  18021.         END
  18022.  
  18023.         if LOWER(@property) = 'allow_pull'
  18024.         BEGIN
  18025.  
  18026.             /* Update the allow_pull column */
  18027.             UPDATE sysmergepublications 
  18028.                 SET allow_pull = @value_bit
  18029.                 WHERE pubid = @pubid
  18030.             if @@error <> 0
  18031.             BEGIN
  18032.                GOTO UNDO
  18033.             END
  18034.         END
  18035.  
  18036.         if LOWER(@property) = 'centralized_conflicts'
  18037.         BEGIN
  18038.             /* Update the centralized_conflicts column */
  18039.             UPDATE sysmergepublications 
  18040.                 SET centralized_conflicts = @value_bit
  18041.                 WHERE pubid = @pubid
  18042.             if @@error <> 0
  18043.             BEGIN
  18044.                GOTO UNDO
  18045.             END
  18046.  
  18047.         END
  18048.  
  18049.         if LOWER(@property) = 'enabled_for_internet'
  18050.         BEGIN
  18051.             /* Update the enabled_for_internet column */
  18052.             UPDATE sysmergepublications 
  18053.                 SET enabled_for_internet = @value_bit
  18054.                 WHERE pubid = @pubid
  18055.             if @@error <> 0
  18056.             BEGIN
  18057.                GOTO UNDO
  18058.             END
  18059.  
  18060.         END
  18061.  
  18062.         if LOWER(@property) = 'snapshot_ready'
  18063.         BEGIN
  18064.             /* Update the allow_anonymous column */
  18065.             UPDATE sysmergepublications 
  18066.                 SET snapshot_ready = @value_bit
  18067.                 WHERE pubid = @pubid
  18068.             if @@error <> 0
  18069.             BEGIN
  18070.                GOTO UNDO
  18071.             END
  18072.  
  18073.         END
  18074.     END
  18075.  
  18076.     /*
  18077.     ** Update merge publication property at distributor side if necessaray 
  18078.     */
  18079.     
  18080.     IF LOWER(@property) IN ('description','allow_push', 'allow_pull', 'allow_anonymous','retention')
  18081.  
  18082.         BEGIN
  18083.  
  18084.         IF LOWER(@property) IN ('allow_push', 'allow_pull', 'allow_anonymous')
  18085.             
  18086.         /* Translate values */
  18087.         BEGIN            
  18088.             IF LOWER(@value) = 'true'
  18089.                 SELECT @value = '1'
  18090.             ELSE IF LOWER(@value) = 'false'
  18091.                     SELECT @value = '0'
  18092.         END
  18093.                 
  18094.         /*
  18095.         ** Get distribution server information for remote RPC call.
  18096.         */
  18097.         EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  18098.            @distribdb   = @distribdb OUTPUT
  18099.         IF @@ERROR <> 0 or @retcode <> 0
  18100.             BEGIN
  18101.                 GOTO UNDO
  18102.             END
  18103.  
  18104.         SELECT @dbname =  DB_NAME()
  18105.         
  18106.         SELECT @distproc = RTRIM(@distributor) + '.' + @distribdb + 
  18107.             '.dbo.sp_MSchange_publication'
  18108.     
  18109.         EXECUTE @retcode = @distproc
  18110.             @publisher = @@SERVERNAME,
  18111.             @publisher_db = @dbname,
  18112.             @publication = @publication,
  18113.             @property = @property,
  18114.             @value = @value
  18115.  
  18116.         IF @@ERROR <> 0 OR @retcode <> 0
  18117.         BEGIN
  18118.             GOTO UNDO
  18119.         END
  18120.     END
  18121.  
  18122.     COMMIT TRAN
  18123.  
  18124.     /*
  18125.     ** Return succeed.
  18126.     */
  18127.     
  18128.     RAISERROR (14077, 10, -1)
  18129.     RETURN (0)
  18130.  
  18131. UNDO: 
  18132.     IF @@TRANCOUNT = 1
  18133.         ROLLBACK TRAN
  18134.     ELSE COMMIT TRAN
  18135. GO
  18136.     
  18137.  
  18138. go
  18139. exec dbo.sp_MS_marksystemobject sp_changemergepublication 
  18140. go
  18141.  
  18142. grant execute on dbo.sp_changemergepublication to public
  18143. go
  18144.  
  18145.  
  18146.  
  18147. --------------------------------------------------------------------------------
  18148. --. sp_MSchange_retention
  18149. --------------------------------------------------------------------------------
  18150. if exists (select * from sysobjects
  18151.     where type = 'P '
  18152.             and name = 'sp_MSchange_retention')
  18153.     drop procedure sp_MSchange_retention
  18154. GO
  18155.  
  18156. raiserror('Creating procedure sp_MSchange_retention', 0,1)
  18157. GO
  18158.  
  18159. -- @value has to be unicode too.
  18160.  
  18161. CREATE PROCEDURE sp_MSchange_retention (@pubid uniqueidentifier, @value nvarchar(255))
  18162. as
  18163.     update sysmergepublications set retention = convert(int, @value) where pubid = @pubid
  18164. go
  18165. grant execute on dbo.sp_MSchange_retention to public
  18166. GO
  18167.  
  18168. --------------------------------------------------------------------------------
  18169. --. sp_MScleanup_metadata
  18170. --------------------------------------------------------------------------------
  18171. if exists (select * from sysobjects
  18172.     where type = 'P '
  18173.             and name = 'sp_MScleanup_metadata')
  18174.     drop procedure sp_MScleanup_metadata
  18175. GO
  18176.  
  18177. raiserror('Creating procedure sp_MScleanup_metadata', 0,1)
  18178. GO
  18179.  
  18180. create procedure sp_MScleanup_metadata
  18181. @pubid            uniqueidentifier
  18182. AS
  18183.  
  18184. declare @retcode         int
  18185.  
  18186.     /*
  18187.     ** Security Check
  18188.     */
  18189.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  18190.     IF @@ERROR <> 0 or @retcode <> 0
  18191.         return (1)
  18192.     delete from MSmerge_contents where tablenick in (select nickname from sysmergearticles where pubid=@pubid)
  18193.     delete from MSmerge_tombstone where tablenick in (select nickname from sysmergearticles where pubid=@pubid)    
  18194. GO
  18195. grant execute on dbo.sp_MScleanup_metadata to public
  18196. go
  18197.  
  18198. --------------------------------------------------------------------------------
  18199. --. sp_MSsetconflictscript
  18200. --------------------------------------------------------------------------------
  18201. if exists (select * from sysobjects    where type = 'P'
  18202.     and name = 'sp_MSsetconflictscript')
  18203.     drop procedure sp_MSsetconflictscript
  18204. go
  18205.  
  18206. raiserror('Creating procedure sp_MSsetconflictscript', 0,1)
  18207. GO
  18208.  
  18209. CREATE PROCEDURE sp_MSsetconflictscript (
  18210.     @publication        sysname,
  18211.     @article            sysname,
  18212.     @conflict_script    nvarchar(255),
  18213.     @login                sysname =NULL,
  18214.     @password            sysname =NULL
  18215.     ) AS
  18216.  
  18217.     declare @artid uniqueidentifier
  18218.     declare @pubid uniqueidentifier
  18219.     DECLARE @osql_cmd1 nvarchar (255)
  18220.     DECLARE @osql_cmd_full varchar (255)
  18221.  
  18222.     DECLARE @install_path varchar (255)
  18223.     declare @db_name        sysname
  18224.     
  18225.     /*
  18226.     ** Check for publish permission.
  18227.     */
  18228.     declare @retcode int
  18229.     exec @retcode=sp_MSreplcheck_publish
  18230.     if @retcode<>0 or @@ERROR<>0 return (1)
  18231.     
  18232.     select @pubid = pubid from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@@SERVERNAME) and publisher_db=db_name()
  18233.     if @pubid IS NULL
  18234.         BEGIN
  18235.             RAISERROR (20026, 16, -1, @publication)
  18236.             RETURN (1)
  18237.         END
  18238.     
  18239.     select @artid = artid FROM sysmergearticles WHERE name = @article    AND pubid = @pubid
  18240.     if @artid IS NULL
  18241.         BEGIN
  18242.             RAISERROR (20027, 16, -1, @article)
  18243.             RETURN (1)
  18244.         END
  18245.  
  18246.     update sysmergearticles set conflict_script = @conflict_script where artid = @artid
  18247.     if @@ERROR <> 0
  18248.         return (1)
  18249.  
  18250.     /* if there is already a conflict table, don't run script */
  18251.     if exists (select * from sysmergearticles where artid = @artid and OBJECT_ID(conflict_table) is null)
  18252.         BEGIN
  18253.  
  18254.         /* Run the script and create the conflict table */
  18255.         EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
  18256.                   'SOFTWARE\Microsoft\MSSQLServer\Setup',
  18257.                   'SQLPath',
  18258.                 @param = @install_path OUTPUT
  18259.         IF @@ERROR<> 0 OR @retcode <> 0 or @install_path is NULL or @install_path=''
  18260.             return (1)
  18261.  
  18262.         IF @login is NULL
  18263.             SELECT @osql_cmd1 = @install_path + '\binn\osql -E ' 
  18264.         ELSE
  18265.             -- cannot specify -S w/ -E for local execution, SID does not map due to nofix bug
  18266.             SELECT @osql_cmd1 = @install_path + '\binn\osql -U' + @login + ' -P' + 
  18267.                 isnull(@password,'') + ' -S' + @@SERVERNAME + ' '
  18268.         select @osql_cmd1 = @osql_cmd1 + '-l30 -t30 '
  18269.         set @db_name = db_name()
  18270.  
  18271.         SELECT @osql_cmd_full = @osql_cmd1 + 
  18272.             ' -d"' + @db_name +  '" -b ' +
  18273.             ' -i"' + @conflict_script + '"'  +
  18274.             ' -o"' + @install_path + '\install\conflict.out' + '"'
  18275.  
  18276.         EXEC @retcode = master..xp_cmdshell @osql_cmd_full
  18277.         IF @@ERROR<> 0 OR @retcode <> 0
  18278.             return (1)
  18279.         END
  18280.         
  18281.     /* Create the conflict insert proc */
  18282.     if exists (select * from sysmergearticles where artid = @artid and OBJECT_ID(ins_conflict_proc) is null)
  18283.         BEGIN
  18284.         exec dbo.sp_MSgetconflictinsertproc @artid = @artid, @output = 0
  18285.         IF @@ERROR<> 0 OR @retcode <> 0
  18286.             return (1)
  18287.         END
  18288.     return (0)
  18289. go
  18290. grant exec on dbo.sp_MSsetconflictscript to public
  18291. go
  18292.  
  18293.  
  18294. --------------------------------------------------------------------------------
  18295. --. sp_MSenumschemachange
  18296. --------------------------------------------------------------------------------
  18297. if exists (select * from sysobjects    where type = 'P'
  18298.     and name = 'sp_MSenumschemachange')
  18299.     drop procedure sp_MSenumschemachange
  18300. go
  18301.  
  18302. raiserror('Creating procedure sp_MSenumschemachange', 0,1)
  18303. GO
  18304.  
  18305. CREATE PROCEDURE sp_MSenumschemachange(
  18306.     @pubid             uniqueidentifier,
  18307.     @schemaversion     int,
  18308.     @compatibility_level int = 7000000 -- for 70 RTM and 70 SP1; SP2 and up will pass in a bigger value
  18309.     )
  18310. as
  18311.  
  18312.     /*
  18313.     ** To public
  18314.     */
  18315.     
  18316.     if (@schemaversion is null)
  18317.         begin
  18318.         RAISERROR(14043, 16, -1, '@schemaversion')
  18319.         return (1)
  18320.         end
  18321.  
  18322.     if (not exists(select * from sysobjects where name = 'MSmerge_contents'))
  18323.         begin
  18324.         RAISERROR(20054 , 16, -1)
  18325.         return (1)
  18326.         end
  18327.  
  18328.     /*
  18329.     ** For 70 RTM and SP1, we want to filter out type 9 (retention propagation) and 16 (metadata cleanup)
  18330.     ** and 5 ( last rec generation ) and 6 (last sent generation)
  18331.     ** which they do not support. SP2 subscriber will be passing in 7000200, which gets all schema types
  18332.     ** SP2 publishers have to offer
  18333.     */
  18334.     select pubid, artid, schemaversion, schemaguid, schematype, schematext
  18335.          from sysmergeschemachange where schemaversion > @schemaversion 
  18336.              and pubid = @pubid and (@compatibility_level>7000000 or (schematype not in (5, 6, 9, 16)))
  18337.                  order by schemaversion         
  18338.                  
  18339.     return (0)
  18340. go
  18341. grant exec on dbo.sp_MSenumschemachange to public
  18342. go
  18343.  
  18344.  
  18345. --------------------------------------------------------------------------------
  18346. --. sp_MShelpmergearticles
  18347. --------------------------------------------------------------------------------
  18348. if exists (select * from sysobjects    where type = 'P'
  18349.     and name = 'sp_MShelpmergearticles')
  18350.     drop procedure sp_MShelpmergearticles
  18351. go
  18352.  
  18353. raiserror('Creating procedure sp_MShelpmergearticles', 0,1)
  18354. go
  18355.  
  18356. CREATE PROCEDURE sp_MShelpmergearticles @publication sysname
  18357. as
  18358.     declare @pubid uniqueidentifier
  18359.  
  18360.     /*
  18361.     ** To public.
  18362.     */
  18363.     
  18364.     if (@publication is null)
  18365.         begin
  18366.         RAISERROR(14003, 16, -1)
  18367.         return (1)
  18368.         end
  18369.     if (not exists(select * from sysobjects where name = 'MSmerge_contents'))
  18370.         begin
  18371.         RAISERROR(20054 , 16, -1)
  18372.         return (1)
  18373.         end
  18374.     
  18375.     select @pubid = pubid from sysmergepublications
  18376.         where name = @publication and UPPER(publisher)=UPPER(@@SERVERNAME) and publisher_db=db_name()
  18377.  
  18378.     if (@pubid is null)
  18379.         begin
  18380.         RAISERROR (20026, 11, -1, @publication)
  18381.         return (1)
  18382.         end
  18383.         
  18384.     create table #helpmergearticles
  18385.         (
  18386.             art_name                sysname         NOT NULL,
  18387.             table_name                sysname            NOT NULL,
  18388.             table_owner                sysname         NOT NULL,
  18389.             artid                    uniqueidentifier NOT NULL,
  18390.             pre_creation_command    tinyint         NULL, 
  18391.             pubid                    uniqueidentifier NOT NULL,
  18392.             nickname                int                NOT NULL,
  18393.             column_tracking         int             NOT NULL,
  18394.             status                  tinyint         NULL,
  18395.             resolver_clsid            nvarchar(50)    NULL,
  18396.             conflict_script            nvarchar(255)    NULL,
  18397.             conflict_table          nvarchar(258)   NULL,
  18398.             insert_proc                sysname            NULL,
  18399.             update_proc                sysname            NULL,
  18400.             select_proc                sysname            NULL,
  18401.             destination_object        sysname            NULL,
  18402.             missing_col_count        int                NULL,
  18403.             missing_cols            varbinary(128)    NULL,
  18404.             rowguid_colname            sysname            NOT NULL,
  18405.             article_resolver        nvarchar(255)    NULL,
  18406.             resolver_info           nvarchar(255)   NULL,
  18407.              subset_filterclause        nvarchar(1000)  NULL,
  18408.             has_join                int                NULL
  18409.         )
  18410.    INSERT INTO #helpmergearticles 
  18411.         (art_name, 
  18412.         table_name,
  18413.         table_owner, 
  18414.         artid,
  18415.         pre_creation_command, 
  18416.         pubid,
  18417.         nickname,
  18418.         column_tracking,
  18419.         status,
  18420.         resolver_clsid,
  18421.         conflict_script,
  18422.         conflict_table,
  18423.         insert_proc,
  18424.         update_proc,
  18425.         select_proc,
  18426.         destination_object,
  18427.         missing_col_count,
  18428.         missing_cols,
  18429.         rowguid_colname,
  18430.         article_resolver,
  18431.         resolver_info,
  18432.         subset_filterclause)(
  18433.            select a.name, o.name, user_name(o.uid), a.artid, a.pre_creation_command, a.pubid, a.nickname, 
  18434.         a.column_tracking, a.status, a.resolver_clsid, a.conflict_script, a.conflict_table,
  18435.         a.insert_proc, a.update_proc, a.select_proc, a.destination_object, a.missing_col_count, a.missing_cols, c.name, 
  18436.         a.article_resolver, a.resolver_info, a.subset_filterclause
  18437.         from sysmergearticles a, 
  18438.             sysobjects o left outer join syscolumns c
  18439.             on o.id = c.id and ColumnProperty(o.id, c.name, 'IsRowGuidCol') = 1
  18440.         where a.pubid = @pubid 
  18441.             and o.id = a.objid )
  18442.     update #helpmergearticles set has_join = 1 where nickname in
  18443.         (select join_nickname from sysmergesubsetfilters)
  18444.  
  18445.     select * from #helpmergearticles order by nickname 
  18446.     return (0)
  18447. go
  18448.  
  18449. grant exec on dbo.sp_MShelpmergearticles to public
  18450. go
  18451. --------------------------------------------------------------------------------
  18452. --. sp_MSmakesystableviews
  18453. --------------------------------------------------------------------------------
  18454. if exists (select * from sysobjects    where type = 'P'
  18455.     and name = 'sp_MSmakesystableviews')
  18456.     drop procedure sp_MSmakesystableviews
  18457. go
  18458.  
  18459. raiserror('Creating procedure sp_MSmakesystableviews', 0,1)
  18460. GO
  18461.  
  18462. create procedure sp_MSmakesystableviews
  18463.     (@publication sysname)
  18464. AS
  18465.     declare @guidstr         nvarchar(40)
  18466.     declare @pubid          uniqueidentifier
  18467.     declare @contentsview     sysname 
  18468.     declare @tombstoneview     sysname
  18469.     declare @genhistoryview    sysname
  18470.     declare @filtersview    sysname
  18471.     declare @retcode smallint
  18472.     declare @dbname            sysname
  18473.     declare    @command        nvarchar(500)
  18474.     
  18475.     /*
  18476.     ** Check to see if current publication has permission
  18477.     */
  18478.     exec @retcode=sp_MSreplcheck_publish
  18479.     if @retcode<>0 or @@ERROR<>0 return (1)
  18480.     
  18481.     select @pubid = pubid from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@@SERVERNAME) and publisher_db=db_name()
  18482.     if @pubid is null
  18483.         BEGIN
  18484.             RAISERROR (20026, 16, -1, @publication)
  18485.             RETURN (1)
  18486.         END
  18487.  
  18488.     exec @retcode = dbo.sp_MSguidtostr @pubid, @guidstr out
  18489.     if @@ERROR<>0 OR @retcode<>0 return (1)
  18490.     select @contentsview = 'cont' + @guidstr
  18491.     select @tombstoneview = 'ts' + @guidstr
  18492.     select @genhistoryview = 'gh' + @guidstr
  18493.     select @filtersview = 'filt' + @guidstr
  18494.  
  18495.     set @guidstr = '''' + convert(nchar(36), @pubid) + ''''
  18496.     
  18497.     exec @retcode = dbo.sp_MSuniqueobjectname @tombstoneview, @tombstoneview out
  18498.     if @@ERROR<>0 OR @retcode<>0 return (1)
  18499.     exec @retcode = dbo.sp_MSuniqueobjectname @contentsview, @contentsview out
  18500.     if @@ERROR<>0 OR @retcode<>0 return (1)
  18501.     exec @retcode = dbo.sp_MSuniqueobjectname @genhistoryview, @genhistoryview out
  18502.     if @@ERROR<>0 OR @retcode<>0 return (1)
  18503.     exec @retcode = dbo.sp_MSuniqueobjectname @filtersview, @filtersview out
  18504.     if @@ERROR<>0 OR @retcode<>0 return (1)
  18505.  
  18506.     /* generate view for MSmerge_contents qualified by the pubid */
  18507.     set @command = 'sp_MSmakectsview ' + QUOTENAME(@publication) + ' , ' + @contentsview
  18508.     set @dbname = db_name()
  18509.  
  18510.     exec @retcode = master..xp_execresultset @command, @dbname
  18511.     if @@ERROR<>0 OR @retcode <>0 return (1)
  18512.  
  18513.     /* 
  18514.     ** generate the view for MSmerge_tombstone. In SP2, the change was made to make the view 
  18515.     ** return 0 rows since it is unnecessary and expensive to propagate the tombstones.
  18516.     ** In order to leave all the other moving parts unchanged, we decided to let the view 
  18517.     ** return 0 rows.
  18518.     */
  18519.     exec ('create view ' + @tombstoneview + ' as select * from MSmerge_tombstone where 1 = 2 and
  18520.             tablenick in (select nickname from sysmergearticles where convert(nchar(36), pubid) = ' +
  18521.             @guidstr + ')')
  18522.     if @@ERROR <>0 
  18523.         begin
  18524.             return (1)
  18525.         end
  18526.  
  18527.     exec ('create view ' + @genhistoryview + '(guidsrc, guidlocal, pubid, generation,
  18528.             art_nick, nicknames, coldate) as select DISTINCT guidsrc, guidlocal, CONVERT(uniqueidentifier, ' 
  18529.             + @guidstr + '), generation, art_nick, nicknames, coldate  from MSmerge_genhistory
  18530.             where guidlocal <> ''00000000-0000-0000-0000-000000000000'' and (art_nick = 0 or art_nick is NULL or
  18531.                     art_nick in (select nickname from sysmergearticles where convert(nchar(36), pubid) = ' +
  18532.             @guidstr + ')) ')
  18533.     if @@ERROR <>0
  18534.         begin
  18535.             return (1)
  18536.         end
  18537.  
  18538.     exec ('create view ' + @filtersview + ' as select * from sysmergesubsetfilters where convert(nchar(36), pubid) = ' +
  18539.             @guidstr)
  18540.     if @@ERROR <>0
  18541.         begin
  18542.             return (1)
  18543.         end
  18544.  
  18545.     set nocount on
  18546.     select @contentsview, @tombstoneview, @genhistoryview, @filtersview
  18547.     return (0)
  18548. go
  18549.  
  18550. grant exec on dbo.sp_MSmakesystableviews to public
  18551. go
  18552.  
  18553. --------------------------------------------------------------------------------
  18554. --. sp_MSmakectsview
  18555. --------------------------------------------------------------------------------
  18556. if exists (select * from sysobjects    where type = 'P'
  18557.     and name = 'sp_MSmakectsview')
  18558.     drop procedure sp_MSmakectsview
  18559. go
  18560.  
  18561. raiserror('Creating procedure sp_MSmakectsview', 0,1)
  18562. GO
  18563.  
  18564. create procedure sp_MSmakectsview
  18565.     @publication sysname,
  18566.     @ctsview     sysname
  18567. AS
  18568.     declare @pubid          uniqueidentifier
  18569.     declare @pubidstr        nvarchar(40)
  18570.     declare @objid        int
  18571.     declare @tablenick    int
  18572.     declare @tablenickstr nvarchar(12)
  18573.     declare @command_piece nvarchar(2000)
  18574.     declare @rowguidcolname sysname
  18575.     declare @view_type    int
  18576.     declare    @view_name  sysname
  18577.     declare @union_after_first nvarchar(100)
  18578.  
  18579.     set @union_after_first = ''
  18580.  
  18581.     select @pubid = pubid from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@@SERVERNAME) and publisher_db=db_name()
  18582.     set @pubidstr = '''' + convert(nchar(36), @pubid) + ''''
  18583.     /* Check for the no filtering cases */
  18584.     if not exists (select * from sysmergesubsetfilters where pubid = @pubid) and
  18585.        not exists (select * from sysmergearticles where pubid = @pubid and
  18586.                        len(subset_filterclause) > 0)
  18587.            begin
  18588.         set @command_piece = 'create view ' + @ctsview + ' as select * from MSmerge_contents '
  18589.         /* Are there any published tables not in this publication? */
  18590.         if exists (select * from sysmergearticles where pubid <> @pubid and
  18591.                    nickname not in (select nickname from sysmergearticles where pubid = @pubid))
  18592.             set @command_piece = @command_piece + ' where tablenick in
  18593.                     (select nickname from sysmergearticles where convert(nchar(36), pubid) = ' + @pubidstr + ')'
  18594.         /* Now select our simple view syntax and we are done with this simple unfiltered case */
  18595.         select @command_piece
  18596.         return 0
  18597.            end
  18598.     /* create temp table to insert into and select commands out of */
  18599.     create table #tempcmd (phase int NOT NULL, step int identity NOT NULL, cmdtext nvarchar(4000) NULL)
  18600.  
  18601.     set @command_piece = 'create view ' + @ctsview + ' as '
  18602.     insert into #tempcmd (phase, cmdtext) values (1, @command_piece)
  18603.  
  18604.     /* Initialize for loop over articles in this publication */
  18605.     select @tablenick = min(nickname) from sysmergearticles where pubid = @pubid
  18606.     while @tablenick is not null
  18607.         begin
  18608.         select @objid = objid, @view_type = view_type, @view_name = object_name(sync_objid) from 
  18609.             sysmergearticles where pubid = @pubid and nickname = @tablenick
  18610.         select @rowguidcolname = name from syscolumns where id = @objid and
  18611.                 columnproperty(id, name, 'isrowguidcol')=1
  18612.  
  18613.         set @rowguidcolname = QUOTENAME(@rowguidcolname)
  18614.         set @view_name = QUOTENAME(@view_name)
  18615.         set @tablenickstr = convert(nchar(12), @tablenick)
  18616.         
  18617.         if @view_type <> 0
  18618.             set @command_piece = @union_after_first + ' select * from MSmerge_contents where
  18619.                 tablenick = ' + @tablenickstr + ' and rowguid in
  18620.                     (select ' + @rowguidcolname + ' from ' + @view_name + ')'
  18621.         else
  18622.             set @command_piece = @union_after_first + ' select * from MSmerge_contents where
  18623.                 tablenick = ' + @tablenickstr
  18624.  
  18625.         insert into #tempcmd (phase, cmdtext) values (2, @command_piece)
  18626.         
  18627.         /* Advance to next article and repeat the loop */
  18628.         select @tablenick = min(nickname) from sysmergearticles where
  18629.             pubid = @pubid and nickname > @tablenick
  18630.  
  18631.         /* make it so that any subsequent selects in the view are preceded by the word UNION */
  18632.         set @union_after_first = ' UNION ALL '
  18633.         end
  18634.         
  18635.     /* final steps: select out the text and drop the temp table */
  18636.         
  18637.     select cmdtext from #tempcmd order by phase, step
  18638.     drop table #tempcmd
  18639. go
  18640.  
  18641. exec dbo.sp_MS_marksystemobject sp_MSmakectsview
  18642. go
  18643. grant execute on dbo.sp_MSmakectsview to public
  18644. go
  18645.  
  18646. --------------------------------------------------------------------------------
  18647. --. sp_MSdummyupdate
  18648. --------------------------------------------------------------------------------
  18649. if exists (select * from sysobjects    where type = 'P'
  18650.     and name = 'sp_MSdummyupdate')
  18651.     drop procedure sp_MSdummyupdate
  18652. go
  18653.  
  18654. raiserror('Creating procedure sp_MSdummyupdate', 0,1)
  18655. go
  18656.  
  18657. CREATE PROCEDURE sp_MSdummyupdate
  18658.     (@rowguid uniqueidentifier, @tablenick int, @metatype tinyint, @pubid uniqueidentifier = NULL, @uplineage tinyint = 1)
  18659. as
  18660.     declare @retcode int
  18661.     declare @lineage varbinary(255)
  18662.     declare @mynickname int
  18663.     declare @objid int
  18664.     declare @col_tracking int
  18665.     declare @ccols int
  18666.     declare @missing_count int
  18667.     declare @colv varbinary(2048)
  18668.  
  18669.     /*
  18670.     ** Check to see if current publication has permission
  18671.     */
  18672.     exec @retcode=sp_MSreplcheck_connection
  18673.         @tablenick = @tablenick
  18674.     if @retcode<>0 or @@ERROR<>0 return (1)
  18675.     
  18676.     /* Parameter checks */
  18677.     if (@rowguid is null)
  18678.         begin
  18679.         RAISERROR(14043, 16, -1, '@rowguid')
  18680.         return (1)
  18681.         end
  18682.     if (@tablenick is null)
  18683.         begin
  18684.         RAISERROR(14043, 16, -1, '@tablenick')
  18685.         return (1)
  18686.         end
  18687.     if (@metatype is null)
  18688.         begin
  18689.         RAISERROR(14043, 16, -1, '@metatype')
  18690.         return (1)
  18691.         end
  18692.  
  18693.     /* Check if we have a merge publication by whether system table is there */
  18694.     if (not exists(select * from sysobjects where name = 'MSmerge_contents'))
  18695.         begin
  18696.         RAISERROR(20054 , 16, -1)
  18697.         return (1)
  18698.         end
  18699.  
  18700.     exec dbo.sp_MSgetreplnick @nickname = @mynickname out
  18701.     if (@@error <> 0) or @mynickname IS NULL 
  18702.         begin
  18703.         RAISERROR (14055, 11, -1)
  18704.         RETURN(1)
  18705.         end                 
  18706.  
  18707.     if (@metatype = 0) or @@ERROR<>0
  18708.         begin
  18709.         declare @reason nvarchar(255)
  18710.         /* We don't have the row.  Putting in a system delete tombstone should cause a delete and
  18711.         ** eventual convergence.  We are already logging the row as a conflict / error.
  18712.         */
  18713.         set @lineage = { fn UPDATELINEAGE(0x0, @mynickname) }
  18714.         select @reason = formatmessage(20562)
  18715.     
  18716.         insert into MSmerge_tombstone (rowguid, tablenick, type, lineage, generation, reason) 
  18717.             values (@rowguid, @tablenick, 6, @lineage, 0, @reason)
  18718.         
  18719.         end
  18720.     else if (@metatype = 1)
  18721.         begin
  18722.         /* Update systombstone */
  18723.         select @lineage = lineage from MSmerge_tombstone (UPDLOCK ROWLOCK index = 1) where tablenick = @tablenick and
  18724.             rowguid = @rowguid
  18725.         if (@uplineage = 1)
  18726.             begin
  18727.             set @lineage = { fn UPDATELINEAGE(@lineage, @mynickname) }
  18728.             end
  18729.         update MSmerge_tombstone set generation = 0, lineage = @lineage where
  18730.             tablenick = @tablenick and rowguid = @rowguid
  18731.         end
  18732.     else if (@metatype = 2)
  18733.         begin
  18734.         /* Update MSmerge_contents */
  18735.         select @lineage = lineage, @colv = colv1 from MSmerge_contents (UPDLOCK ROWLOCK index = 1) where tablenick = @tablenick and
  18736.             rowguid = @rowguid
  18737.         if (@uplineage = 1)
  18738.             begin
  18739.             set @lineage = { fn UPDATELINEAGE(@lineage, @mynickname) }
  18740.             if @pubid is NULL
  18741.                 select @objid = objid, @col_tracking = column_tracking, @missing_count = missing_col_count
  18742.                  from sysmergearticles where nickname = @tablenick
  18743.             else
  18744.                 select @objid = objid, @col_tracking = column_tracking, @missing_count = missing_col_count
  18745.                      from sysmergearticles where nickname = @tablenick and pubid = @pubid
  18746.             if (@col_tracking = 0 or @colv is NULL)
  18747.                 set @colv = NULL
  18748.             else
  18749.                 set @colv = { fn UPDATECOLVBM(@colv, @mynickname, 0x01, 0x00) }
  18750.             
  18751.             end
  18752.         update MSmerge_contents set generation = 0, lineage = @lineage, colv1 = @colv where
  18753.             tablenick = @tablenick and rowguid = @rowguid
  18754.         end
  18755.     else if (@metatype = 3)
  18756.         begin
  18757.         set @lineage = { fn UPDATELINEAGE(0x0, @mynickname) }
  18758.         if @pubid is NULL
  18759.             select @objid = objid, @col_tracking = column_tracking, @missing_count = missing_col_count
  18760.                  from sysmergearticles where nickname = @tablenick
  18761.         else
  18762.             select @objid = objid, @col_tracking = column_tracking, @missing_count = missing_col_count
  18763.                  from sysmergearticles where nickname = @tablenick and pubid = @pubid
  18764.         if (@col_tracking = 0)
  18765.             set @colv = NULL
  18766.         else
  18767.             begin
  18768.             select @ccols= count(*) from syscolumns where id = @objid
  18769.             set @ccols = @ccols + @missing_count
  18770.             set @colv = { fn INITCOLVS(@ccols, @mynickname ) }
  18771.             end
  18772.         insert into MSmerge_contents (tablenick, rowguid, lineage, generation, colv1)
  18773.             values (@tablenick, @rowguid, @lineage, 0, @colv)
  18774.  
  18775.         end
  18776.     return (0)
  18777. go
  18778.  
  18779. grant exec on dbo.sp_MSdummyupdate to public
  18780. go
  18781.  
  18782. --------------------------------------------------------------------------------
  18783. --. sp_mergecleanupmetadata
  18784. --------------------------------------------------------------------------------
  18785. if exists (select * from sysobjects    where type = 'P'
  18786.     and name = 'sp_mergecleanupmetadata')
  18787.     drop procedure sp_mergecleanupmetadata
  18788. go
  18789.  
  18790. raiserror('Creating procedure sp_mergecleanupmetadata', 0,1)
  18791. go
  18792.  
  18793. create procedure sp_mergecleanupmetadata
  18794.     @publication                sysname = '%',
  18795.     @reinitialize_subscriber    nvarchar(5) = 'true'
  18796. AS
  18797. declare @pubid            uniqueidentifier
  18798. declare @retcode        int
  18799. declare @pubname          sysname
  18800. declare @snapshot_ready int
  18801.  
  18802. declare @artid                  uniqueidentifier
  18803. declare @schematype             int
  18804. declare @schemaversion          int
  18805. declare @schemaguid             uniqueidentifier
  18806. declare @schematext             nvarchar(2000)
  18807.  
  18808. /*
  18809. ** Security Check
  18810. */
  18811. EXEC @retcode = dbo.sp_MSreplcheck_publish
  18812. IF @@ERROR <> 0 or @retcode <> 0
  18813.     return (1)
  18814.  
  18815. if not exists (select * from sysobjects where name='sysmergearticles')
  18816.     return (1)
  18817.     
  18818. begin TRAN
  18819. declare #per_publication CURSOR LOCAL FAST_FORWARD for select pubid
  18820.     from sysmergepublications where LOWER(publisher)=LOWER(@@SERVERNAME) and publisher_db=db_name() and name like @publication
  18821. open #per_publication
  18822. fetch #per_publication into @pubid
  18823. while @@fetch_status<>-1
  18824. begin
  18825.     select @pubname=name, @snapshot_ready=snapshot_ready from sysmergepublications where pubid=@pubid
  18826.     if @publication <> '%' and exists (select * from sysmergearticles where pubid<>@pubid and objid in
  18827.         (select objid from sysmergearticles where pubid=@pubid))
  18828.     begin
  18829.         raiserror(21287, 16, -1, @pubname)
  18830.         goto FAILURE
  18831.     end
  18832.  
  18833.     /* Only do this when snapshot has been ran before this operation */
  18834.     if @snapshot_ready>0
  18835.     begin
  18836.         if LOWER(@reinitialize_subscriber)='true'
  18837.         begin
  18838.             exec @retcode = sp_reinitmergesubscription @publication=@pubname
  18839.             if @@ERROR<>0 or @retcode<>0
  18840.             begin
  18841.                 close #per_publication
  18842.                 deallocate #per_publication
  18843.                 goto FAILURE
  18844.             end
  18845.             update sysmergepublications set snapshot_ready=2 where pubid=@pubid
  18846.             if @@ERROR<>0
  18847.             begin
  18848.                 close #per_publication
  18849.                 deallocate #per_publication
  18850.                 goto FAILURE
  18851.             end
  18852.         end
  18853.         else
  18854.         begin
  18855.             select @schemaversion = schemaversion from sysmergeschemachange
  18856.             if (@schemaversion is NULL)
  18857.             set @schemaversion = 1
  18858.             else
  18859.                 select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange
  18860.             set @schemaguid = newid()
  18861.             set @artid = newid()
  18862.             set @schematype = 16 /* metadata cleanup */
  18863.             select @schematext = 'exec dbo.sp_MScleanup_metadata '+ '''' + convert(nchar(36),@pubid) + '''' 
  18864.             exec @retcode=sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext
  18865.             if @@ERROR<>0 or @retcode<>0 
  18866.             begin
  18867.                 close #per_publication
  18868.                 deallocate #per_publication
  18869.                 goto FAILURE            
  18870.             end
  18871.         end
  18872.     end
  18873.     
  18874.     delete from MSmerge_contents where tablenick in (select nickname from sysmergearticles where pubid=@pubid)
  18875.     delete from MSmerge_tombstone where tablenick in (select nickname from sysmergearticles where pubid=@pubid)    
  18876.     fetch next from #per_publication into @pubid
  18877. end
  18878. close #per_publication
  18879. deallocate #per_publication
  18880. COMMIT TRAN
  18881. return (0)
  18882. FAILURE:
  18883.     if @@TRANCOUNT = 1 
  18884.         ROLLBACK TRANSACTION 
  18885.     else
  18886.         COMMIT TRANSACTION 
  18887.     return (1)
  18888.  
  18889. GO
  18890. exec dbo.sp_MS_marksystemobject sp_mergecleanupmetadata
  18891. go
  18892. grant execute on dbo.sp_mergecleanupmetadata to public
  18893. go
  18894.  
  18895. --------------------------------------------------------------------------------
  18896. --. sp_MScleanuptask
  18897. --------------------------------------------------------------------------------
  18898. if exists (select * from sysobjects    where type = 'P'
  18899.     and name = 'sp_MScleanuptask')
  18900.     drop procedure sp_MScleanuptask
  18901. go
  18902.  
  18903. raiserror('Creating procedure sp_MScleanuptask', 0,1)
  18904. go
  18905.  
  18906. CREATE PROCEDURE sp_MScleanuptask
  18907.     (@pubid uniqueidentifier)
  18908. as
  18909.     /*
  18910.     ** Check to see if current publication has permission
  18911.     */
  18912.     declare @retention int
  18913.     declare @retcode int
  18914.     declare @before_name sysname
  18915.     declare @procname sysname
  18916.     
  18917.     exec @retcode=sp_MSreplcheck_connection
  18918.         @pubid = @pubid
  18919.     if @retcode<>0 or @@ERROR<>0 return (1)
  18920.     
  18921.     set nocount on
  18922.     if (@pubid is null)
  18923.         begin
  18924.         RAISERROR(14043, 16, -1, '@pubid')
  18925.         return (1)
  18926.         end
  18927.     if (not exists(select * from sysobjects where name = 'MSmerge_contents'))
  18928.         begin
  18929.         RAISERROR(20054 , 16, -1)
  18930.         return (1)
  18931.         end
  18932.     declare @cutoff datetime
  18933.  
  18934.     /*
  18935.     ** Bypass task cleanup if retention value is 0; Null value has been converted to 0
  18936.     */
  18937.     select @retention = retention from sysmergepublications where pubid = @pubid
  18938.     if @retention = 0 
  18939.         return (0)
  18940.     
  18941.     select @cutoff = dateadd(dd, -@retention, getdate())
  18942.     
  18943.     delete from MSmerge_genhistory where coldate < @cutoff
  18944.     declare @mingen int
  18945.     select @mingen = min(generation) from MSmerge_genhistory
  18946.     delete from MSmerge_tombstone where generation > 0 and generation < @mingen
  18947.     IF @@ERROR <>0 return (1)
  18948.     
  18949.     -- If there are any before image tables, clean them up too
  18950.     declare bi_cursor CURSOR LOCAL FAST_FORWARD for select distinct OBJECT_NAME(before_image_objid)
  18951.         from sysmergearticles where OBJECT_NAME(before_image_objid) is NOT NULL
  18952.     FOR READ ONLY
  18953.  
  18954.     open bi_cursor
  18955.  
  18956.     fetch next from bi_cursor into @before_name
  18957.     while (@@fetch_status <> -1)
  18958.         begin
  18959.         set @procname = @before_name + '_clean '
  18960.         exec @procname @mingen
  18961.         fetch next from bi_cursor into @before_name
  18962.         end
  18963.     close bi_cursor
  18964.     deallocate bi_cursor
  18965.  
  18966.     return (0)
  18967. go
  18968.  
  18969. grant exec on dbo.sp_MScleanuptask to public
  18970. go
  18971.  
  18972. --------------------------------------------------------------------------------
  18973. --. sp_MSenumdeletesmetadata
  18974. --------------------------------------------------------------------------------
  18975. if exists (select * from sysobjects    where type = 'P'
  18976.     and name = 'sp_MSenumdeletesmetadata')
  18977.     drop procedure sp_MSenumdeletesmetadata
  18978. go
  18979.  
  18980. raiserror('Creating procedure sp_MSenumdeletesmetadata', 0,1)
  18981. go
  18982.  
  18983. CREATE PROCEDURE sp_MSenumdeletesmetadata(
  18984.     @pubid         uniqueidentifier, 
  18985.     @maxrows     int, 
  18986.     @genlist     varchar(1000), 
  18987.     @tablenick     int, 
  18988.     @rowguid     uniqueidentifier,
  18989.     @filter_partialdeletes int = 0)
  18990. as
  18991.     declare @tnstring nvarchar(12)
  18992.     declare @rgstring nvarchar(38)
  18993.     declare @pubidstr nvarchar(38)
  18994.     declare @tablenick_qual nvarchar(100)
  18995.  
  18996.     /*
  18997.     ** To public.
  18998.     */
  18999.     
  19000.     if (@genlist is null)
  19001.         begin
  19002.         RAISERROR(14043, 16, -1, '@genlist')
  19003.         return (1)
  19004.         end
  19005.     if (not exists(select * from sysobjects where name = 'MSmerge_contents'))
  19006.         begin
  19007.         RAISERROR(20054 , 16, -1)
  19008.         return (1)
  19009.         end
  19010.             
  19011.     set @pubidstr = '''' + convert(nchar(36), @pubid) + ''''
  19012.  
  19013.     /* If the filter_partialdeletes is NOT set, include all types of tombstones, else filter the type = 5 ones */
  19014.     if (@filter_partialdeletes = 0)
  19015.         set @tablenick_qual = '    and ts.tablenick = sm.nickname '
  19016.     else
  19017.         set @tablenick_qual = '    and ts.tablenick = sm.nickname and ts.type <> 5'
  19018.     
  19019.  
  19020.     if (@tablenick = 0)
  19021.         begin
  19022.             set rowcount @maxrows
  19023.             execute ('select tablenick, rowguid, generation, lineage, ts.type from MSmerge_tombstone ts, sysmergearticles sm
  19024.                     where generation in (' + @genlist + ') 
  19025.                     and sm.pubid = ' + @pubidstr + @tablenick_qual + '
  19026.                     order by tablenick desc, rowguid asc' )
  19027.         end
  19028.     else
  19029.         begin
  19030.             set rowcount @maxrows
  19031.             set @tnstring = convert(nchar, @tablenick)
  19032.             set @rgstring = '''' + convert(nchar(36), @rowguid) + ''''
  19033.             execute ('select tablenick, rowguid, generation, lineage, ts.type from MSmerge_tombstone ts, sysmergearticles sm
  19034.                     where generation in (' + @genlist + ') and 
  19035.                         ((tablenick = ' + @tnstring + ' and 
  19036.                         rowguid > ' + @rgstring + ') or
  19037.                          tablenick < ' + @tnstring + ') 
  19038.                          and sm.pubid = ' + @pubidstr + @tablenick_qual + ' 
  19039.                          order by tablenick desc, rowguid asc' )
  19040.                 end
  19041.     IF @@ERROR <>0 
  19042.         begin
  19043.             return (1)     
  19044.         end
  19045.     return (0)
  19046. go
  19047.  
  19048. grant exec on dbo.sp_MSenumdeletesmetadata to public
  19049. go
  19050.  
  19051. --------------------------------------------------------------------------------
  19052. --. sp_MSenumpartialdeletes
  19053. --------------------------------------------------------------------------------
  19054. if exists (select * from sysobjects    where type = 'P'
  19055.     and name = 'sp_MSenumpartialdeletes')
  19056.     drop procedure sp_MSenumpartialdeletes
  19057. go
  19058.  
  19059. raiserror('Creating procedure sp_MSenumpartialdeletes', 0,1)
  19060. go
  19061.  
  19062. CREATE PROCEDURE sp_MSenumpartialdeletes
  19063.     (@maxrows int,
  19064.      @tablenick int,
  19065.      @rowguid uniqueidentifier,
  19066.      @tablenotbelongs nvarchar(255),
  19067.      @bookmark int = NULL)
  19068. as
  19069.  
  19070.     declare @tnstring         nvarchar(12)
  19071.     declare @rgstring         nvarchar(38)
  19072.     declare @lowrangestr     nvarchar(12) 
  19073.     declare @highrangestr     nvarchar(12) 
  19074.  
  19075.     /*
  19076.     ** To public.
  19077.     */
  19078.     
  19079.     if (not exists(select * from sysobjects where name = 'MSmerge_contents'))
  19080.         begin
  19081.         RAISERROR(20054 , 16, -1)
  19082.         return (1)
  19083.         end
  19084.  
  19085.     /* Always do the set rowcount, we never want to return too many rows */
  19086.     set rowcount @maxrows
  19087.  
  19088.     if (@tablenick < 1)
  19089.         begin
  19090.             execute ('select tablenick, rowguid, COALESCE (generation, 0), lineage, type, bookmark from ' + @tablenotbelongs + '
  19091.                     order by tablenick desc, rowguid asc' )
  19092.             IF @@ERROR <>0 
  19093.                 begin
  19094.                     return (1)     
  19095.                 end
  19096.         end
  19097.     else
  19098.         begin
  19099.             set @tnstring = convert(nchar, @tablenick)
  19100.             set @rgstring = '''' + convert(nchar(36), @rowguid) + ''''
  19101.             /* 
  19102.             ** If a 7.0 SP1 Merge agent is calling this sp, it passed a valid bookmark parameter 
  19103.             ** Use the bookmark column in the ##belongs_<> table to retrieve the next batch of rows
  19104.             */
  19105.             if @bookmark is NOT NULL
  19106.                 begin
  19107.                     set @lowrangestr = convert(nchar, @bookmark)
  19108.                     set @highrangestr = convert(nchar, (@bookmark + @maxrows))
  19109.                     execute ('select tablenick, rowguid, COALESCE (generation, 0), lineage, type, bookmark from ' + @tablenotbelongs + '
  19110.                             where  bookmark > ' + @lowrangestr + ' and bookmark <= ' + @highrangestr + '
  19111.                                  order by bookmark' )
  19112.                     if @@ERROR<>0
  19113.                         begin
  19114.                             return (1)
  19115.                         end                        
  19116.                 end
  19117.             /* 
  19118.             ** Backward copatibilty mode : If a 7.0 Merge agent is calling this sp, it will pass a NULL bookmark parameter 
  19119.             ** Use the rowguid and set rowcount to retrieve the next batch of rows
  19120.             */
  19121.             else
  19122.                 begin
  19123.                     execute ('select tablenick, rowguid, COALESCE (generation, 0), lineage, type from ' + @tablenotbelongs + '
  19124.                             where  ((tablenick = ' + @tnstring + ' and 
  19125.                                 rowguid > ' + @rgstring + ') or
  19126.                                  tablenick < ' + @tnstring + ') 
  19127.                                  order by tablenick desc, rowguid asc' )
  19128.                     IF @@ERROR <>0 
  19129.                         begin
  19130.                             return (1)     
  19131.                         end
  19132.                 end
  19133.         end
  19134.         
  19135.     return (0)
  19136. go        
  19137.  
  19138. grant exec on dbo.sp_MSenumpartialdeletes to public
  19139. go
  19140.  
  19141. --------------------------------------------------------------------------------
  19142. --. sp_MSenumpartialchanges
  19143. --------------------------------------------------------------------------------
  19144. if exists (select * from sysobjects    where type = 'P'
  19145.     and name = 'sp_MSenumpartialchanges')
  19146.     drop procedure sp_MSenumpartialchanges
  19147. go
  19148.  
  19149. raiserror('Creating procedure sp_MSenumpartialchanges', 0,1)
  19150. go
  19151.  
  19152. CREATE PROCEDURE sp_MSenumpartialchanges
  19153.     (@maxrows int, @temp_cont sysname, @tablenick int, @rowguid uniqueidentifier, @pubid uniqueidentifier = NULL)
  19154. as
  19155.     declare @retcode         smallint
  19156.     declare @tnstring         nvarchar(12)
  19157.     declare @rgstring         nvarchar(38)
  19158.     -- Owner qualified
  19159.     declare @tablename         nvarchar(266)
  19160.     declare @procname        nvarchar(258)
  19161.     declare @ownername        sysname
  19162.     /*
  19163.     ** To public.
  19164.     */
  19165.     
  19166.     if (@tablenick is null)
  19167.         begin
  19168.         RAISERROR(14043, 16, -1, '@tablenick')
  19169.         return (1)
  19170.         end
  19171.     exec @retcode = dbo.sp_MStablenamefromnick @tablenick, @tablename out, @pubid
  19172.         
  19173.     if @@ERROR<>0 or @retcode<>0 
  19174.         begin
  19175.             return (1)
  19176.         end    
  19177.     if (not exists(select * from sysobjects where name = 'MSmerge_contents'))
  19178.         begin
  19179.         RAISERROR(20054 , 16, -1)
  19180.         return (1)
  19181.         end
  19182.     set @tnstring = convert(nchar, @tablenick)
  19183.     set @rgstring = '''' + convert(nchar(36), @rowguid) + ''''
  19184.     create table #cont (tablenick int NOT NULL, rowguid uniqueidentifier NOT NULL, generation int NULL, lineage varbinary(249) NULL    ,colv1 varbinary(2048) NULL)
  19185.  
  19186.     set rowcount @maxrows
  19187.     execute ('insert into #cont 
  19188.                     select tablenick, rowguid, generation, lineage, colv from ' + @temp_cont + ' where
  19189.                             tablenick = ' + @tnstring + ' and rowguid > ' + @rgstring
  19190.                             + ' order by rowguid')
  19191.     if @@ERROR<>0
  19192.         begin
  19193.             return (1)
  19194.         end                        
  19195.  
  19196.  
  19197.     select @ownername = user_name(uid) from sysobjects where id = object_id(@tablename)    
  19198.     select @procname = select_proc from sysmergearticles where nickname=@tablenick and pubid = @pubid
  19199.     
  19200.     exec @retcode = @procname @type =3
  19201.     IF @@ERROR<>0 or @retcode<>0 RETURN (1)
  19202.     drop table #cont
  19203.     return (0)
  19204. go
  19205.  
  19206. grant exec on dbo.sp_MSenumpartialchanges to public
  19207. go
  19208.  
  19209. --------------------------------------------------------------------------------
  19210. --. sp_MSinitdynamicsubscriber
  19211. --------------------------------------------------------------------------------
  19212. if exists (select * from sysobjects    where type = 'P'
  19213.     and name = 'sp_MSinitdynamicsubscriber')
  19214.     drop procedure sp_MSinitdynamicsubscriber
  19215. go
  19216.  
  19217. raiserror('Creating procedure sp_MSinitdynamicsubscriber', 0,1)
  19218. go
  19219.  
  19220. CREATE PROCEDURE sp_MSinitdynamicsubscriber
  19221.     (@maxrows int, @tablenick int, @rowguid uniqueidentifier, @pubid uniqueidentifier = NULL)
  19222. as
  19223.     declare @retcode         smallint
  19224.     declare @procname        nvarchar(258)
  19225.     /*
  19226.     ** To public.
  19227.     */
  19228.     
  19229.     if (@tablenick is null)
  19230.         begin
  19231.         RAISERROR(14043, 16, -1, '@tablenick')
  19232.         return (1)
  19233.         end
  19234.     select @procname = view_sel_proc from sysmergearticles where
  19235.             pubid = @pubid and nickname = @tablenick
  19236.     exec @retcode = @procname @tablenick, @maxrows, @rowguid
  19237.     if @@ERROR<>0 or @retcode<>0 
  19238.         begin
  19239.             return (1)
  19240.         end    
  19241.     return (0)
  19242. go
  19243.  
  19244. grant exec on dbo.sp_MSinitdynamicsubscriber to public
  19245. go
  19246.  
  19247. --------------------------------------------------------------------------------
  19248. --. sp_MSgetrowmetadata
  19249. --------------------------------------------------------------------------------
  19250. if exists (select * from sysobjects    where type = 'P'
  19251.     and name = 'sp_MSgetrowmetadata')
  19252.     drop procedure sp_MSgetrowmetadata
  19253. go
  19254.  
  19255. raiserror('Creating procedure sp_MSgetrowmetadata', 0,1)
  19256. go
  19257.  
  19258. CREATE PROCEDURE sp_MSgetrowmetadata
  19259.     (@tablenick int,
  19260.      @rowguid uniqueidentifier,
  19261.      @generation int output,
  19262.      @type  tinyint output,
  19263.      @lineage varbinary(255) output,
  19264.      @colv varbinary(2048) output,
  19265.      @pubid uniqueidentifier = NULL)
  19266. as
  19267.     declare @retcode         smallint
  19268.     declare @saverr         int
  19269.     declare @rc             int
  19270.     declare @procname         nvarchar(258)
  19271.     declare @ownername        sysname
  19272.     
  19273.     /*
  19274.     ** To public.
  19275.     */
  19276.     
  19277.     
  19278.     if (@tablenick is null)
  19279.         begin
  19280.         RAISERROR(14043, 16, -1, '@tablenick')
  19281.         return (1)
  19282.         end
  19283.     if (@rowguid is null)
  19284.         begin
  19285.         RAISERROR(14043, 16, -1, '@rowguid')
  19286.         return (1)
  19287.         end
  19288.     if (not exists(select * from sysobjects where name = 'MSmerge_contents'))
  19289.         begin
  19290.         RAISERROR(20054 , 16, -1)
  19291.         return (1)
  19292.         end
  19293.     select @colv = null
  19294.     select @type = type, @generation = generation, @lineage = lineage from MSmerge_tombstone where
  19295.         tablenick = @tablenick and rowguid = @rowguid
  19296.     if (@lineage is null)
  19297.         begin
  19298.         select @type = 0
  19299.         select @generation = 0
  19300.         end
  19301.     if (@type = 0)
  19302.         begin
  19303.         declare @tablename nvarchar(266)
  19304.         exec @retcode = dbo.sp_MStablenamefromnick @tablenick, @tablename out, @pubid
  19305.         if @@ERROR<>0  
  19306.             begin
  19307.             return (1)
  19308.             end    
  19309.  
  19310.         select @ownername = user_name(uid) from sysobjects where id = object_id(@tablename)
  19311.         select @procname = select_proc from sysmergearticles where objid = object_id(@tablename) and pubid = @pubid
  19312.         set @type = 4
  19313.         exec @retcode = @procname @type  = @type output, @rowguid=@rowguid
  19314.         
  19315.         if @@ERROR <>0 return (1)
  19316.         if (@type = 3)
  19317.             begin
  19318.             select @type = 2,  @generation = generation, @lineage = lineage, @colv = colv1 from MSmerge_contents
  19319.                 where tablenick = @tablenick and rowguid = @rowguid
  19320.             end
  19321.         end
  19322. -- DEBUG    insert into master.dbo.debuglog(tablenick, rowguid, type, twhen, comment) values
  19323. -- DEBUG    (@tablenick, @rowguid, @type, getdate(), 'sp_MSgetrowmetadata')
  19324.     return (0)
  19325. go
  19326.  
  19327. grant exec on dbo.sp_MSgetrowmetadata to public
  19328. go
  19329.  
  19330. --------------------------------------------------------------------------------
  19331. --. sp_MSgetmetadatabatch
  19332. --------------------------------------------------------------------------------
  19333. if exists (select * from sysobjects    where type = 'P'
  19334.     and name = 'sp_MSgetmetadatabatch')
  19335.     drop procedure sp_MSgetmetadatabatch
  19336. go
  19337.  
  19338. raiserror('Creating procedure sp_MSgetmetadatabatch', 0,1)
  19339. go
  19340.  
  19341. CREATE PROCEDURE sp_MSgetmetadatabatch
  19342.     (@pubid uniqueidentifier,
  19343.      @tablenickarray varbinary(2000),
  19344.      @rowguidarray varbinary(8000)
  19345.     )
  19346. as
  19347.     declare @tablenick int
  19348.     declare @rowguid uniqueidentifier
  19349.     declare @generation int 
  19350.     declare @type  tinyint
  19351.     declare @lineage varbinary(255) 
  19352.     declare @colv varbinary(2048)
  19353.     declare @retcode         smallint
  19354.     declare @saverr         int
  19355.     declare @rc             int
  19356.     declare @tnlength        int
  19357.     declare @tnoffset        int
  19358.     declare @guidoffset        int
  19359.     
  19360.     /*
  19361.     ** To public.
  19362.     */
  19363.     
  19364.     
  19365.     if (@tablenickarray is null)
  19366.         begin
  19367.         RAISERROR(14043, 16, -1, '@tablenick')
  19368.         return (1)
  19369.         end
  19370.     if (@rowguidarray is null)
  19371.         begin
  19372.         RAISERROR(14043, 16, -1, '@rowguid')
  19373.         return (1)
  19374.         end
  19375.     -- create temp table for returning results
  19376.     create table #meta_batch(idx int identity, generation int, type  tinyint,
  19377.              lineage varbinary(255), colv varbinary(2048))
  19378.  
  19379.     -- initialize offsets and length for walking through arrays
  19380.     set @tnoffset = 1
  19381.     set @guidoffset = 1
  19382.     set @tnlength = datalength(@tablenickarray)
  19383.  
  19384.     -- walk through arrays and populate temp table
  19385.     while (@tnoffset < @tnlength)
  19386.         begin
  19387.         set @tablenick = substring(@tablenickarray, @tnoffset, 4)
  19388.         set @rowguid = substring(@rowguidarray, @guidoffset, 16)
  19389.         set @generation = 0
  19390.         set @type = 0
  19391.         set @lineage = NULL
  19392.         set @colv = NULL
  19393.         exec @rc = sp_MSgetrowmetadata @tablenick, @rowguid,  @generation output,
  19394.              @type  output, @lineage output, @colv output, @pubid
  19395.          if @rc <> 0 return @rc
  19396.          -- insert values into temp table
  19397.          insert into #meta_batch (generation, type, lineage, colv) values
  19398.              (@generation, @type, @lineage, @colv) 
  19399.  
  19400.          -- bump up offsets for next time through loop
  19401.          set @tnoffset = @tnoffset + 4
  19402.          set @guidoffset = @guidoffset + 16
  19403.         end
  19404.  
  19405.     -- select out our result set
  19406.     select generation, type, lineage, colv from #meta_batch order by idx
  19407.     drop table #meta_batch
  19408.  
  19409.     return (0)
  19410. go
  19411.  
  19412. grant exec on dbo.sp_MSgetmetadatabatch to public
  19413. go
  19414.  
  19415. --------------------------------------------------------------------------------
  19416. --. sp_MSupdateschemachange
  19417. --------------------------------------------------------------------------------
  19418. if exists (select * from sysobjects    where type = 'P'
  19419.     and name = 'sp_MSupdateschemachange')
  19420.     drop procedure sp_MSupdateschemachange
  19421. go
  19422.  
  19423. raiserror('Creating procedure sp_MSupdateschemachange', 0,1)
  19424. go
  19425.  
  19426. CREATE PROCEDURE sp_MSupdateschemachange(
  19427.     @pubid            uniqueidentifier,
  19428.     @artid            uniqueidentifier = NULL, /* Can be NULL for directory commands */
  19429.     @schemaversion     int,
  19430.     @schemaguid        uniqueidentifier,
  19431.     @schematype        int,
  19432.     @schematext        nvarchar(2000)
  19433.     )
  19434. as
  19435.     /*
  19436.     ** Check to see if current publication has permission
  19437.     */
  19438.     declare @retcode int
  19439.     exec @retcode=sp_MSreplcheck_connection
  19440.         @pubid = @pubid
  19441.     if @retcode<>0 or @@ERROR<>0 return (1)
  19442.     
  19443.     /* Parameter validation */
  19444.     if (@schemaversion is null)
  19445.         begin
  19446.         RAISERROR(14043, 16, -1, '@schemaversion')
  19447.         return (1)
  19448.         end
  19449.  
  19450.     if (not exists(select * from sysobjects where name = 'MSmerge_contents'))
  19451.         begin
  19452.         RAISERROR(20054 , 16, -1)
  19453.         return (1)
  19454.         end
  19455.  
  19456.     update sysmergeschemachange set schematext = @schematext, schematype = @schematype
  19457.         where pubid = @pubid and schemaversion = @schemaversion
  19458.     if @@error <> 0        
  19459.         begin
  19460.             RAISERROR(20054 , 16, -1)
  19461.             return (1)
  19462.         end        
  19463.     return (0)
  19464. go
  19465.  
  19466. grant exec on dbo.sp_MSupdateschemachange to public
  19467. go
  19468.  
  19469. --------------------------------------------------------------------------------
  19470. --. sp_MSadd_mergereplcommand
  19471. --------------------------------------------------------------------------------
  19472. if exists (select * from sysobjects    where type = 'P'
  19473.     and name = 'sp_MSadd_mergereplcommand')
  19474.     drop procedure sp_MSadd_mergereplcommand
  19475. go
  19476.  
  19477. raiserror('Creating procedure sp_MSadd_mergereplcommand', 0,1)
  19478. go
  19479.  
  19480. /* Add the replication command to the database - Used by snapshot */
  19481. CREATE PROCEDURE sp_MSadd_mergereplcommand (
  19482.     @publication        sysname,
  19483.     @article            sysname = NULL,
  19484.     @schematype            int,
  19485.     @schematext            nvarchar(2000)
  19486.     ) AS
  19487.     declare @schemaguid            uniqueidentifier
  19488.     declare @schemaversion         int
  19489.     declare @retcode             int
  19490.     declare @pubid                uniqueidentifier
  19491.     declare @artid                uniqueidentifier
  19492.     
  19493.     /*
  19494.     ** Publish permission check
  19495.     */
  19496.     exec @retcode=sp_MSreplcheck_publish
  19497.     if @retcode<>0 or @@ERROR<>0 return (1)
  19498.     
  19499.     if @publication IS NULL
  19500.         BEGIN
  19501.             RAISERROR (14003, 16, -1)
  19502.             RETURN (1)
  19503.         END
  19504.  
  19505.     select @pubid = pubid FROM sysmergepublications WHERE name = @publication and UPPER(publisher)=UPPER(@@SERVERNAME) and publisher_db=db_name()
  19506.     select @artid = artid FROM sysmergearticles WHERE name = @article
  19507.     /* 
  19508.     ** For certain system tables that are bcped out such as MSmerge_contents 
  19509.     ** and MSmerge_tombstone use the article name as sysobjects.name and get
  19510.     ** sysobjects.id as the artid
  19511.     */
  19512.     if (@artid IS NULL) AND (@schematype <> 7)
  19513.         begin
  19514.             declare @binguid binary(16)
  19515.             set @binguid = OBJECT_ID(@article)
  19516.             set @artid = convert(uniqueidentifier, @binguid)
  19517.         end
  19518.  
  19519.     if exists (select *    from sysmergeschemachange
  19520.             where pubid = @pubid 
  19521.             AND artid = @artid
  19522.             AND (schematype = @schematype or @schematype in (3,4) and schematype in (3,4)) )
  19523.         begin
  19524.             /* Select the existing schema guid */
  19525.             select @schemaversion = schemaversion, @schemaguid = schemaguid from sysmergeschemachange
  19526.                 where pubid = @pubid 
  19527.                 AND artid = @artid
  19528.                 AND (schematype = @schematype or @schematype in (3,4) and schematype in (3,4))
  19529.  
  19530.  
  19531.             /* For directory commands, delete the previous directory before the update */
  19532.             if (@schematype = 7)
  19533.                 begin
  19534.                     declare @dir             nvarchar(255)
  19535.                     declare @local_path        nvarchar(255)
  19536.                     declare @delcmd         nvarchar(255)
  19537.                     declare @distributor     sysname
  19538.                     declare @distproc         nvarchar(255)
  19539.                     
  19540.                     /*
  19541.                     ** Get distribution server information for remote RPC call.
  19542.                     */
  19543.                     EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT
  19544.                     IF @@ERROR <> 0 OR  @retcode <> 0
  19545.                         BEGIN
  19546.                             RAISERROR (14071, 16, -1)
  19547.                             RETURN (1)
  19548.                         END
  19549.  
  19550.                     select @dir = schematext from sysmergeschemachange 
  19551.                         where schemaversion = @schemaversion 
  19552.                     /* 
  19553.                     ** We have to convert UNC to drive, otherwise will get 'Access denied' error in xp_cmdshell
  19554.                     */
  19555.                     EXEC @retcode = master.dbo.sp_MSunc_to_drive @unc_path = @dir, 
  19556.                         @local_server = @distributor, @local_path = @local_path OUTPUT
  19557.                     if @retcode<>0 or @@ERROR<>0 return (1)
  19558.                     /*
  19559.                     ** Delete publication directory in the distributor machine.
  19560.                     */
  19561.                     SET @distproc = RTRIM(@distributor) + '.master..xp_cmdshell'
  19562.                     SET @delcmd = 'rmdir /S /Q "' + @local_path + '"'
  19563.  
  19564.                     -- Put outter quotes if running on NT
  19565.                     if ((platform() & 0x1) = 0x1)
  19566.                         select @delcmd = '" ' + @delcmd + ' "'  
  19567.  
  19568.                     EXECUTE @distproc @delcmd, NO_OUTPUT        
  19569.                     if @@ERROR<>0 return (1)
  19570.                 end
  19571.  
  19572.             /*
  19573.             ** Update the schema change version
  19574.             */
  19575.             exec @retcode = dbo.sp_MSupdateschemachange @pubid, @artid, @schemaversion, 
  19576.                 @schemaguid, @schematype, @schematext
  19577.             if @@error <> 0    or @retcode <> 0
  19578.                 begin
  19579.                 RAISERROR(20054 , 16, -1)
  19580.                 return (1)
  19581.             end
  19582.         end
  19583.     else        
  19584.         begin
  19585.             /* Insert the schema change */
  19586.             select @schemaversion = schemaversion from sysmergeschemachange
  19587.             if (@schemaversion is NULL)
  19588.                 set @schemaversion = 1
  19589.             else
  19590.                 select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange
  19591.                 
  19592.             /* generate a new schema guid */
  19593.             set @schemaguid = newid()
  19594.             exec @retcode = dbo.sp_MSinsertschemachange @pubid, @artid, @schemaversion, 
  19595.                 @schemaguid, @schematype, @schematext
  19596.             if @@error <> 0    or @retcode <> 0
  19597.                 begin
  19598.                     RAISERROR(20054 , 16, -1)
  19599.                     return (1)
  19600.                 end
  19601.         end                
  19602.         
  19603.         /*
  19604.         ** change last_validate column of sysmergesubscription entry that represents the publication
  19605.         */
  19606.         if (@schematype = 7)
  19607.         begin
  19608.             update sysmergesubscriptions set last_validated=getdate() where pubid=@pubid and subid=@pubid
  19609.             IF @@ERROR <> 0
  19610.             begin
  19611.                 RAISERROR(20054 , 16, -1)
  19612.                 RETURN (1)
  19613.             end
  19614.         end
  19615.  
  19616.     return (0)
  19617. go
  19618.  
  19619. grant exec on dbo.sp_MSadd_mergereplcommand to public
  19620. go
  19621.  
  19622. --------------------------------------------------------------------------------
  19623. --. sp_MSsetreplicainfo
  19624. --------------------------------------------------------------------------------
  19625. if exists (select * from sysobjects    where type = 'P'
  19626.     and name = 'sp_MSsetreplicainfo')
  19627.     drop procedure sp_MSsetreplicainfo
  19628. go
  19629.  
  19630. raiserror('Creating procedure sp_MSsetreplicainfo', 0,1)
  19631. go
  19632.  
  19633. CREATE PROCEDURE sp_MSsetreplicainfo
  19634.     (@publisher            sysname,
  19635.      @publisher_db        sysname,
  19636.      @publication         sysname,
  19637.      @datasource_type    int = 0,             /* 0 = SQL Server, 1 = DSN, 2 = Jet */
  19638.      @server_name        sysname    = NULL, /* Server Name */
  19639.      @db_name            sysname = NULL, /* Database Name */
  19640.      @datasource_path    nvarchar(255) = NULL,/* Datasource path - JET MDB file path etc */
  19641.      @nickname     int = NULL,
  19642.      @schemaversion int = NULL,
  19643.      @subid    uniqueidentifier = NULL)
  19644. as
  19645.     declare     @pubid         uniqueidentifier
  19646.     declare     @repid         uniqueidentifier
  19647.     declare        @srvid        int
  19648.     declare        @retcode    int
  19649.  
  19650.     /*
  19651.     ** NOTE -- WORKAROUND ODBC PROBLEM
  19652.     */
  19653.     select @publisher_db = RTRIM(@publisher_db)
  19654.     select @db_name = RTRIM(@db_name)
  19655.     
  19656.     /*
  19657.     ** Subscriber permission check
  19658.     */
  19659.     if UPPER(@@servername) = UPPER(@publisher) and db_name() = @publisher_db
  19660.     begin
  19661.         exec @retcode=sp_MSreplcheck_connection
  19662.             @publication = @publication
  19663.         if @retcode<>0 or @@ERROR<>0 return (1)
  19664.     end
  19665.     else
  19666.     begin
  19667.         exec @retcode=sp_MSreplcheck_subscribe
  19668.         if @retcode<>0 or @@ERROR<>0 return (1)
  19669.     end
  19670.     
  19671.     /*
  19672.     ** Parameter Check:  @publication.
  19673.     ** Make sure that the publication exists.
  19674.     */
  19675.     if (@publication is null)
  19676.         begin
  19677.         RAISERROR(14043, 16, -1, '@publication')
  19678.         return (1)
  19679.         end
  19680.  
  19681.     if (@server_name is NULL)
  19682.         SET @server_name = @@SERVERNAME
  19683.  
  19684.     if (@db_name is NULL)
  19685.         set @db_name = db_name()
  19686.         
  19687.     SELECT @srvid = srvid FROM master..sysservers WHERE UPPER(srvname) = UPPER(@server_name)
  19688.        IF @@ERROR <> 0 or @srvid IS NULL
  19689.            BEGIN
  19690.             RAISERROR(20021, 16, -1)
  19691.              RETURN (1)
  19692.         END
  19693.  
  19694.     select @pubid = pubid from sysmergepublications 
  19695.         where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  19696.     if (@pubid is null)
  19697.         begin
  19698.             RAISERROR (20026, 11, -1, @publication)
  19699.             return (1)
  19700.         end
  19701.  
  19702.     if (@datasource_type = 0)
  19703.         begin
  19704.             /*
  19705.             ** SQL Server
  19706.             */
  19707.             SELECT @repid = subid FROM sysmergesubscriptions
  19708.                 WHERE srvid = @srvid and db_name = @db_name and pubid = @pubid
  19709.         END
  19710.     ELSE IF (@datasource_type = 4) or (@datasource_type = 5)
  19711.         BEGIN
  19712.             /* 
  19713.             ** Exchange or Oracle 
  19714.             */
  19715.             SELECT @repid = subid FROM sysmergesubscriptions
  19716.                 WHERE srvid = @srvid and pubid = @pubid
  19717.         END
  19718.     ELSE
  19719.         BEGIN
  19720.             /*
  19721.             ** Jet
  19722.             */
  19723.             SELECT @repid = subid FROM sysmergesubscriptions
  19724.                 WHERE datasource_path = @datasource_path and pubid = @pubid
  19725.         END
  19726.     if @repid is NULL
  19727.         begin
  19728.             RAISERROR(20021, 16, -1)
  19729.             return (1)
  19730.         end
  19731.     if @schemaversion is not null
  19732.         begin
  19733.             update MSmerge_replinfo set schemaversion = @schemaversion where repid = @repid
  19734.             if @@error <> 0        
  19735.                 begin
  19736.                     RAISERROR(20054 , 16, -1)
  19737.                     return (1)
  19738.                 end
  19739.         end
  19740.         
  19741.     if @subid is not null and @subid <> @repid
  19742.         begin
  19743.         /* Fix the repid for pull subscribers before we copy around global replica rows */
  19744.         update MSmerge_replinfo set repid = @subid where repid = @repid
  19745.         if @@error <> 0        
  19746.             begin
  19747.                 RAISERROR(20054 , 16, -1)
  19748.                 return (1)
  19749.             end
  19750.         update sysmergesubscriptions set subid = @subid where subid = @repid
  19751.         if @@error <> 0        
  19752.             begin
  19753.                 RAISERROR(20054 , 16, -1)
  19754.                 return (1)
  19755.             end
  19756.         end
  19757.         
  19758.     if @nickname IS NOT NULL        
  19759.         begin
  19760.             /* If this nickname isn't already assigned, reset it */
  19761.             if exists (select * from MSmerge_replinfo, sysmergesubscriptions
  19762.                     where replnickname = @nickname and repid = subid and (srvid <> @srvid or
  19763.                                 db_name <> @db_name))
  19764.                 return (0)
  19765.             update MSmerge_replinfo set replnickname = @nickname where repid = @repid
  19766.             if @@error <> 0        
  19767.                 begin
  19768.                     RAISERROR(20054 , 16, -1)
  19769.                     return (1)
  19770.                 end
  19771.         end            
  19772.     
  19773.     return (0)
  19774. go
  19775.  
  19776. grant exec on dbo.sp_MSsetreplicainfo to public
  19777. go
  19778.  
  19779. --------------------------------------------------------------------------------
  19780. --. sp_MSmakeconflictinsertproc
  19781. --------------------------------------------------------------------------------
  19782. if exists (select * from sysobjects    where type = 'P'
  19783.     and name = 'sp_MSmakeconflictinsertproc')
  19784.     drop procedure sp_MSmakeconflictinsertproc
  19785. go
  19786.  
  19787. raiserror('Creating procedure sp_MSmakeconflictinsertproc', 0,1)
  19788. go
  19789.  
  19790. create procedure sp_MSmakeconflictinsertproc 
  19791.     (@tablename sysname, @ownername sysname, @procname sysname, @basetableid int)
  19792. as
  19793. declare @arglist    nvarchar(4000)
  19794. declare @header        nvarchar(4000)
  19795. declare @vallist     nvarchar(4000)
  19796. declare @qualname   nvarchar(266)
  19797. declare @argname    nvarchar(258)
  19798. declare @noset        bit
  19799. declare @wherepc    nvarchar(255)
  19800. declare @id         int
  19801. declare @colname nvarchar(258)
  19802. declare @typename nvarchar(258)
  19803. declare @colid smallint
  19804. declare @status tinyint
  19805. declare @len smallint
  19806. declare @prec smallint
  19807. declare @scale int
  19808. declare @retcode smallint
  19809. declare @sys_loop bit
  19810. declare @old_colname nvarchar(258)
  19811. declare @create_time_col nvarchar(5)
  19812. set nocount on
  19813.  
  19814. select @sys_loop = 0
  19815. set @create_time_col = NULL
  19816.  
  19817. if (@ownername is null or @ownername = ' ')
  19818.     set @qualname = QUOTENAME(@tablename)
  19819. else
  19820.     set @qualname = QUOTENAME(@ownername) + '.' + QUOTENAME(@tablename)
  19821.  
  19822. /*
  19823. ** To check if specified object exists in current database
  19824. */
  19825. set @id = object_id(@qualname)
  19826.     if @id is NULL return (1)
  19827.  
  19828. -- create temp table to select the command text out of
  19829. create table #tempcmd (phase int NOT NULL, step int identity NOT NULL, 
  19830. cmdtext nvarchar(4000) NULL)
  19831.  
  19832. select @header = 'Create procedure dbo.' + @procname + ' ( ' 
  19833. insert into #tempcmd (phase, cmdtext) values (0,  @header)
  19834.  
  19835. select @colid = min(colid) from syscolumns where id = @id and iscomputed <>1 and 
  19836.     type_name(xtype) <> 'timestamp' and ((name not in (select name from syscolumns where id=@basetableid) 
  19837.         and @sys_loop =1) OR
  19838.      (name in (select name from syscolumns where id=@basetableid) and @sys_loop =0))
  19839. select @colname = c.name, @status = c.status, @typename = t.name, @len = c.length,
  19840.     @prec = c.prec, @scale = c.scale
  19841.     from syscolumns c, systypes t
  19842.     where c.id = @id and c.colid = @colid and c.xusertype = t.xusertype 
  19843.  
  19844. /*
  19845. ** Get the column list from the conflict_table schema and filter it with 
  19846. table view for vertical partitioning
  19847. */
  19848. Reverse_Order:
  19849. while (@colname is not null) 
  19850. begin
  19851.     set @noset = 0
  19852.     if @typename='nvarchar' or @typename='nchar' -- a unit of nchar takes 2 bytes
  19853.         select @len = @len/2
  19854.     exec @retcode = dbo.sp_MSmaptype @typename out, @len, @prec, @scale
  19855.     if @@ERROR<>0 or @retcode<>0 return (1)
  19856.     select @argname = '@p' + rtrim(convert(nchar, @colid))
  19857.  
  19858.     -- based on colid, add text to appropriate pieces
  19859.     if (COLUMNPROPERTY( @basetableid, @colname, 'IsRowGuidCol') = 1)  
  19860.         begin
  19861.             select @noset =1
  19862.             set @wherepc = ' where rowguidcol = ' + @argname
  19863.         end
  19864.     else if (@colname = 'origin_datasource')
  19865.         begin
  19866.             select @wherepc =@wherepc +  ' and origin_datasource = ' + @argname
  19867.             set @noset =1
  19868.         end
  19869.     set @old_colname = @colname
  19870.     set @colname = QUOTENAME(@colname)
  19871.     if @arglist is null
  19872.         begin
  19873.         set @arglist = @argname + ' ' + @typename
  19874.         --give default value of NULL to new merge columns for backward compatibility concern
  19875.         insert into #tempcmd (phase, cmdtext) values (3, @colname)
  19876.         set @vallist = @argname
  19877.         if @noset=0
  19878.             insert into #tempcmd (phase, cmdtext) values (1, @colname + ' = ' + @argname)
  19879.         end
  19880.     else 
  19881.         begin
  19882.         if len(@arglist)>3700
  19883.             begin
  19884.                 insert into #tempcmd (phase, cmdtext) values (0,  @arglist)            
  19885.                 select @arglist = ' '
  19886.             end
  19887.         set @arglist = @arglist + ', ' + @argname + ' ' + @typename
  19888.         if @sys_loop = 1 and @old_colname not in ('origin_datasource','conflict_type','reason_code','reason_text', 'pubid') 
  19889.             begin
  19890.                 select @arglist=@arglist + ' = NULL'        
  19891.                 if @old_colname='create_time'
  19892.                     select @create_time_col=@argname
  19893.             end
  19894.  
  19895.         insert into #tempcmd (phase, cmdtext) values (3, ',' + @colname)
  19896.         set @vallist = @vallist + ', ' + @argname
  19897.         if @noset =0
  19898.             begin
  19899.                 if exists (select * from #tempcmd where phase=1)
  19900.                     insert into #tempcmd (phase, cmdtext) values (1, ',' + @colname + ' = ' + @argname)
  19901.                 else
  19902.                     insert into #tempcmd (phase, cmdtext) values (1, @colname + ' = ' + @argname)
  19903.             end
  19904.         end
  19905. NEXT_COL:
  19906.     select @colid = min(colid) from syscolumns where id = @id and colid>@colid and iscomputed <>1 and 
  19907.         type_name(xtype) <> 'timestamp' and 
  19908.         ((name not in (select name from syscolumns where id=@basetableid) and @sys_loop =1) OR
  19909.              (name in (select name from syscolumns where id=@basetableid) and @sys_loop =0))
  19910.     set @colname = NULL
  19911.     select @colname = c.name, @status = c.status, @typename = t.name, @len = c.length,
  19912.         @prec = c.prec, @scale = c.scale
  19913.         from syscolumns c, systypes t
  19914.         where c.id = @id and c.colid = @colid and c.xusertype = t.xusertype
  19915. end
  19916.  
  19917. if @sys_loop = 0
  19918. begin
  19919.     select @sys_loop = 1
  19920.     select @colid = min(colid) from syscolumns where id = @id  and iscomputed <>1 
  19921.         and type_name(xtype) <> 'timestamp' and 
  19922.         ((name not in (select name from syscolumns where id=@basetableid) and @sys_loop =1) OR
  19923.          (name in (select name from syscolumns where id=@basetableid) and @sys_loop =0))
  19924.     select @colname = c.name, @status = c.status, @typename = t.name, @len = c.length,
  19925.         @prec = c.prec, @scale = c.scale
  19926.         from syscolumns c, systypes t
  19927.             where c.id = @id and c.colid = @colid and c.xusertype = t.xusertype 
  19928.     goto Reverse_Order
  19929. end
  19930.  
  19931. -- now create the procedure
  19932. select @procname = QUOTENAME(@procname)
  19933.  
  19934. insert into #tempcmd (phase, cmdtext) values (0,  @arglist)            
  19935.  
  19936. select @header =  ') as'
  19937. insert into #tempcmd (phase, cmdtext) values (0,  @header)
  19938.  
  19939. select @header = ' '
  19940. -- for ease of expansion here in case we add new merge columns in conflict tables.
  19941. if @create_time_col is not NULL
  19942.     select @header = @header + ' 
  19943.         select ' + @create_time_col + ' = getdate() '
  19944.  
  19945. select @header = @header + '
  19946.     update ' + @qualname + ' set ' 
  19947. insert into #tempcmd (phase, cmdtext) values (0,  @header)
  19948. select @header = @wherepc + '
  19949.     if (@@rowcount = 0)
  19950.     insert into ' + @qualname + ' ('
  19951. insert into #tempcmd (phase, cmdtext) values (2,  @header)
  19952. select @header =     ') values (' + @vallist + ')'
  19953. insert into #tempcmd (phase, cmdtext) values (4,  @header)
  19954.  
  19955. -- Now we select out the command text pieces in proper order so that our caller,
  19956. -- xp_execresultset will execute the command that creates the stored procedure.
  19957.  
  19958. select cmdtext from #tempcmd order by phase, step
  19959. go
  19960.  
  19961. grant exec on dbo.sp_MSmakeconflictinsertproc to public
  19962. go
  19963.  
  19964. --------------------------------------------------------------------------------
  19965. --. sp_MSgetconflictinsertproc
  19966. --------------------------------------------------------------------------------
  19967. if exists (select * from sysobjects    where type = 'P'
  19968.     and name = 'sp_MSgetconflictinsertproc')
  19969.     drop procedure sp_MSgetconflictinsertproc
  19970. go
  19971.  
  19972. raiserror('Creating procedure sp_MSgetconflictinsertproc', 0,1)
  19973. go
  19974.  
  19975. CREATE PROCEDURE sp_MSgetconflictinsertproc (
  19976.     @artid                 uniqueidentifier,
  19977.     @output    int = 1
  19978.     ) AS
  19979.     declare @conflict_table sysname
  19980.     declare @dbname            sysname
  19981.     declare @conflict_proc    sysname
  19982.     declare @owner             sysname
  19983.     declare @object            sysname
  19984.     declare @retcode         int
  19985.     declare    @basetableid    int
  19986.     
  19987.     -- PARSENAME VARS
  19988.     declare @UnqualName     nvarchar(258)  --rightmost name node
  19989.     declare @QualName1      nvarchar(258)  
  19990.     declare @command        nvarchar(4000)
  19991.     declare @QualName2      nvarchar(258)  
  19992.     -- END PARSENAME VARS
  19993.  
  19994.     declare @guidstr varchar(40)
  19995.     exec @retcode=sp_MSguidtostr @artid, @guidstr out
  19996.     if @retcode<>0 or @@ERROR<>0 return (1)
  19997.     
  19998.     /*
  19999.     ** Check to see if current publication has permission
  20000.     */
  20001.     exec @retcode=sp_MSreplcheck_connection
  20002.         @artid = @artid
  20003.     if @retcode<>0 or @@ERROR<>0 return (1)
  20004.     
  20005.     select @conflict_table = conflict_table, @conflict_proc = ins_conflict_proc, @basetableid = objid from
  20006.         sysmergearticles where artid = @artid
  20007.  
  20008.     if @@ERROR <> 0
  20009.         return (1)
  20010.  
  20011.     -- Create an index on the conflict table if it doesn't have one
  20012.     if (OBJECT_ID(@conflict_table) is not null) and
  20013.         not exists (select * from sysindexes where id = OBJECT_ID(@conflict_table) and keys is not null)
  20014.         begin
  20015.         declare @rgcol sysname
  20016.         declare @indname sysname
  20017.         declare @quotedname sysname
  20018.         
  20019.         select @rgcol = QUOTENAME(name) from syscolumns where id = @basetableid and
  20020.                 ColumnProperty(id, name, 'isrowguidcol') = 1
  20021.         select @indname = 'uc_' + @conflict_table
  20022.         set @indname = QUOTENAME(@indname)
  20023.         set @quotedname = QUOTENAME(@conflict_table)
  20024.         exec ('Create unique clustered index ' + @indname + ' on ' + @quotedname +
  20025.                 ' (' + @rgcol + ', origin_datasource)' )
  20026.         if @@error <> 0
  20027.             return (1)
  20028.         end
  20029.     if ((OBJECT_ID(@conflict_proc) is null) and (OBJECT_ID(@conflict_table) is not null))
  20030.         begin
  20031.  
  20032.         select @UnqualName = PARSENAME(@conflict_table, 1)
  20033.         select @QualName1 = PARSENAME(@conflict_table, 2)
  20034.         if @UnqualName IS NULL
  20035.              return 1
  20036.  
  20037.         -- fixup for variable length differences.  remove when vars expanded
  20038.         -- to new SQL SERVER 7.0 lengths
  20039.  
  20040.         select @owner =  @QualName1
  20041.         select @object = @UnqualName
  20042.  
  20043.         -- first set up the procedure name variable
  20044.         select @conflict_proc = 'sp_cft_' + @guidstr
  20045.         exec @retcode=sp_MSuniqueobjectname @conflict_proc , @conflict_proc output
  20046.         if @@ERROR <> 0 OR @retcode <> 0 
  20047.             return(1)
  20048.         set @dbname = db_name()
  20049.         if @owner is NULL
  20050.             set @command = 'sp_MSmakeconflictinsertproc ' + QUOTENAME(@conflict_table) + ' , NULL, ' + @conflict_proc  + ' , ' + convert(nvarchar,@basetableid)
  20051.         else
  20052.             set @command = 'sp_MSmakeconflictinsertproc ' + QUOTENAME(@conflict_table) + ' , ' + QUOTENAME(@owner) + ' , ' + @conflict_proc  + ' , ' + convert(nvarchar,@basetableid)
  20053.         exec @retcode = master..xp_execresultset @command, @dbname
  20054.         if @@ERROR<>0 OR @retcode<>0 
  20055.         begin
  20056.             return (1)
  20057.         end
  20058.         exec @retcode = dbo.sp_MS_marksystemobject  @conflict_proc 
  20059.         if @@ERROR<>0  return (1)
  20060.         exec ('grant exec on ' + @conflict_proc + ' to public')
  20061.         update sysmergearticles set ins_conflict_proc = @conflict_proc where artid = @artid
  20062.     end
  20063.  
  20064.     if @output = 1
  20065.         select @conflict_table, @conflict_proc
  20066.     if @@ERROR <> 0
  20067.         return (1)
  20068.     return (0)
  20069.     
  20070. go
  20071.  
  20072. grant exec on dbo.sp_MSgetconflictinsertproc to public
  20073. go
  20074.  
  20075. --------------------------------------------------------------------------------
  20076. --. sp_MSdelrow
  20077. --------------------------------------------------------------------------------
  20078. if exists (select * from sysobjects    where type = 'P'
  20079.     and name = 'sp_MSdelrow')
  20080.     drop procedure sp_MSdelrow
  20081. go
  20082.  
  20083. raiserror('Creating procedure sp_MSdelrow', 0,1)
  20084. go
  20085.  
  20086. create PROCEDURE sp_MSdelrow 
  20087.     (@rowguid         uniqueidentifier,
  20088.     @tablenick     int,
  20089.     @metadata_type tinyint, /* 0 - Missing, 1 - Tombstone, 2 - Contents, 3 - ContentsDeferred */
  20090.     @lineage_old varbinary(255),
  20091.     @generation int,
  20092.     @lineage_new varbinary(255),
  20093.     @pubid uniqueidentifier = NULL)
  20094.  
  20095. as
  20096.     set nocount on
  20097.     declare @success int 
  20098.     declare @tablename         nvarchar(266)
  20099.     declare @rowguidstr        nvarchar(40)
  20100.     declare @match             int
  20101.     declare @new_metatype    tinyint
  20102.     declare @retcode         smallint
  20103.     declare @reason         nvarchar(255)
  20104.     declare @procname         nvarchar(266)
  20105.     declare @ownername        sysname
  20106.     
  20107.     /*
  20108.     ** Check to see if current publication has permission
  20109.     */
  20110.     exec @retcode=sp_MSreplcheck_connection
  20111.         @tablenick = @tablenick
  20112.     if @retcode<>0 or @@ERROR<>0 return (1)
  20113.     
  20114.     select @success = 0
  20115.     /* Parameter validation */
  20116.     if (@rowguid is null)
  20117.         begin
  20118.         RAISERROR(14043, 16, -1, '@rowguid')
  20119.         return (0)
  20120.         end
  20121.     if (@tablenick is null)
  20122.         begin
  20123.         RAISERROR(14043, 16, -1, '@tablenick')
  20124.         return (0)
  20125.         end
  20126.     exec @retcode = dbo.sp_MStablenamefromnick    @tablenick, @tablename output, @pubid
  20127.     if @@ERROR<>0 return (0)
  20128.  
  20129.     if (@tablename is null)
  20130.         begin
  20131.         RAISERROR(14043, 16, -1, '@tablename')
  20132.         return (0)
  20133.         end
  20134.     if (@lineage_new is null)
  20135.         begin
  20136.         RAISERROR(14043, 16, -1, '@lineage_new')
  20137.         return (0)
  20138.         end
  20139.  
  20140.     if (not exists(select * from sysobjects where name = 'MSmerge_contents'))
  20141.         begin
  20142.         RAISERROR(20054 , 16, -1)
  20143.         return (0)
  20144.         end
  20145.     set @rowguidstr = '''' + convert(nchar(36), @rowguid) + ''''
  20146.  
  20147. -- DEBUG    insert into master.dbo.debuglog(tablenick, rowguid, type, twhen, comment) values
  20148. -- DEBUG    (@tablenick, @rowguid, @metadata_type, getdate(), 'sp_MSdelrow')
  20149.  
  20150.     -- Are we just changing the type of a tombstone?
  20151.     -- This routine is only called for Upload; won't be type 5 (remove from partial) unless
  20152.     -- subscriber has a user delete and found an existing metadata type of 5 here.
  20153.     -- In that case, set delete type to 1 and update generation, reason text too.
  20154.     if (@metadata_type = 5 and exists (select * from MSmerge_tombstone where
  20155.         rowguid = @rowguid and tablenick = @tablenick))
  20156.         begin
  20157.         set @reason = formatmessage (20562) -- User delete
  20158.         update MSmerge_tombstone set type = 1, reason = @reason, generation = @generation, lineage = @lineage_new where
  20159.             rowguid = @rowguid and tablenick = @tablenick
  20160.         set @success = 1
  20161.         return @success
  20162.         end
  20163.  
  20164.     -- Are we just changing the type of a tombstone?
  20165.     if (@metadata_type = 6 and exists (select * from MSmerge_tombstone where
  20166.         rowguid = @rowguid and tablenick = @tablenick))
  20167.         begin
  20168.         set @reason = formatmessage (20564) -- System deleted
  20169.         update MSmerge_tombstone set type = @metadata_type, reason = @reason, generation = @generation where
  20170.             rowguid = @rowguid and tablenick = @tablenick
  20171.         set @success = 1
  20172.         return @success
  20173.         end
  20174.  
  20175.     -- begin transaction and lock row that we plan to delete
  20176.     begin transaction
  20177.  
  20178.         select @ownername = user_name(uid) from sysobjects where id = object_id(@tablename)
  20179.         select @procname = select_proc from sysmergearticles where objid = object_id(@tablename)  and pubid = @pubid
  20180.         exec @retcode = @procname @type =8, @rowguid=@rowguid
  20181.  
  20182.     /*    
  20183.         execute ('if not exists (select * from ' + @tablename + '(UPDLOCK) where 
  20184.                 rowguidcol = ' + @rowguidstr + ')
  20185.             RAISERROR(20031 , 16, -1) ')
  20186.     */
  20187.             
  20188.     select @success = 2
  20189.     if @metadata_type = 5
  20190.         begin
  20191.         set @match = 1
  20192.         set @new_metatype = 5
  20193.         end
  20194.     else if @metadata_type = 6
  20195.         begin
  20196.         set @match = 1
  20197.         set @new_metatype = 6
  20198.         end
  20199.     else
  20200.         begin
  20201.         exec @retcode=sp_MScheckmetadatamatch @metadata_type, @rowguid, @tablenick, @lineage_old, @match output
  20202.  
  20203.         set @new_metatype = 1
  20204.         end
  20205.     if (@match = 1)
  20206.         begin
  20207.         
  20208.     /*    execute ('delete from ' + @tablename + ' where rowguidcol = ' + @rowguidstr) */
  20209.         
  20210.         /*
  20211.         ** select_proc makes a delete with @type = 5, despite its name. 
  20212.         */
  20213.         exec @retcode = @procname @type =5, @rowguid=@rowguid
  20214.         
  20215.         if (@@error = 0 and @@rowcount = 1)
  20216.             begin
  20217.             exec dbo.sp_MSsetrowmetadata @tablenick, @rowguid, @generation, @lineage_new, NULL, @new_metatype
  20218.             select @success = 1
  20219.             end
  20220.         else
  20221.             select @success = 3
  20222.         end
  20223.     commit
  20224.     return (@success)
  20225. go
  20226.  
  20227. grant exec on dbo.sp_MSdelrow to public
  20228. go
  20229.  
  20230. --------------------------------------------------------------------------------
  20231. --. sp_MSsetartprocs
  20232. --------------------------------------------------------------------------------
  20233. if exists (select * from sysobjects    where type = 'P'
  20234.     and name = 'sp_MSsetartprocs')
  20235.     drop procedure sp_MSsetartprocs
  20236. go
  20237.  
  20238. raiserror('Creating procedure sp_MSsetartprocs', 0,1)
  20239. go
  20240.  
  20241. create procedure sp_MSsetartprocs
  20242.     (@publication        sysname,
  20243.     @article            sysname,
  20244.     @force_flag         int = 0)
  20245. as
  20246.     declare @ownername sysname
  20247.     declare @objectname sysname
  20248.     declare @guidstr nvarchar(40)
  20249.     declare @pubidstr nvarchar(40)
  20250.     declare @ins_procname sysname
  20251.     declare @sel_procname sysname
  20252.     declare @upd_procname sysname
  20253.     declare @view_selprocname sysname
  20254.     declare @viewname sysname
  20255.     declare @artid uniqueidentifier
  20256.     declare @pubid uniqueidentifier
  20257.     declare @objid int
  20258.     declare @rgcol sysname
  20259.     declare @sync_objid int
  20260.     declare @retcode smallint
  20261.     declare @dbname sysname
  20262.     declare @command  nvarchar(1000)
  20263.     
  20264.     set nocount on
  20265.  
  20266.     /*
  20267.     ** Check to see if current publication has permission
  20268.     */
  20269.     exec @retcode=sp_MSreplcheck_publish
  20270.     if @retcode<>0 or @@ERROR<>0 return (1)
  20271.     
  20272.     -- figure out pubid and artid
  20273.     if @force_flag = 1
  20274.         begin
  20275.         -- don't qualify that must be publisher when we are forcing remake at subscribers
  20276.         select @pubid = pubid from sysmergepublications where name = @publication
  20277.         end
  20278.     else
  20279.         select @pubid = pubid from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@@SERVERNAME) and publisher_db=db_name()
  20280.     if @pubid IS NULL
  20281.         BEGIN
  20282.             RAISERROR (20026, 16, -1, @publication)
  20283.             RETURN (1)
  20284.         END
  20285.     
  20286.     select @artid = artid, @objid = objid, @sync_objid = sync_objid FROM sysmergearticles WHERE name = @article    AND pubid = @pubid
  20287.     if @artid IS NULL
  20288.         BEGIN
  20289.             RAISERROR (20027, 16, -1, @article)
  20290.             RETURN (1)
  20291.         END
  20292.  
  20293.     /* Drop the article procs if they preexist */
  20294.     exec @retcode = dbo.sp_MSdroparticleprocs @pubid, @artid
  20295.     if @@ERROR<>0 OR @retcode<>0 
  20296.         begin
  20297.             return (1)
  20298.         end
  20299.     
  20300.     -- get owner name, and table name
  20301.     select @objectname = name, @ownername = user_name(uid)    from sysobjects
  20302.         where id = @objid 
  20303.  
  20304.     -- make the insert and update proc names
  20305.     exec @retcode = dbo.sp_MSguidtostr @artid, @guidstr out
  20306.     if @@ERROR <>0 OR @retcode <>0 return (1)
  20307.  
  20308.     exec @retcode = dbo.sp_MSguidtostr @pubid, @pubidstr out
  20309.     if @@ERROR <>0 OR @retcode <>0 return (1)
  20310.  
  20311.     select @ins_procname = 'sp_ins_' + substring(@guidstr, 1, 16) + substring(@pubidstr, 1, 16)
  20312.     exec dbo.sp_MSuniqueobjectname @ins_procname, @ins_procname output
  20313.     if @@ERROR <>0 OR @retcode <>0 return (1)
  20314.     
  20315.     select @upd_procname = 'sp_upd_' + substring(@guidstr, 1, 16) + substring(@pubidstr, 1, 16)
  20316.     exec dbo.sp_MSuniqueobjectname @upd_procname, @upd_procname output
  20317.     if @@ERROR <>0 OR @retcode <>0 return (1)
  20318.  
  20319.     select @sel_procname = 'sp_sel_' + substring(@guidstr, 1, 16) + substring(@pubidstr, 1, 16)
  20320.     exec dbo.sp_MSuniqueobjectname @sel_procname, @sel_procname output
  20321.     if @@ERROR <>0 OR @retcode <>0 return (1)
  20322.  
  20323.     set @view_selprocname = 'sel_' + substring(@guidstr, 1, 16) + substring(@pubidstr, 1, 16)
  20324.     exec @retcode = dbo.sp_MSuniqueobjectname @view_selprocname , @view_selprocname output
  20325.     if @retcode <> 0 or @@ERROR <> 0 return (1) 
  20326.  
  20327.     -- create the procs
  20328.     set @dbname = db_name()
  20329.     set @command = 'sp_MSmakeinsertproc ' + QUOTENAME(@objectname) + ' , ' + QUOTENAME(@ownername) + ' , ' + @ins_procname  + ', [' + convert(nchar(36), @pubid) + ']'
  20330.     exec @retcode = master..xp_execresultset @command, @dbname
  20331.     if @@ERROR<>0 OR @retcode<>0 
  20332.         begin
  20333.             return (1)
  20334.         end
  20335.  
  20336.  
  20337.     exec @retcode = dbo.sp_MS_marksystemobject  @ins_procname 
  20338.     if @@ERROR<>0  return (1)
  20339.     exec ('grant exec on ' + @ins_procname + ' to public')
  20340.  
  20341.     set @command = 'sp_MSmakeupdateproc ' + QUOTENAME(@objectname) + ' , ' + QUOTENAME(@ownername) + ' , ' + @upd_procname
  20342.     exec @retcode = master..xp_execresultset @command, @dbname
  20343.     if @@ERROR<>0 OR @retcode<>0 
  20344.         begin
  20345.             return (1)
  20346.         end
  20347.     exec @retcode = dbo.sp_MS_marksystemobject  @upd_procname 
  20348.     if @@ERROR<>0 return (1)
  20349.     exec ('grant exec on ' + @upd_procname + ' to public')
  20350.  
  20351.     set @command = 'sp_MSmakeselectproc ' + QUOTENAME(@objectname) + ' , ' + QUOTENAME(@ownername)+ ' , ' + @sel_procname
  20352.     exec (@command)
  20353.     if @@ERROR<>0 
  20354.         begin
  20355.             return (1)
  20356.         end
  20357.      exec @retcode = dbo.sp_MS_marksystemobject  @sel_procname 
  20358.      if @@ERROR<>0 return (1)    
  20359.      exec ('grant exec on ' + @sel_procname + ' to public')
  20360.  
  20361.     if @sync_objid <> 0 
  20362.         begin
  20363.  
  20364.             select @ownername = user_name(uid), @viewname = name from sysobjects 
  20365.                 where id = @sync_objid 
  20366.         select @rgcol = QUOTENAME(name) from syscolumns where id = @objid and
  20367.                 ColumnProperty(id, name, 'isrowguidcol') = 1
  20368.         exec dbo.sp_MSmakeviewproc @viewname, @ownername, @view_selprocname, @rgcol, @objid
  20369.         if @@ERROR<>0 
  20370.             begin
  20371.             return (1)
  20372.             end
  20373.         end
  20374.     else
  20375.         set @view_selprocname = ''
  20376.  
  20377.     -- update articles to set the names
  20378.     update sysmergearticles set insert_proc = @ins_procname, update_proc = @upd_procname ,
  20379.         select_proc = @sel_procname, view_sel_proc = @view_selprocname
  20380.         where artid = @artid and pubid = @pubid
  20381.     IF @@ERROR<>0 return (1)
  20382.     return (0)
  20383. go
  20384.  
  20385. grant exec on dbo.sp_MSsetartprocs to public
  20386. go
  20387.  
  20388. --------------------------------------------------------------------------------
  20389. --. sp_MSexpandbelongs
  20390. --------------------------------------------------------------------------------
  20391. if exists (select * from sysobjects    where type = 'P'
  20392.     and name = 'sp_MSexpandbelongs')
  20393.     drop procedure sp_MSexpandbelongs
  20394. go
  20395.  
  20396. raiserror('Creating procedure sp_MSexpandbelongs', 0,1)
  20397. go
  20398.  
  20399. create procedure sp_MSexpandbelongs
  20400.     @pubid         uniqueidentifier
  20401. AS
  20402.     declare @filterid int
  20403.     declare @retval            int
  20404.     declare @expand_proc    sysname
  20405.     
  20406.     /* We iterate over the join filters */
  20407.     select @filterid = min(flag) from #belong
  20408.     select @filterid = min(join_filterid) from sysmergesubsetfilters where pubid = @pubid and 
  20409.             exists (select * from #belong where tablenick = join_nickname and flag < join_filterid)
  20410.     while (@filterid is not null)
  20411.         begin
  20412.         select @expand_proc = expand_proc from sysmergesubsetfilters where pubid = @pubid and
  20413.                 join_filterid = @filterid
  20414.         exec @retval = @expand_proc @belong = 1
  20415.         if @retval <> 0 return (1)
  20416.         select @filterid = min(join_filterid) from sysmergesubsetfilters where pubid = @pubid and 
  20417.             exists (select * from #belong where tablenick = join_nickname and flag < join_filterid)
  20418.         end
  20419.         
  20420.     return (0)
  20421. go
  20422.  
  20423. grant exec on dbo.sp_MSexpandbelongs to public
  20424. go
  20425.  
  20426. --------------------------------------------------------------------------------
  20427. --. sp_MSexpandnotbelongs
  20428. --------------------------------------------------------------------------------
  20429. if exists (select * from sysobjects    where type = 'P'
  20430.     and name = 'sp_MSexpandnotbelongs')
  20431.     drop procedure sp_MSexpandnotbelongs
  20432. go
  20433.  
  20434. raiserror('Creating procedure sp_MSexpandnotbelongs', 0,1)
  20435. go
  20436.  
  20437. create procedure sp_MSexpandnotbelongs
  20438.     @pubid         uniqueidentifier
  20439. AS
  20440.     declare @filterid         int
  20441.     declare @retval            int
  20442.     declare @expand_proc    sysname
  20443.     
  20444.     /* We iterate over the join filters */
  20445.     select @filterid = min(flag) from #notbelong
  20446.     select @filterid = min(join_filterid) from sysmergesubsetfilters where pubid = @pubid and 
  20447.             exists (select * from #notbelong where tablenick = join_nickname and flag < join_filterid)
  20448.     while (@filterid is not null)
  20449.         begin
  20450.         select @expand_proc = expand_proc from sysmergesubsetfilters where pubid = @pubid and
  20451.                 join_filterid = @filterid
  20452.         exec @retval = @expand_proc @belong = 0
  20453.         if @retval <> 0 return (1)
  20454.         select @filterid = min(join_filterid) from sysmergesubsetfilters where pubid = @pubid and 
  20455.             exists (select * from #notbelong where tablenick = join_nickname and flag < join_filterid)
  20456.         end
  20457.  
  20458.  
  20459. go
  20460.  
  20461. grant exec on dbo.sp_MSexpandnotbelongs to public
  20462. go
  20463.  
  20464. --------------------------------------------------------------------------------
  20465. --. sp_MSsetupbelongs
  20466. --------------------------------------------------------------------------------
  20467. if exists (select * from sysobjects    where type = 'P'
  20468.     and name = 'sp_MSsetupbelongs')
  20469.     drop procedure sp_MSsetupbelongs
  20470. go
  20471.  
  20472. raiserror('Creating procedure sp_MSsetupbelongs', 0,1)
  20473. go
  20474.  
  20475. create procedure sp_MSsetupbelongs
  20476.     @publisher            sysname,
  20477.     @publisher_db        sysname,
  20478.     @publication         sysname,
  20479.     @genlist             varchar(1000),
  20480.     @commongen            int,
  20481.     @subissql            int
  20482.  
  20483. AS
  20484.     declare @pubid uniqueidentifier
  20485.     declare @temp_id int
  20486.     declare @retval int
  20487.     declare @tablenick int
  20488.     declare @tnstr nvarchar(12)
  20489.     declare @rowguid uniqueidentifier
  20490.     declare @rowguidstr nvarchar(40)
  20491.     declare @belongsname sysname
  20492.     declare @belongs_uniquename sysname
  20493.     declare @notbelongsname sysname
  20494.     declare @notbelongs_uniquename sysname
  20495.     declare @artnick    int
  20496.     declare @artnickstr nvarchar(10)
  20497.     declare @artviewobjid int
  20498.     declare @before_view_objid int
  20499.     declare @before_view_name sysname
  20500.     declare @procname sysname
  20501.     declare @sync_objid int
  20502. -- DEBUG declare @belongcnt int
  20503. -- DEBUG declare @nb_cnt int
  20504.     declare @artbaseobjid int
  20505.     declare @artviewname sysname
  20506.     declare @artviewowner sysname
  20507.  
  20508.     declare @commongenstr nvarchar(12)
  20509.     declare @partchangegen int
  20510.     declare @joinchangegen int
  20511.     declare @rgcol sysname
  20512.     declare @maxfilterid int
  20513.     declare @view_type int
  20514.     declare @temp_view int
  20515.     declare @retcode smallint
  20516.     declare @dynamic_join_cnt int
  20517.     
  20518.     /*
  20519.     ** To public
  20520.     */
  20521.     
  20522.     set @temp_view = 2
  20523. -- DEBUG insert into master.dbo.debuglog2 (publisher, pubdb, hostname, twhen, commongen, belong_cnt, nb_cnt, genlist) values
  20524. -- DEBUG (@publisher, @publisher_db, host_name(), getdate(), @commongen, NULL, NULL, @genlist)
  20525.  
  20526.     select @pubid = pubid from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  20527.     set @commongenstr = convert(nchar(12), @commongen)
  20528.     select @dynamic_join_cnt = count(*) from sysmergesubsetfilters where pubid = @pubid and
  20529.         (UPPER(join_filterclause) like '%USER_%NAME%' or
  20530.          UPPER(join_filterclause) like '%USER_%ID%' or
  20531.          UPPER(join_filterclause) like '%SESSION_USER%' or
  20532.          UPPER(join_filterclause) like '%SYSTEM_USER%')
  20533.          
  20534.     /* Set up the ##belong and ##notbelong tables; return names as rowset */
  20535.     /* step 1 make temptable names, create tables */
  20536.     set @rowguid = newid()
  20537.     exec @retcode=sp_MSguidtostr @rowguid, @rowguidstr out
  20538.     if @retcode<>0 or @@ERROR<>0 return (1)
  20539.     
  20540.     set @belongsname = '##belong' + @rowguidstr
  20541.     set @belongs_uniquename = 'bunique_' + @rowguidstr
  20542.     exec @retcode = dbo.sp_MSuniquetempname @belongsname, @belongsname out
  20543.     IF @@ERROR<>0 OR @retcode<>0 return (1)
  20544.     create table #belong (tablenick int NOT NULL, rowguid uniqueidentifier NOT NULL, flag int NOT NULL,
  20545.         partchangegen int null, joinchangegen int null, skippedexpand int null)
  20546.     create index #indbelong on #belong (rowguid)
  20547.     
  20548.     exec ('create table ' + @belongsname + ' (tablenick int NOT NULL, rowguid uniqueidentifier NOT NULL,
  20549.         generation int NULL, lineage varbinary(255) NULL, colv varbinary(2048) NULL) ')
  20550.     if @@ERROR <>0 return (1)
  20551.     create table #notbelong (tablenick int NOT NULL, rowguid uniqueidentifier NOT NULL,
  20552.         flag int NOT NULL, partchangegen int null, joinchangegen int null, type int default 5)
  20553.     create index #indnbelong on #notbelong (tablenick, rowguid)
  20554.     create table #genlist (generation int)
  20555.     exec ('insert into #genlist select distinct generation from MSmerge_genhistory where
  20556.             generation in (' + @genlist + ')')
  20557.             
  20558.     set @notbelongsname = '##notbelong' + @rowguidstr
  20559.     set @notbelongs_uniquename = 'nbunique_' + @rowguidstr
  20560.     exec @retcode = dbo.sp_MSuniquetempname @notbelongsname, @notbelongsname out
  20561.     IF @@ERROR<>0 OR @retcode<>0 return (1)
  20562.     exec ('create table ' + @notbelongsname + ' (bookmark int identity  primary key NOT NULL, tablenick int NOT NULL, rowguid uniqueidentifier NOT NULL,
  20563.         generation int NULL, lineage varbinary(255) NULL, type tinyint NOT NULL) ')
  20564.     if @@ERROR <>0 return (1)
  20565.     create table #temp_cont (temp_id int identity NOT NULL, tablenick int NOT NULL, rowguid uniqueidentifier NOT NULL,
  20566.             partchangegen int null, joinchangegen int null)
  20567.  
  20568.     /* step 2 setup pass through MSmerge_contents */
  20569.     /* article with permanent views can be handled with bulk inserts */
  20570.     set @artnick = 0
  20571.     set rowcount 0
  20572.     
  20573.     /* Get first article, go into loop */
  20574.     select @artnick = min(nickname) from sysmergearticles where pubid = @pubid and
  20575.          nickname > @artnick
  20576.  
  20577.     if @@ERROR <>0 return (1)        
  20578.  
  20579.  
  20580.     while (@artnick is not null)
  20581.         begin
  20582.         set @artnickstr = convert(nchar(10), @artnick)
  20583.         select @artviewobjid = sync_objid, @artbaseobjid = objid, @view_type = view_type,
  20584.             @procname = view_sel_proc, @sync_objid=sync_objid, @before_view_objid = before_view_objid from sysmergearticles where
  20585.             pubid = @pubid and nickname = @artnick
  20586.         /* Get name of rowguidcol. Aliasing doesn't work through a view. */
  20587.         select @rgcol = name from syscolumns where id = @artbaseobjid and ColumnProperty(@artbaseobjid, name, 'isrowguidcol') = 1
  20588.  
  20589.         /* UNDONE get view type from sysmergearticle to see if permanent view to use */
  20590.         set @artviewname = NULL
  20591.         if @view_type <> @temp_view
  20592.             select @artviewname = name, @artviewowner = user_name(uid) from sysobjects where
  20593.                 id = @artviewobjid
  20594.         if (@procname is not null)
  20595.             begin
  20596.             exec @retcode = @procname @artnick
  20597.             if @@ERROR <>0 or @retcode <> 0 return (1)
  20598.             end
  20599.         else
  20600.             begin
  20601.             delete from #temp_cont
  20602.             exec ('insert into #temp_cont (tablenick, rowguid, partchangegen, joinchangegen) 
  20603.                         select tablenick, rowguid, partchangegen, joinchangegen from MSmerge_contents where
  20604.                         tablenick  = ' + @artnickstr + ' and generation in (' +
  20605.                     @genlist + ') ')
  20606.             if @@ERROR <>0 return (1)        
  20607.             set @temp_id = 0
  20608.             select @temp_id = min(temp_id) from #temp_cont where temp_id > @temp_id
  20609.             while (@temp_id is not null)
  20610.                 begin
  20611.                 select @tablenick = tablenick, @rowguid = rowguid,
  20612.                    @partchangegen = partchangegen, @joinchangegen = joinchangegen 
  20613.                     from #temp_cont where temp_id = @temp_id
  20614.                 set @rowguidstr = '''' + convert(nchar(36), @rowguid) + ''''
  20615.                 exec @retcode = dbo.sp_MSbelongs @publisher, @publisher_db,    @publication, @tablenick, @rowguid, @retval    output, 0
  20616.                 if @@ERROR <>0 or @retcode <> 0 return (1)
  20617.                 if @retval = 1
  20618.                     begin
  20619.                     insert into #belong (tablenick, rowguid, flag, partchangegen, joinchangegen) values
  20620.                             (@artnick, @rowguid, 0, @partchangegen, @joinchangegen)
  20621.                     if @@ERROR <>0 return (1)    
  20622.                     end
  20623.  
  20624.                 else
  20625.                     begin
  20626.                     /* Checking partchangegen will tell us if we need to insert this */
  20627.                     if @partchangegen > @commongen
  20628.                         insert into #notbelong (tablenick, rowguid, flag) values
  20629.                             (@artnick, @rowguid, 0)
  20630.                     end
  20631.  
  20632.                 select @temp_id = min(temp_id) from #temp_cont where temp_id > @temp_id
  20633.                 end
  20634.  
  20635.             end
  20636.         /* Put changes in #notbelong  that aren't in #belong and have a relevant partchangegen    */
  20637.         -- If publication has before image tables, we should screen changes using the before image tables
  20638.         if @before_view_objid is not null
  20639.             begin
  20640.             set @before_view_name = OBJECT_NAME(@before_view_objid)
  20641.             execute ('insert into #notbelong (tablenick, rowguid, flag, partchangegen, joinchangegen)
  20642.                 select tablenick, c.rowguid, 0, partchangegen, joinchangegen
  20643.                     from MSmerge_contents c, #genlist g where c.generation = g.generation
  20644.                     and partchangegen > ' + @commongenstr + ' and tablenick = ' + @artnickstr + ' and
  20645.                     rowguid in (select ' + @rgcol + ' from ' + @before_view_name + ') and
  20646.                     rowguid not in (select rowguid from #belong)')
  20647.             if @@ERROR <>0 return (1)
  20648.             
  20649.             /* Add tombstones to ##notbelong */
  20650.             execute ('insert into #notbelong (tablenick, rowguid, flag, partchangegen, joinchangegen, type) 
  20651.                 select tablenick, rowguid,  0, generation, generation, type from
  20652.                 MSmerge_tombstone where tablenick = ' + @artnickstr + ' and
  20653.                     rowguid in (select ' + @rgcol + ' from ' + @before_view_name + ') and generation in (' + @genlist + ' ) ')
  20654.             if @@ERROR <>0 return (1)
  20655.  
  20656.             end
  20657.         else
  20658.             begin 
  20659.             insert into #notbelong (tablenick, rowguid, flag, partchangegen, joinchangegen)
  20660.                 select tablenick, c.rowguid, 0, partchangegen, joinchangegen
  20661.                     from MSmerge_contents c, #genlist g where c.generation = g.generation
  20662.                     and partchangegen > @commongen and tablenick = @artnick and
  20663.                     rowguid not in (select rowguid from #belong)
  20664.             if @@ERROR <>0 return (1)
  20665.             execute ('insert into #notbelong (tablenick, rowguid, flag, partchangegen, joinchangegen, type) 
  20666.                 select tablenick, rowguid,  0, generation, generation, type from
  20667.                 MSmerge_tombstone where tablenick = ' + @artnickstr + ' and generation in (' + @genlist + ' ) ')
  20668.             if @@ERROR <>0 return (1)
  20669.             end
  20670.         /* Move on to next article, repeat while loop */
  20671.         select @artnick = min(nickname) from sysmergearticles where pubid = @pubid and
  20672.              nickname > @artnick
  20673.         end
  20674.  
  20675.     drop table #temp_cont 
  20676.  
  20677.     /* Optimization: If joinchangegen and partchange are both null or < common gen,
  20678.     ** it is not necessary to expand #belong for that particular row.
  20679.     */
  20680.     
  20681.     select @maxfilterid = max(join_filterid) from sysmergesubsetfilters
  20682.  
  20683.     if @maxfilterid is not null
  20684.         begin
  20685.         update #belong set flag = @maxfilterid, skippedexpand = 1 where
  20686.             ((joinchangegen is null or joinchangegen <= @commongen) and
  20687.              (partchangegen is null or partchangegen <= @commongen))
  20688.  
  20689.         /* Expand the #belong temptable */
  20690.         exec @retcode = dbo.sp_MSexpandbelongs @pubid
  20691.         if @@ERROR<>0 OR @retcode<>0 return (1)
  20692.         end
  20693.         
  20694.     /* transfer rows from local temp to global temp */
  20695.     exec ('insert into ' + @belongsname + ' (tablenick, rowguid, generation, lineage, colv) 
  20696.         select distinct b.tablenick, b.rowguid, c.generation, c.lineage, c.colv1 from
  20697.         #belong b left outer join MSmerge_contents c  
  20698.         on  c.tablenick = b.tablenick and c.rowguid = b.rowguid order by b.tablenick, b.rowguid')
  20699.     if @@ERROR <>0 return (1)    
  20700.  
  20701.     /* If subscriber is sql server, we don't have to expand belongs */
  20702.     if @subissql = 0 or @dynamic_join_cnt > 0
  20703.         begin
  20704.         /* Expand the #notbelong temptable */
  20705.         exec dbo.sp_MSexpandnotbelongs @pubid
  20706.         end
  20707.  
  20708.     /* transfer rows from local temp to global temp */
  20709.     exec ('insert into ' + @notbelongsname + ' (tablenick, rowguid, generation, lineage, type) 
  20710.         select distinct b.tablenick, b.rowguid, coalesce (c.generation, t.generation), coalesce(c.lineage, t.lineage), b.type from
  20711.         #notbelong b left outer join MSmerge_contents c  
  20712.          on  c.tablenick = b.tablenick and c.rowguid = b.rowguid
  20713.         left outer join MSmerge_tombstone t on t.tablenick = b.tablenick and t.rowguid = b.rowguid
  20714.             order by b.tablenick DESC, b.rowguid ASC')
  20715.     if @@ERROR <>0 return (1)    
  20716. -- DEBUG select @belongcnt = count(*) from #belong
  20717. -- DEBUG select @nb_cnt = count(*) from #notbelong
  20718.     drop table #notbelong
  20719.  
  20720. -- DEBUG insert into master.dbo.debuglog2 (publisher, pubdb, hostname, twhen, commongen, belong_cnt, nb_cnt, genlist) values
  20721. -- DEBUG (@publisher, @publisher_db, host_name(), getdate(), @commongen, @belongcnt, @nb_cnt, @genlist)
  20722.  
  20723.     if not exists (select * from #belong)
  20724.         select @belongsname, @notbelongsname, -1
  20725.     else
  20726.         select distinct @belongsname, @notbelongsname, tablenick from #belong
  20727.     drop table #belong
  20728.     return (0)
  20729. go
  20730.  
  20731. grant exec on dbo.sp_MSsetupbelongs to public
  20732. go
  20733.  
  20734. --------------------------------------------------------------------------------
  20735. --. sp_MSexclause
  20736. --------------------------------------------------------------------------------
  20737. if exists (select * from sysobjects    where type = 'P'
  20738.     and name = 'sp_MSexclause')
  20739.     drop procedure sp_MSexclause
  20740. go
  20741.  
  20742. raiserror('Creating procedure sp_MSexclause', 0,1)
  20743. go
  20744.  
  20745. create proc sp_MSexclause  @tablenick int  as
  20746. set nocount on
  20747. declare @clause nvarchar(4000)
  20748. declare @filterid int
  20749. declare @joinnick int
  20750. declare @jointable nvarchar(258)
  20751. declare @table sysname
  20752. declare @basetable nvarchar(258)
  20753. declare @filter_clause nvarchar(2000)
  20754.  
  20755. exec sp_MStablenamefromnick @tablenick, @basetable out
  20756. select @table = QUOTENAME(name)  from sysobjects where id in (select 
  20757.             objid from sysmergearticles where nickname = @tablenick)
  20758.  
  20759. declare f_c CURSOR LOCAL FAST_FORWARD for  select art_nickname, join_filterclause 
  20760.     from sysmergesubsetfilters where join_nickname = @tablenick
  20761.     FOR READ ONLY
  20762. open f_c
  20763. fetch next from f_c into @joinnick, @filter_clause
  20764. while (@@fetch_status <> -1)
  20765.     begin
  20766.     exec sp_MStablenamefromnick @joinnick, @jointable out
  20767.     -- As helper proc for sp_MSmakeinsertproc, we can insert directly to the
  20768.     -- temp table as we build up more commands for the insert proc.
  20769.     -- Our commands are part of phase 8...
  20770.     set @clause = ' if @has_rows = 0 select @has_rows = 
  20771.         count(*) from ' + @basetable + ', ' + @jointable + ' where ' +
  20772.         @filter_clause + ' and ' + @table + '.rowguidcol = @rowguid
  20773. '
  20774.     insert into #tempcmd (phase, cmdtext) values (8, @clause)
  20775.  
  20776.     fetch next from f_c into @joinnick, @filter_clause
  20777.     end
  20778.  
  20779. close f_c
  20780. deallocate f_c
  20781. go
  20782.  
  20783. grant exec on dbo.sp_MSexclause to public
  20784. go
  20785.  
  20786. --------------------------------------------------------------------------------
  20787. --. sp_MSmakeinsertproc
  20788. --------------------------------------------------------------------------------
  20789. if exists (select * from sysobjects    where type = 'P'
  20790.     and name = 'sp_MSmakeinsertproc')
  20791.     drop procedure sp_MSmakeinsertproc
  20792. go
  20793.  
  20794. raiserror('Creating procedure sp_MSmakeinsertproc', 0,1)
  20795. go
  20796.  
  20797. create procedure sp_MSmakeinsertproc 
  20798.     (@tablename sysname, @ownername sysname, @procname sysname, @pubid uniqueidentifier)
  20799. as
  20800. declare @argname            sysname
  20801. declare @id                 int
  20802. declare @qualified_name        nvarchar(255)
  20803. declare @idstr                nvarchar(100)
  20804.  
  20805. if @ownername is NULL or @ownername=''
  20806.     select @qualified_name = QUOTENAME(@tablename)
  20807. else    
  20808.     select @qualified_name = QUOTENAME(@ownername) + '.' + QUOTENAME(@tablename)
  20809.     
  20810. select @id = object_id(@qualified_name)
  20811. if @id is NULL return (1)
  20812.  
  20813. set @idstr = rtrim(convert(nchar, @id))    
  20814.  
  20815. declare @retcode smallint
  20816. declare @colname sysname
  20817. declare @rgcolname sysname
  20818. declare @typename sysname
  20819. declare @colid smallint
  20820. declare @status tinyint
  20821. declare @len smallint
  20822. declare @prec smallint
  20823. declare @scale int
  20824. declare @tablenick int
  20825. declare @tablenickstr nvarchar(12)
  20826. declare @colordinal smallint
  20827. declare @cmdpiece nvarchar(4000)
  20828.  
  20829. set nocount on
  20830.  
  20831.     /*
  20832.     ** Check for subscribing permission
  20833.     */
  20834.     exec @retcode=sp_MSreplcheck_subscribe
  20835.     if @retcode<>0 or @@ERROR<>0 return (1)
  20836.     
  20837. execute @retcode = dbo.sp_MStablenickname @ownername, @tablename, @tablenick output
  20838. IF @@ERROR <> 0 or @retcode <>0 return (1)
  20839. set @tablenickstr = rtrim(convert(nchar, @tablenick))
  20840.  
  20841. -- create temp table to select the command text out of
  20842. create table #tempcmd (phase int NOT NULL, step int identity NOT NULL, cmdtext nvarchar(4000) NULL)
  20843.  
  20844. -- insert text pieces that don't repeat for each column
  20845.  
  20846. -- phase 0 : create procedure and fixed part of argument list
  20847. set @cmdpiece = 'create procedure dbo.'  + QUOTENAME(@procname) + ' (@rowguid uniqueidentifier, 
  20848.     @generation int, @lineage varbinary(255),  @colv varbinary(2048) '
  20849. insert into #tempcmd (phase, cmdtext) values (0, @cmdpiece)
  20850.  
  20851. -- phase 1 is rest of argument list; goes in during loop over columns
  20852. -- phase 2 : paren to close argument list, and variable declarations
  20853. set @cmdpiece = ') as
  20854.     declare @tablenick int
  20855.     declare @success int
  20856.     declare @retcode int
  20857.     declare @has_rows int
  20858.     set nocount on
  20859.     set @has_rows = 0
  20860.  
  20861.     exec @retcode = dbo.sp_MSreplcheck_connection @objid = ' + @idstr + '
  20862.         if @retcode<>0 or @@ERROR<>0 return (3)
  20863.     
  20864.     select @tablenick = ' + @tablenickstr + '
  20865.     set @success = 0
  20866.     '
  20867. insert into #tempcmd (phase, cmdtext) values (2, @cmdpiece)
  20868.  
  20869. -- if we already have a tombstone for this row, (especially a remove from partial) then
  20870. -- make sure we will set the generation so that it goes on down to subscribers of republishers
  20871. set @cmdpiece = 'if exists (select * from MSmerge_tombstone where tablenick = @tablenick and
  20872.             rowguid = @rowguid) set @has_rows = 1'
  20873. insert into #tempcmd (phase, cmdtext) values (2, @cmdpiece)
  20874.  
  20875. -- phase 3 is optional set identity insert on, goes in during loop if needed
  20876. -- phase 4 is beginning a sub transaction, setting save point and starting insert statement
  20877. set @cmdpiece = '
  20878.     begin transaction sub
  20879.     save transaction sp1
  20880.     if @metadata_type = 1 or @metadata_type = 5
  20881.         begin
  20882.         if not exists (select * from MSmerge_tombstone where tablenick = @tablenick and rowguid = @rowguid and
  20883.                         lineage = @lineage_old)
  20884.             begin
  20885.             set @success = 2
  20886.             commit transaction
  20887.             return 0
  20888.             end
  20889.         end
  20890.     exec dbo.sp_MSsetrowmetadata @tablenick, @rowguid, @generation, @lineage, @colv, 2
  20891.     insert into ' + @qualified_name + ' ('
  20892. insert into #tempcmd (phase, cmdtext) values (4, @cmdpiece)
  20893.  
  20894. -- phase 5 is column list that we are inserting; done in loop
  20895.  
  20896. -- phase 6 is just the opening and closing parens and VALUES keyword
  20897. set @cmdpiece = ') values ('
  20898. insert into #tempcmd (phase, cmdtext) values (6, @cmdpiece)
  20899.  
  20900. -- phase 7 is all of those arguments as the list of value expressions; done in loop
  20901. -- phase 8 finish insert, check status, etc.
  20902. -- if we have a permanent view, check for case where we inserted a row that doesn't
  20903. -- meet filters of subscriber we are getting the insert from
  20904. set @cmdpiece = ')
  20905.         if (@@rowcount = 1)
  20906.             begin
  20907.             set @success = 1
  20908.             end
  20909.         else
  20910.             begin
  20911.             select @success = 3
  20912.             end
  20913.         '
  20914. insert into #tempcmd (phase, cmdtext) values (8, @cmdpiece)
  20915.  
  20916.  
  20917. -- Add in pieces that check for inserting a row that instantly means other rows need to be downloaded
  20918. -- If we insert such a row, set the generation and partchangegen so that we will download everything
  20919. -- that needs to go.
  20920.  
  20921. exec sp_MSexclause @tablenick
  20922. set @cmdpiece = 'if @has_rows > 0     update MSmerge_contents set generation = 0, partchangegen = 0 where
  20923.             rowguid = @rowguid and tablenick = @tablenick'
  20924. insert into #tempcmd (phase, cmdtext) values (8, @cmdpiece)
  20925.  
  20926. if exists (select * from sysmergearticles where pubid = @pubid and objid = @id and
  20927.     view_type = 1)
  20928.     begin
  20929.     /* Get name of rowguidcol. Aliasing doesn't work through a view. */
  20930.     select @rgcolname = QUOTENAME(name) from syscolumns where id = @id and ColumnProperty(@id, name, 'isrowguidcol') = 1
  20931.     if @rgcolname is null
  20932.         set @rgcolname = 'rowguid'
  20933.     select @cmdpiece = ' if not exists (select * from ' + QUOTENAME(OBJECT_NAME(sync_objid))
  20934.         from sysmergearticles where pubid = @pubid and objid = @id
  20935.     set @cmdpiece = @cmdpiece + ' where ' + @rgcolname + ' = @rowguid) 
  20936.         begin
  20937.         update MSmerge_contents set generation = 0, partchangegen = 0 where
  20938.             rowguid = @rowguid and tablenick = @tablenick
  20939.         end
  20940.         '
  20941.     insert into #tempcmd (phase, cmdtext) values (8, @cmdpiece)
  20942.     end
  20943.  
  20944. set @cmdpiece = '
  20945.         if (@success = 3)
  20946.             begin
  20947.             rollback transaction sp1
  20948.             end
  20949.         commit transaction
  20950.         '
  20951. insert into #tempcmd (phase, cmdtext) values (8, @cmdpiece)
  20952.  
  20953. -- phase 9 is setting identity insert off if needed; done in loop
  20954. -- phase 10 is returning our success / failure status
  20955. set @cmdpiece = '
  20956.     return @success'
  20957. insert into #tempcmd (phase, cmdtext) values (10, @cmdpiece)
  20958.     
  20959. -- now loop over columns and insert missing command pieces
  20960. select @colid = min (colid) from syscolumns where id = @id and iscomputed<>1
  20961. select @colname = QUOTENAME(name), @status = status, @typename = type_name(xtype),
  20962.     @len = length,     @prec = COLUMNPROPERTY(id, name, 'precision'), @scale = scale
  20963.     from syscolumns 
  20964.     where id = @id and colid = @colid
  20965. if @typename='nvarchar' or @typename='nchar' -- a unit of nchar takes 2 bytes
  20966.     select @len = @len/2
  20967. set @colordinal = 1
  20968.  
  20969. while (@colname is not null)
  20970.     begin
  20971.     exec @retcode = dbo.sp_MSmaptype @typename out, @len, @prec, @scale
  20972.     if @@error<>0 OR @retcode <>0 return (1)
  20973.  
  20974.     select @argname = '@p' + rtrim(convert(nchar, @colordinal))
  20975.     -- add to argument list (phase 1)
  20976.     set @cmdpiece = ', ' + @argname + ' ' + @typename
  20977.     insert into #tempcmd (phase, cmdtext) values (1, @cmdpiece)
  20978.  
  20979.     -- add to column list and value list
  20980.     if (@colordinal = 1)
  20981.         begin
  20982.         -- column list is phase 5
  20983.         set @cmdpiece = @colname
  20984.         insert into #tempcmd (phase, cmdtext) values (5, @cmdpiece)
  20985.  
  20986.         -- argname for values list is phase 7
  20987.         set @cmdpiece = @argname
  20988.         insert into #tempcmd (phase, cmdtext) values (7, @cmdpiece)
  20989.         end
  20990.     else
  20991.         begin
  20992.         -- column list is phase 5; need preceding comma since not the first one.
  20993.         set @cmdpiece = ', ' + @colname
  20994.         insert into #tempcmd (phase, cmdtext) values (5, @cmdpiece)
  20995.  
  20996.         -- argname for values list is phase 7 need preceding comma since not the first one.
  20997.         set @cmdpiece = ', ' + @argname
  20998.         insert into #tempcmd (phase, cmdtext) values (7, @cmdpiece)
  20999.         end
  21000.         
  21001.     -- is this an identity column?
  21002.     if (@status = 128)
  21003.         begin
  21004.         -- turning identity insert on is phase 3
  21005.         set @cmdpiece = ' set identity_insert ' + @qualified_name + ' on'
  21006.         insert into #tempcmd (phase, cmdtext) values (3, @cmdpiece)
  21007.  
  21008.         -- turning identity insert on is phase 9
  21009.         set @cmdpiece = ' set identity_insert ' + @qualified_name + ' off'
  21010.         insert into #tempcmd (phase, cmdtext) values (9, @cmdpiece)
  21011.         end
  21012.  
  21013.     -- now set up to repeat the loop with the next column
  21014.     select @colid = min (colid) from syscolumns where id = @id and colid > @colid and iscomputed<>1
  21015.     set @colname = NULL
  21016.     if @colid is not null
  21017.         select @colname = QUOTENAME(name), @status = status, @typename = type_name(xtype), @len = length,
  21018.         @prec = COLUMNPROPERTY(id, name, 'precision'), @scale = scale
  21019.         from syscolumns where id = @id and colid = @colid
  21020.     if @typename='nvarchar' or @typename='nchar' -- a unit of nchar takes 2 bytes
  21021.         select @len = @len/2
  21022.     set @colordinal = @colordinal + 1
  21023.     end
  21024.  
  21025.     select @cmdpiece = ',@metadata_type tinyint = NULL, @lineage_old varbinary(255) = NULL'
  21026.     insert into #tempcmd (phase, cmdtext) values (1, @cmdpiece)
  21027.  
  21028.  
  21029. -- Now we select out the command text pieces in proper order so that our caller,
  21030. -- xp_execresultset will execute the command that creates the stored procedure.
  21031.  
  21032. select cmdtext from #tempcmd order by phase, step
  21033. go
  21034.  
  21035. exec dbo.sp_MS_marksystemobject sp_MSmakeinsertproc 
  21036. go
  21037. grant exec on dbo.sp_MSmakeinsertproc to public
  21038. go
  21039.  
  21040. --------------------------------------------------------------------------------
  21041. --. sp_MSmakeupdateproc
  21042. --------------------------------------------------------------------------------
  21043. if exists (select * from sysobjects    where type = 'P'
  21044.     and name = 'sp_MSmakeupdateproc')
  21045.     drop procedure sp_MSmakeupdateproc
  21046. go
  21047.  
  21048. raiserror('Creating procedure sp_MSmakeupdateproc', 0,1)
  21049. go
  21050.  
  21051. create procedure sp_MSmakeupdateproc 
  21052.     (@tablename sysname, @ownername sysname, @procname sysname)
  21053. as
  21054. declare @retcode             smallint
  21055. declare @argname            nvarchar(10)
  21056. declare @varname            nvarchar(10)
  21057. declare @cmdpiece            nvarchar(4000)
  21058. declare @qualified_name        nvarchar(255)
  21059.  
  21060. declare @littlecomp nvarchar(300)
  21061.  
  21062. declare @id int
  21063. declare @idstr nvarchar(100) 
  21064. set nocount on
  21065.  
  21066. if @ownername is NULL or @ownername=''
  21067.     select @qualified_name = QUOTENAME(@tablename)
  21068. else    
  21069.     select @qualified_name = QUOTENAME(@ownername) + '.' + QUOTENAME(@tablename)
  21070.  
  21071. select @id = object_id(@qualified_name)
  21072.     if @id is NULL return (1)
  21073.     
  21074. set @idstr = rtrim(convert(nchar, @id))    
  21075.  
  21076. declare @colname sysname
  21077. declare @typename sysname
  21078. declare @colid smallint
  21079. declare @colordinal smallint
  21080. declare @colordstr nvarchar(4)
  21081.  
  21082. declare @status tinyint
  21083. declare @len smallint
  21084. declare @blen smallint
  21085. declare @prec smallint
  21086. declare @scale int
  21087. declare @tablenick int
  21088. declare @tablenickstr nvarchar(12)
  21089.  
  21090.     /*
  21091.     ** Check for dbo permission
  21092.     */
  21093.     exec @retcode=sp_MSreplcheck_subscribe
  21094.     if @retcode<>0 or @@ERROR<>0 return (1)
  21095.     
  21096. execute @retcode = dbo.sp_MStablenickname @ownername, @tablename, @tablenick output
  21097. if @@ERROR <>0 OR @retcode <>0 return (1)
  21098. set @tablenickstr = rtrim(convert(nchar, @tablenick))
  21099.  
  21100. -- create temp table to select the command text out of
  21101. create table #tempcmd (phase int NOT NULL, step int identity NOT NULL, cmdtext nvarchar(4000) NULL)
  21102.  
  21103. -- insert text pieces that don't repeat for each column
  21104.  
  21105. -- phase 0 : create procedure and fixed part of argument list
  21106. set @cmdpiece = 'Create procedure dbo.' + @procname + ' (@rowguid uniqueidentifier, @setbm varbinary(125) = NULL,
  21107.     @metadata_type tinyint, @lineage_old varbinary(255), @generation int,
  21108.     @lineage_new varbinary(255), @colv varbinary(2048) '
  21109. insert into #tempcmd (phase, cmdtext) values (0, @cmdpiece)
  21110.  
  21111. -- phase 1 is rest of argument list; goes in during loop over columns
  21112. -- phase 2 paren to close argument list and fixed variable declarations
  21113. set @cmdpiece = ') as
  21114.     declare @tablenick int
  21115.     declare @failure int
  21116.     declare @success int
  21117.     declare @fset int
  21118.     declare @match int
  21119.     declare @retcode smallint
  21120.     set nocount on
  21121.     exec @retcode = dbo.sp_MSreplcheck_connection @objid = ' + @idstr + '
  21122.         if @retcode<>0 or @@ERROR<>0 return (3)
  21123.  
  21124.     select @tablenick = ' + @tablenickstr + '
  21125.     set @failure = 0
  21126.     '
  21127. insert into #tempcmd (phase, cmdtext) values (2, @cmdpiece)
  21128.  
  21129. -- phase 3 is rest of variable declarations; goes in during loop over columns
  21130. -- phase 4 begin a transaction, set savepoint in case we roll back, begin select to get current values
  21131. set @cmdpiece = 'begin transaction sub
  21132.     save transaction sp1
  21133.     select @success = 2'
  21134. insert into #tempcmd (phase, cmdtext) values (4, @cmdpiece)
  21135.  
  21136. -- phase 5 is middle part of select assigning column values to local variables -- goes in loop
  21137. -- phase 6 -- finish the select, check that metadata matches
  21138. set @cmdpiece = ' from ' + @qualified_name + ' (updlock) where rowguidcol = @rowguid
  21139.     set @match = @@rowcount
  21140.     exec dbo.sp_MScheckmetadatamatch @metadata_type, @rowguid, @tablenick, @lineage_old, @match output
  21141.     if (@match = 1)
  21142.         begin
  21143.         select @success = 1
  21144.     '
  21145. insert into #tempcmd (phase, cmdtext) values (6, @cmdpiece)
  21146.  
  21147. -- phase 7 is a bunch of if's that compare old values with new values ; goes in during loop
  21148. -- phase 8 finish the stored procedure
  21149. set @cmdpiece = '        if (@failure = 0)
  21150.         exec dbo.sp_MSsetrowmetadata @tablenick, @rowguid, @generation, @lineage_new, @colv, 2
  21151.         end
  21152.     if (@failure = 1)
  21153.         begin
  21154.         rollback transaction sp1
  21155.         select @success = 3
  21156.         end
  21157.     commit transaction
  21158.     return @success'
  21159. insert into #tempcmd (phase, cmdtext) values (8, @cmdpiece)
  21160.  
  21161. -- now do the loop over all columns and insert the missing pieces
  21162.  
  21163. -- don't script out computed columns
  21164. select @colid = min (colid) from syscolumns where id = @id and iscomputed <> 1
  21165. select @colname = QUOTENAME(name), @status = status, @typename = type_name(xtype), @blen = length,
  21166.     @prec = COLUMNPROPERTY(id, name, 'precision'), @scale = scale
  21167.     from syscolumns 
  21168.     where id = @id and colid = @colid
  21169. if @typename='nvarchar' or @typename='nchar' -- a unit of nchar takes 2 bytes
  21170.     set @len = @blen/2
  21171. else
  21172.     set @len = @blen
  21173. set @colordinal = 1
  21174.  
  21175. while (@colname is not null)
  21176.     begin
  21177.     if (@status = 128)
  21178.         begin
  21179.         -- just skip past identity columns as they can't be updated
  21180.         select @colid = min (colid) from syscolumns where id = @id and colid > @colid and iscomputed<>1
  21181.         set @colname = NULL
  21182.         select @colname = QUOTENAME(name), @status = status, @typename = type_name(xtype), @blen = length,
  21183.             @prec = COLUMNPROPERTY(id, name, 'precision'), @scale = scale
  21184.             from syscolumns 
  21185.             where id = @id and colid = @colid
  21186.         if @typename='nvarchar' or @typename='nchar' -- a unit of nchar takes 2 bytes
  21187.             set @len = @blen/2
  21188.         else
  21189.             set @len = @blen
  21190.         set @colordinal = @colordinal + 1
  21191.         end
  21192.     set @colordstr = convert(nvarchar(4), @colordinal)
  21193.     exec @retcode = dbo.sp_MSmaptype @typename out, @len, @prec, @scale
  21194.     if @@ERROR <>0 OR @retcode <>0 return (1)
  21195.  
  21196.     -- put in argument list element (phase 1)
  21197.     set @argname = '@p' + rtrim(@colordstr)
  21198.     set @cmdpiece = ',
  21199.         ' + @argname + ' ' + @typename + ' = NULL '
  21200.     insert into #tempcmd (phase, cmdtext) values (1, @cmdpiece)
  21201.  
  21202.     -- put in declaration for variable (phase 3) -- text and image get no variable
  21203.     if (@typename <> 'ntext' and @typename <> 'text' and @typename <> 'image')
  21204.         begin
  21205.         set @varname = '@l' + rtrim(@colordstr)
  21206.  
  21207.         set @cmdpiece = 'declare ' + @varname + ' ' + @typename + '
  21208. '
  21209.         insert into #tempcmd (phase, cmdtext) values (3, @cmdpiece)
  21210.  
  21211.         -- put in set piece to initialize variable to old value in select statement (phase 5)
  21212.         set @cmdpiece = ', ' + @varname + ' = ' + @colname
  21213.         insert into #tempcmd (phase, cmdtext) values (5, @cmdpiece)
  21214.  
  21215.         -- put in if piece that compares old value with new, checks bit if argument is null
  21216.         if (@typename like '%char%')
  21217.             begin
  21218.             -- Compare binaries instead of variables so that case changes are caught as different
  21219.             set @littlecomp = 'convert(varbinary(' + rtrim(convert(nchar, @blen)) + '), ' + @argname + ')
  21220.                 = convert(varbinary(' + rtrim(convert(nchar, @blen)) + '), ' + @varname + ')'
  21221.             end
  21222.         else
  21223.             begin
  21224.             set @littlecomp = @argname + ' = ' + @varname
  21225.             end
  21226.             
  21227.         set @cmdpiece = '            if ' + @littlecomp + '
  21228.             set @fset = 0
  21229.             else if ( ' + @varname + ' is null and ' + @argname + ' is null) 
  21230.             set @fset = 0
  21231.             else if ' + @argname + ' is not null
  21232.                 set @fset = 1
  21233.             else exec @fset = dbo.sp_MStestbit @setbm, ' + @colordstr + '
  21234.             if @fset <> 0
  21235.                 begin
  21236.                 update ' + @qualified_name + ' set ' + @colname + ' = ' + @argname + ' where rowguidcol = @rowguid 
  21237.                 if (@@rowcount <> 1)
  21238.                     set @failure = 1
  21239.                 end 
  21240.             '
  21241.         insert into #tempcmd (phase, cmdtext) values (7, @cmdpiece)
  21242.         end
  21243.     else
  21244.         begin
  21245.         -- for text and image, we just test if argument is null and whether bit is set
  21246.         -- build conditional update (phase 7)
  21247.         set @cmdpiece =  '            if ' + @argname + ' is not null
  21248.                 set @fset = 1
  21249.             else exec @fset = dbo.sp_MStestbit @setbm, ' + @colordstr + '
  21250.             if @fset <> 0
  21251.                 begin
  21252.                 update ' + @qualified_name + ' set ' + @colname + ' = ' + @argname + ' where rowguidcol = @rowguid 
  21253.                 if (@@rowcount <> 1)
  21254.                     set @failure = 1
  21255.                 end 
  21256.             '
  21257.         -- Now insert the command to temp table
  21258.         insert into #tempcmd (phase, cmdtext) values (7, @cmdpiece)    
  21259.         end
  21260.         
  21261.     -- Advance loop to next column and repeat!
  21262.     select @colid = min (colid) from syscolumns where id = @id and colid > @colid and iscomputed<>1
  21263.     set @colname = NULL
  21264.     if (@colid is not null)
  21265.         begin
  21266.         select @colname = QUOTENAME(name), @status = status, @typename = type_name(xtype), @blen = length,
  21267.             @prec = COLUMNPROPERTY(id, name, 'precision'), @scale = scale
  21268.             from syscolumns 
  21269.             where id = @id and colid = @colid
  21270.             if @typename='nvarchar' or @typename='nchar' -- a unit of nchar takes 2 bytes
  21271.                 set @len = @blen/2
  21272.             else
  21273.                 set @len = @blen
  21274.         set @colordinal = @colordinal + 1
  21275.         end
  21276.     end
  21277.  
  21278. -- Now we select out the command text pieces in proper order so that our caller,
  21279. -- xp_execresultset will execute the command that creates the stored procedure.
  21280.  
  21281. select cmdtext from #tempcmd order by phase, step
  21282.  
  21283. go
  21284.  
  21285. grant exec on dbo.sp_MSmakeupdateproc to public
  21286. go
  21287.  
  21288. --------------------------------------------------------------------------------
  21289. --. sp_MSmakeselectproc
  21290. --------------------------------------------------------------------------------
  21291. if exists (select * from sysobjects    where type = 'P'
  21292.     and name = 'sp_MSmakeselectproc')
  21293.     drop procedure sp_MSmakeselectproc
  21294. go
  21295.  
  21296. raiserror('Creating procedure sp_MSmakeselectproc', 0,1)
  21297. go
  21298.  
  21299. create procedure sp_MSmakeselectproc 
  21300.     (@tablename sysname, @ownername sysname, @procname sysname)
  21301. as
  21302. declare @retcode             smallint
  21303. declare @argname            nvarchar(10)
  21304. declare @varname            nvarchar(10)
  21305. declare @cmdpiece            nvarchar(4000)
  21306. declare @qualified_name        nvarchar(255)
  21307. declare @column_list        nvarchar(4000)
  21308. declare @littlecomp nvarchar(300)
  21309. declare @colid                int
  21310. declare @col_name            sysname
  21311. declare @id int
  21312. set nocount on
  21313.  
  21314. if @ownername is NULL or @ownername=''
  21315.     select @qualified_name = QUOTENAME(@tablename)
  21316. else    
  21317.     select @qualified_name = QUOTENAME(@ownername) + '.' + QUOTENAME(@tablename)
  21318.  
  21319. select @id = object_id(@qualified_name)
  21320.     if @id is NULL return (1)
  21321.  
  21322. /*
  21323. ** Dynamically generate column list excluding computed columns
  21324. */
  21325.  
  21326. if EXISTS (select name from syscolumns where id=@id and iscomputed=1)
  21327. BEGIN
  21328.     select @column_list = ''
  21329.     DECLARE column_cursor CURSOR LOCAL FAST_FORWARD FOR
  21330.         select name from syscolumns where id=@id and iscomputed<>1
  21331.     FOR READ ONLY
  21332.     open column_cursor
  21333.     fetch next from column_cursor into @col_name
  21334.     WHILE (@@fetch_status <> -1)
  21335.     BEGIN
  21336.             if LOWER(@col_name)='rowguid' 
  21337.                 select @col_name = 'rowguidcol' --Use alias to avoid conflict with #cont table
  21338.             else
  21339.                 set @col_name = QUOTENAME(@col_name)
  21340.             if @column_list=''
  21341.                 select @column_list = @col_name
  21342.             else
  21343.                 select @column_list = @column_list + ', ' + @col_name            
  21344.             fetch next from column_cursor into @col_name            
  21345.     END
  21346.     close column_cursor
  21347.     deallocate column_cursor
  21348.  
  21349.     if @column_list=''
  21350.     begin
  21351.         RAISERROR(21125, 16, -1)
  21352.         return (1)
  21353.     end
  21354. END
  21355. else 
  21356.     select @column_list = '*'
  21357.  
  21358. /*
  21359. ** Check for dbo permission
  21360. */
  21361.     exec @retcode=sp_MSreplcheck_subscribe
  21362.     if @retcode<>0 or @@ERROR<>0 return (1)
  21363.  
  21364. set @cmdpiece = 'Create procedure dbo.'  + QUOTENAME(@procname) + ' (@type int output, @rowguid uniqueidentifier=NULL) AS
  21365.         declare @retcode     int
  21366.         declare @objid        int
  21367.         set nocount on
  21368.         select @objid = object_id(''' + @qualified_name + ''')
  21369.         exec @retcode = dbo.sp_MSreplcheck_connection @objid=@objid
  21370.         if @@ERROR<>0 or @retcode<>0 
  21371.             return (1)
  21372.  
  21373.         if @type = 1 
  21374.             select ' + @column_list + ' from ' + @qualified_name + ' where rowguidcol = @rowguid
  21375.             
  21376.         else if @type < 4 
  21377.             select c.tablenick, c.rowguid, c.generation, c.lineage, c.colv1, ' + @column_list + ' from ' +
  21378.                  @qualified_name + ' t,  #cont c where
  21379.                       t.rowguidcol = c.rowguid
  21380.                      order by c.rowguid
  21381.         else if @type = 4
  21382.             begin
  21383.                 set @type = 0
  21384.             if exists (select * from ' + @qualified_name + ' where rowguidcol = @rowguid)
  21385.                 set @type = 3
  21386.             return 0
  21387.             end
  21388.  
  21389.         else if @type = 5
  21390.             delete ' + @qualified_name + ' where rowguidcol = @rowguid
  21391.         else if @type = 6 -- sp_MSenumcolumns
  21392.             select ' + @column_list + ' from ' + @qualified_name + ' where 1=2
  21393.         else if @type = 7 -- sp_MSlocktable
  21394.             select count(*) from ' + @qualified_name + '(tablock holdlock) where 1 = 2
  21395.         else if @type = 8 -- put update lock
  21396.             if not exists (select * from ' + @qualified_name + '(UPDLOCK) where rowguidcol = @rowguid)
  21397.                 RAISERROR(20031 , 16, -1)'
  21398.             
  21399. exec (@cmdpiece)
  21400. go
  21401.             
  21402. grant exec on dbo.sp_MSmakeselectproc to public
  21403. go
  21404.  
  21405. --------------------------------------------------------------------------------
  21406. --. sp_MSexpandsubsnb
  21407. --------------------------------------------------------------------------------
  21408. if exists (select * from sysobjects    where type = 'P'
  21409.     and name = 'sp_MSexpandsubsnb')
  21410.     drop procedure sp_MSexpandsubsnb
  21411. go
  21412.  
  21413. raiserror('Creating procedure sp_MSexpandsubsnb', 0,1)
  21414. go
  21415.  
  21416. create PROCEDURE sp_MSexpandsubsnb (@pubid uniqueidentifier)
  21417. AS
  21418.     declare @filterid int
  21419.     declare @base_nick int
  21420.     declare @join_nick int
  21421.     declare @basetable nvarchar(258)
  21422.     declare @jointable nvarchar(258)
  21423.     declare @join_clause nvarchar(4000)
  21424.     declare @retcode int
  21425.     declare @base_nickstr nvarchar(10)
  21426.     declare @join_unique_key int
  21427.  
  21428.     /* get first filter to expand on */
  21429.     select @filterid = min(join_filterid) from sysmergesubsetfilters f, #notbelong nb
  21430.         where pubid = @pubid and nb.tablenick = f.join_nickname and f.join_filterid > nb.flag
  21431.  
  21432.     while @filterid is not null
  21433.         begin
  21434.         /* get join clause and tables for this filter */
  21435.         select @join_nick = join_nickname, @join_clause = join_filterclause,
  21436.             @base_nick = art_nickname, @join_unique_key = join_unique_key from sysmergesubsetfilters where
  21437.                 pubid = @pubid and join_filterid = @filterid
  21438.         exec @retcode = dbo.sp_MStablenamefromnick @join_nick, @jointable out, @pubid
  21439.         exec @retcode = dbo.sp_MStablenamefromnick @base_nick, @basetable out, @pubid
  21440.         set @base_nickstr = convert(nchar(10), @base_nick)
  21441.  
  21442.         /* Mark rows so that we know we've expanded those rows for this filter */
  21443.         update #notbelong set flag = @filterid where flag < @filterid
  21444.         
  21445.         /* exec an insert/select query to expand #notbelong */
  21446.         exec ('insert into #notbelong (tablenick, rowguid, flag) select ' +
  21447.                 @base_nickstr + ', ' + @basetable + '.RowGuidCol, 0 from ' + @basetable + 
  21448.                 ', ' + @jointable + ' where ( ' + @jointable + '.RowGuidCol in 
  21449.                     (select rowguid from #notbelong) ) and ' + @join_clause)
  21450.         /* 
  21451.         ** if any rows inserted, try to contract the #notbelong table.
  21452.         ** Only join filters that are non unique need to contract the 
  21453.         ** NOTBELONGS table - 
  21454.         */
  21455.         if @@rowcount <> 0 and @join_unique_key = 0
  21456.             exec @retcode = dbo.sp_MScontractsubsnb @pubid, @base_nick, @basetable
  21457.         
  21458.         /* get next filter to expand with */
  21459.         select @filterid = min(join_filterid) from sysmergesubsetfilters f, #notbelong nb
  21460.             where pubid = @pubid and nb.tablenick = f.join_nickname and f.join_filterid > nb.flag
  21461.         end
  21462. go
  21463.  
  21464. grant exec on dbo.sp_MSexpandsubsnb to public
  21465. go
  21466.  
  21467. --------------------------------------------------------------------------------
  21468. --. sp_MSdelsubrows
  21469. --------------------------------------------------------------------------------
  21470. if exists (select * from sysobjects    where type = 'P'
  21471.     and name = 'sp_MSdelsubrows')
  21472.     drop procedure sp_MSdelsubrows
  21473. go
  21474.  
  21475. raiserror('Creating procedure sp_MSdelsubrows', 0,1)
  21476. go
  21477.  
  21478. create PROCEDURE sp_MSdelsubrows 
  21479.     (@rowguid         uniqueidentifier,
  21480.     @tablenick     int,
  21481.     @metadata_type tinyint, /* 0 - Missing, 1 - Tombstone, 2 - Contents, 3 - ContentsDeferred */
  21482.     @lineage_old varbinary(255),
  21483.     @generation int,
  21484.     @lineage_new varbinary(255),
  21485.     @pubid uniqueidentifier = NULL,
  21486.     @rowsdeleted INT = NULL OUTPUT)
  21487.  
  21488. as
  21489.     set nocount on
  21490.     declare @success int 
  21491.     declare @tablename         nvarchar(258)
  21492.     declare @rowguidstr        nvarchar(40)
  21493.     declare @match             int
  21494.     declare @new_metatype    tinyint
  21495.     declare @retcode         smallint
  21496.     declare @reason         nvarchar(255)
  21497.     declare @procname         nvarchar(258)
  21498.     declare @ownername        sysname
  21499.     /* By default this sp should delete exactly one row */
  21500.     set    @rowsdeleted = 1
  21501.  
  21502.     /*
  21503.     ** Check to see if current publication has permission
  21504.     */
  21505.     exec @retcode=sp_MSreplcheck_connection
  21506.         @tablenick = @tablenick
  21507.     if @retcode<>0 or @@ERROR<>0 return (1)
  21508.     
  21509.     select @success = 0
  21510.     /* Parameter validation */
  21511.     if (@rowguid is null)
  21512.         begin
  21513.         RAISERROR(14043, 16, -1, '@rowguid')
  21514.         return (0)
  21515.         end
  21516.     if (@tablenick is null)
  21517.         begin
  21518.         RAISERROR(14043, 16, -1, '@tablenick')
  21519.         return (0)
  21520.         end
  21521.     if @pubid is NULL
  21522.         exec @retcode = dbo.sp_MStablenamefromnick    @tablenick, @tablename output
  21523.     else
  21524.         exec @retcode = dbo.sp_MStablenamefromnick    @tablenick, @tablename output, @pubid
  21525.     if @@ERROR<>0 return (0)
  21526.  
  21527.     if (@tablename is null)
  21528.         begin
  21529.         RAISERROR(14043, 16, -1, '@tablename')
  21530.         return (0)
  21531.         end
  21532.     if (@lineage_new is null)
  21533.         begin
  21534.         RAISERROR(14043, 16, -1, '@lineage_new')
  21535.         return (0)
  21536.         end
  21537.  
  21538.     if (not exists(select * from sysobjects where name = 'MSmerge_contents'))
  21539.         begin
  21540.         RAISERROR(20054 , 16, -1)
  21541.         return (0)
  21542.         end
  21543.     set @rowguidstr = '''' + convert(nchar(36), @rowguid) + ''''
  21544.  
  21545. -- DEBUG    insert into master.dbo.debuglog(tablenick, rowguid, type, twhen, comment) values
  21546. -- DEBUG    (@tablenick, @rowguid, @metadata_type, getdate(), 'sp_MSdelsubrows')
  21547.  
  21548.     -- Are we just changing the type of a tombstone?
  21549.     if (@metadata_type = 5 and exists (select * from MSmerge_tombstone where
  21550.         rowguid = @rowguid and tablenick = @tablenick))
  21551.         begin
  21552.         return @success
  21553.         end
  21554.  
  21555.     -- Are we just changing the type of a tombstone?
  21556.     if (@metadata_type = 1 and exists (select * from MSmerge_tombstone where
  21557.         rowguid = @rowguid and tablenick = @tablenick))
  21558.         begin
  21559.         set @reason = formatmessage (20562) -- User delete
  21560.         update MSmerge_tombstone set type = @metadata_type, reason = @reason where
  21561.             rowguid = @rowguid and tablenick = @tablenick
  21562.         set @success = 1
  21563.         return @success
  21564.         end
  21565.  
  21566.  
  21567.     -- Are we just changing the type of a tombstone?
  21568.     if (@metadata_type = 6 and exists (select * from MSmerge_tombstone where
  21569.         rowguid = @rowguid and tablenick = @tablenick))
  21570.         begin
  21571.         set @reason = formatmessage (20564) -- System deleted
  21572.         update MSmerge_tombstone set type = @metadata_type, reason = @reason where
  21573.             rowguid = @rowguid and tablenick = @tablenick
  21574.         set @success = 1
  21575.         return @success
  21576.         end
  21577.  
  21578.     -- begin transaction and lock row that we plan to delete
  21579.     begin transaction
  21580.  
  21581.         select @ownername = user_name(uid) from sysobjects where id = object_id(@tablename)
  21582.         select @procname = select_proc from sysmergearticles where objid = object_id(@tablename)  and pubid = @pubid
  21583.         exec @retcode = @procname @type =8, @rowguid=@rowguid
  21584.  
  21585.         select @success = 2
  21586.         
  21587.     if @metadata_type = 5
  21588.         begin
  21589.         set @match = 1
  21590.         set @new_metatype = 5
  21591.         end
  21592.     else if @metadata_type = 6
  21593.         begin
  21594.         set @match = 1
  21595.         set @new_metatype = 6
  21596.         end
  21597.     else
  21598.         begin
  21599.         exec @retcode=sp_MScheckmetadatamatch @metadata_type, @rowguid, @tablenick, @lineage_old, @match output
  21600.  
  21601.         set @new_metatype = 1
  21602.         end
  21603.     if (@match = 1)
  21604.         begin
  21605.         
  21606.         /* If there are any joinfilters with this as the join table, try to expand to deleting
  21607.         ** a set of related rows.
  21608.         */
  21609.         if (exists (select * from sysmergesubsetfilters where pubid = @pubid and
  21610.                         join_nickname = @tablenick))
  21611.             begin
  21612.             declare @tn int
  21613.             declare @table_name sysname
  21614.             
  21615.             set @reason = formatmessage (20563) -- Moved out of partial range
  21616.             /* create temp and put in our tablenick, rowguid */
  21617.             create table #notbelong (tablenick int NOT NULL,
  21618.                 rowguid uniqueidentifier NOT NULL, flag int NOT NULL)
  21619.             create index #indnbelong on #notbelong (rowguid)
  21620.             insert into #notbelong (tablenick, rowguid, flag) values
  21621.                     (@tablenick, @rowguid, 0)
  21622.                     
  21623.             /* call expand proc */
  21624.             exec @retcode = dbo.sp_MSexpandsubsnb @pubid
  21625.  
  21626.             select @rowsdeleted = count(*) from #notbelong
  21627.             
  21628.             select @tn = max(tablenick) from #notbelong where flag > -1
  21629.             while @tn is not null
  21630.                 begin
  21631.                 exec @retcode = dbo.sp_MStablenamefromnick @tn, @table_name out, @pubid
  21632.                 /* delete all rows indicated by the temp table */
  21633.                 exec ('delete from ' + @table_name + ' where RowGuidCol in 
  21634.                     (select rowguid from #notbelong)' )
  21635.                 /* change tombstone type for those rows */
  21636.                 update MSmerge_tombstone set type = 5, reason = @reason where tablenick = @tn and
  21637.                     rowguid in (select rowguid from #notbelong)
  21638.                     
  21639.                 /* move on to next nickname - decreasing makes delete order correct */
  21640.                 update #notbelong set flag = -1 where tablenick = @tn
  21641.                 select @tn = max(tablenick) from #notbelong where flag > -1
  21642.                 end
  21643.  
  21644.             /* drop temp, set success */
  21645.             drop table #notbelong
  21646.             exec dbo.sp_MSsetrowmetadata @tablenick, @rowguid, @generation, @lineage_new, NULL, @new_metatype
  21647.             select @success = 1
  21648.             end
  21649.         else
  21650.             begin
  21651.         
  21652.             /*
  21653.             ** select_proc makes a delete with @type = 5, despite its name. 
  21654.             */
  21655.             exec @retcode = @procname @type =5, @rowguid=@rowguid
  21656.         
  21657.             if (@@error = 0 and @@rowcount = 1)
  21658.                 begin
  21659.                 exec dbo.sp_MSsetrowmetadata @tablenick, @rowguid, @generation, @lineage_new, NULL, @new_metatype
  21660.                 select @success = 1
  21661.                 end
  21662.             else
  21663.                 select @success = 3
  21664.             end
  21665.         end
  21666.     commit
  21667.     return (@success)
  21668. go
  21669.  
  21670. grant exec on dbo.sp_MSdelsubrows to public
  21671. go
  21672.  
  21673. --------------------------------------------------------------------------------
  21674. --. sp_MSmakeviewproc
  21675. --------------------------------------------------------------------------------
  21676. if exists (select * from sysobjects    where type = 'P'
  21677.     and name = 'sp_MSmakeviewproc')
  21678.     drop procedure sp_MSmakeviewproc
  21679. go
  21680.  
  21681. raiserror('Creating procedure sp_MSmakeviewproc', 0,1)
  21682. go
  21683.  
  21684. create procedure sp_MSmakeviewproc 
  21685.     (@viewname sysname, @ownername sysname, @procname nvarchar(290), @rgcol sysname, @source_id int)
  21686. as
  21687. declare @retcode             smallint
  21688. declare @varname            nvarchar(10)
  21689. declare @cmdpiece            nvarchar(4000)
  21690. declare @column_list        nvarchar(4000)
  21691. declare @col_name            sysname
  21692.  
  21693. set nocount on
  21694.  
  21695. if EXISTS (select name from syscolumns where id=@source_id and iscomputed=1)
  21696. BEGIN
  21697.     select @column_list = ''
  21698.     DECLARE column_cursor CURSOR LOCAL FAST_FORWARD FOR
  21699.         select name from syscolumns where id=@source_id and iscomputed<>1
  21700.     FOR READ ONLY
  21701.     open column_cursor
  21702.     fetch next from column_cursor into @col_name
  21703.     WHILE (@@fetch_status <> -1)
  21704.     BEGIN
  21705.             if LOWER(@col_name)='rowguid' 
  21706.                 select @col_name = 'v.rowguid' --Use alias to avoid conflict with #cont table
  21707.             else
  21708.                 set @col_name = QUOTENAME(@col_name)
  21709.             if @column_list=''
  21710.                 select @column_list = @col_name
  21711.             else
  21712.                 select @column_list = @column_list + ', ' + @col_name            
  21713.             fetch next from column_cursor into @col_name            
  21714.     END
  21715.     close column_cursor
  21716.     deallocate column_cursor
  21717.  
  21718.     if @column_list=''
  21719.     begin
  21720.         RAISERROR(21125, 16, -1)
  21721.         return (1)
  21722.     end
  21723. END
  21724. else 
  21725.     select @column_list = '*'
  21726.  
  21727. select @procname=QUOTENAME(@procname)
  21728.  
  21729. set @cmdpiece = 'create procedure dbo.' + @procname + ' (@tablenick int, @max_rows int = NULL,
  21730.     @guidlast uniqueidentifier = NULL) 
  21731.     AS
  21732.  
  21733.     set nocount on
  21734.     set rowcount 0
  21735.     if  @max_rows is not null
  21736.         begin
  21737.         -- used to select data for initial pop. of subscriber for dynamic filtered publication
  21738.         set rowcount @max_rows
  21739.         declare @lin varbinary (255)
  21740.         declare @cv varbinary (2048)
  21741.         declare @replnick int
  21742.         declare @objid int
  21743.         declare @ccols int
  21744.  
  21745.         select @objid = objid from sysmergearticles where nickname = @tablenick
  21746.         select @ccols = max(colid) from syscolumns where id = @objid
  21747.         
  21748.         exec dbo.sp_MSgetreplnick @nickname = @replnick out
  21749.         if (@@error <> 0) or @replnick IS NULL 
  21750.                 begin
  21751.             RAISERROR (14055, 11, -1)
  21752.             RETURN(1)
  21753.             end                 
  21754.         set @lin = { fn UPDATELINEAGE(0x0, @replnick) }
  21755.         set @cv = { fn INITCOLVS(@ccols, @replnick) }
  21756.  
  21757.         select @tablenick, v.' + @rgcol + ', coalesce (c.generation,1), 
  21758.             coalesce (c.lineage, @lin), coalesce (c.colv1, @cv), ' + @column_list + ' from ' +
  21759.                  QUOTENAME(@ownername) + '.' +
  21760.                     QUOTENAME(@viewname) + ' v left outer join  MSmerge_contents c on
  21761.                       v.' + @rgcol + ' = c.rowguid and c.tablenick = @tablenick where v.' + @rgcol + ' > @guidlast 
  21762.                      order by v.' + @rgcol + '
  21763.         return (1)        
  21764.         end
  21765.     insert into #belong (tablenick, rowguid, flag, partchangegen, joinchangegen)
  21766.         select ct.tablenick, ct.rowguid, 0, ct.partchangegen, ct.joinchangegen
  21767.                     from  MSmerge_contents ct, #genlist g, ' + QUOTENAME(@ownername) + '.' +
  21768.                     QUOTENAME(@viewname) + ' v where ct.tablenick = @tablenick
  21769.                     and (ct.generation = g.generation  or ct.partchangegen = g.generation) 
  21770.                     and ct.rowguid = v.' + @rgcol + '
  21771.     if @@ERROR <> 0
  21772.         begin
  21773.         RAISERROR(''Error selecting from view'' , 16, -1)
  21774.         return (1)    
  21775.         end'
  21776.  
  21777.             
  21778. exec (@cmdpiece)
  21779. exec dbo.sp_MS_marksystemobject @procname
  21780. exec ('grant exec on ' + @procname + ' to public')
  21781. go
  21782.             
  21783. grant exec on dbo.sp_MSmakeviewproc to public
  21784. go
  21785.  
  21786. --------------------------------------------------------------------------------
  21787. --. sp_MScreatebeforetable
  21788. --------------------------------------------------------------------------------
  21789. if exists (select * from sysobjects    where type = 'P'
  21790.     and name = 'sp_MScreatebeforetable')
  21791.     drop procedure sp_MScreatebeforetable
  21792. go
  21793.  
  21794. raiserror('Creating procedure sp_MScreatebeforetable', 0,1)
  21795. go
  21796.  
  21797. create procedure sp_MScreatebeforetable
  21798.     @objid int
  21799. AS
  21800.     declare     @command            nvarchar(4000)
  21801.     declare     @objidstr            nvarchar(12)
  21802.     declare     @dbname             sysname
  21803.     declare        @oldname            sysname
  21804.     declare     @newname sysname
  21805.     declare     @nameguid uniqueidentifier
  21806.     declare     @retcode int
  21807.      declare @tablenick int
  21808.  
  21809.     set nocount on
  21810.  
  21811. -- If no publication including this table needs before images, just return
  21812.     if not exists (select * from sysmergepublications p, sysmergearticles a where
  21813.             a.objid = @objid and p.pubid = a.pubid and p.keep_before_values = 1)
  21814.         return (0)
  21815.     select @tablenick = max(nickname) from sysmergearticles where objid = @objid
  21816.     if @tablenick is null return (1)
  21817.  
  21818. -- If a before image table already exists for this table, we need to drop it and create a new one
  21819.     select @oldname = max(o.name) from sysobjects o, sysmergearticles a where
  21820.         a.objid = @objid and o.id = a.before_image_objid
  21821.     if @oldname is not null
  21822.         begin
  21823.            exec @retcode = sp_MShelpalterbeforetable @objid, @oldname
  21824.            if @retcode <> 0 return (1)
  21825.            return 0
  21826.         end
  21827.  
  21828. -- If this table is not involved with any filters or join filters, don't bother
  21829.     if not exists (select * from sysmergesubsetfilters where art_nickname = @tablenick
  21830.         or join_nickname = @tablenick) and
  21831.         not exists (select * from sysmergearticles where nickname = @tablenick and
  21832.             datalength (subset_filterclause) > 1)
  21833.         return 0
  21834.     
  21835. -- Generate a unique name for our new table
  21836.     set @nameguid = newid()
  21837.     exec @retcode = dbo.sp_MSguidtostr @nameguid, @newname out
  21838.     set @newname = 'MS_bi' + @newname
  21839.     if @@ERROR <>0 OR @retcode <>0 return (1)
  21840.  
  21841. -- Call xp_execresultset with helper function command
  21842.     set @objidstr = convert(nvarchar(12), @objid)
  21843.     set @dbname = db_name()
  21844.  
  21845.        set @command = 'exec dbo.sp_MShelpcreatebeforetable '  + @objidstr + ', ''' + @newname + '''' 
  21846.        exec @retcode = master..xp_execresultset @command, @dbname
  21847.        if @retcode <> 0 return (1)
  21848.  
  21849.     update sysmergearticles set before_image_objid = object_id( @newname )
  21850.         where objid = @objid
  21851.  
  21852.     -- Now create a cleanup proc and grant execute on it..
  21853.     set @command = 'create procedure ' + @newname + '_clean @mingen int  AS
  21854.         delete from ' + @newname + ' where generation < @mingen '
  21855.     exec (@command)
  21856.     set @command = 'grant execute on ' + @newname + '_clean to public'
  21857.     exec (@command)
  21858.  
  21859. go
  21860.  
  21861. --------------------------------------------------------------------------------
  21862. --. sp_MShelpcreatebeforetable
  21863. --------------------------------------------------------------------------------
  21864. if exists (select * from sysobjects    where type = 'P'
  21865.     and name = 'sp_MShelpcreatebeforetable')
  21866.     drop procedure sp_MShelpcreatebeforetable
  21867. go
  21868.  
  21869. raiserror('Creating procedure sp_MShelpcreatebeforetable', 0,1)
  21870. go
  21871.  
  21872. create procedure sp_MShelpcreatebeforetable
  21873.     @objid int,
  21874.     @newname sysname
  21875. AS
  21876.     declare @command nvarchar(1000)
  21877.     declare @retcode int
  21878.     declare @include int
  21879.     declare @tablenick int
  21880.     declare @colpat nvarchar(130)
  21881.     declare @colname sysname
  21882.     declare @typename sysname
  21883.     declare @colid smallint
  21884.     declare @colidstr nvarchar(3)
  21885.     declare @status tinyint
  21886.     declare @len smallint
  21887.     declare @prec smallint
  21888.     declare @scale int
  21889.     declare @isnullable tinyint
  21890.  
  21891.     set nocount on
  21892.  
  21893.     select @tablenick = max(nickname) from sysmergearticles where objid = @objid
  21894.     if @tablenick is null return (1)
  21895.     
  21896.     -- create temp table to select the command text out of
  21897.     create table #tempcmd (phase int NOT NULL, step int identity NOT NULL, cmdtext nvarchar(4000) NULL)
  21898.  
  21899.     set @command = 'create table ' + @newname + '('
  21900.     insert into #tempcmd (phase, cmdtext) values (1, @command)
  21901.     
  21902.     -- Loop over the columns and see which ones we include
  21903.     declare col_cursor CURSOR LOCAL FAST_FORWARD for select name, status, type_name(xtype), length,
  21904.          prec, scale, isnullable, colid from syscolumns
  21905.     where id = @objid and iscomputed <> 1 and type_name(xtype) <> 'timestamp' order by colid
  21906.     FOR READ ONLY
  21907.     
  21908.     open col_cursor
  21909.     fetch next from col_cursor into @colname, @status, @typename, @len, @prec, @scale, @isnullable, @colid
  21910.     while (@@fetch_status <> -1)
  21911.         begin
  21912.         set @include = 0
  21913.         set @colpat = '%' + @colname + '%'
  21914.         if columnproperty( @objid, @colname , 'isrowguidcol')=1
  21915.             begin
  21916.             set @include = 1
  21917.             end
  21918.         else
  21919.             begin
  21920.             -- does updating this column change membership in a partial replica? 
  21921.             if exists (select * from sysmergearticles 
  21922.                 where objid = @objid and subset_filterclause like @colpat)
  21923.                 set @include = 1
  21924.             else if exists (select * from sysmergesubsetfilters
  21925.                 where art_nickname = @tablenick and join_filterclause like @colpat)
  21926.                 set @include = 1
  21927.             else if exists (select * from sysmergesubsetfilters
  21928.                  where join_nickname = @tablenick and join_filterclause like @colpat)
  21929.                 set @include = 1
  21930.             end
  21931.         -- If we want this column, map its type and insert a row to temp table
  21932.         if @include = 1
  21933.             begin
  21934.             if @typename='nvarchar' or @typename='nchar' -- a unit of nchar takes 2 bytes
  21935.                 set @len = @len/2
  21936.             exec @retcode = dbo.sp_MSmaptype @typename out, @len, @prec, @scale
  21937.             if @@ERROR<>0 or @retcode<>0 return (1)
  21938.             set @colname = QUOTENAME(@colname)
  21939.             if @isnullable = 1
  21940.                 set @command = @colname + ' ' + @typename + ' NULL, '
  21941.             else
  21942.                 set @command = @colname + ' ' + @typename + ' NOT NULL, '
  21943.                 
  21944.             -- Insert the part of create table command for this column
  21945.             insert into #tempcmd (phase, cmdtext) values (1, @command)
  21946.  
  21947.             -- Insert a create index command
  21948.             set @colidstr =convert(nvarchar(3), @colid)
  21949.             set @command = 'create index ' + @newname + '_' + @colidstr + ' on ' + @newname +
  21950.                 ' (' + @colname + ')
  21951.                     '
  21952.             insert into #tempcmd (phase, cmdtext) values (2, @command)
  21953.             
  21954.             end
  21955.         /* Repeat the loop with next column */
  21956.         fetch next from col_cursor into @colname, @status, @typename, @len, @prec, @scale, @isnullable, @colid
  21957.         end
  21958.     close col_cursor
  21959.     deallocate col_cursor
  21960.  
  21961.     -- Insert last column, generation
  21962.     set @command = 'generation int NOT NULL)
  21963.         '
  21964.     insert into #tempcmd (phase, cmdtext) values (1, @command)
  21965.     set @command = 'create index ' + @newname + '_gen on ' + @newname + '(generation) 
  21966.         '
  21967.     insert into #tempcmd (phase, cmdtext) values (2, @command)
  21968.         
  21969.     select cmdtext from #tempcmd order by phase, step
  21970. go
  21971.  
  21972. --------------------------------------------------------------------------------
  21973. --. sp_MShelpalterbeforetable
  21974. --------------------------------------------------------------------------------
  21975. if exists (select * from sysobjects    where type = 'P'
  21976.     and name = 'sp_MShelpalterbeforetable')
  21977.     drop procedure sp_MShelpalterbeforetable
  21978. go
  21979.  
  21980. raiserror('Creating procedure sp_MShelpalterbeforetable', 0,1)
  21981. go
  21982.  
  21983. create procedure sp_MShelpalterbeforetable
  21984.     @objid int,
  21985.     @biname sysname
  21986. AS
  21987.     declare @command nvarchar(1000)
  21988.     declare @retcode int
  21989.     declare @include int
  21990.     declare @tablenick int
  21991.     declare @colpat nvarchar(130)
  21992.     declare @colname sysname
  21993.     declare @typename sysname
  21994.     declare @colid smallint
  21995.     declare @colidstr nvarchar(3)
  21996.     declare @status tinyint
  21997.     declare @len smallint
  21998.     declare @prec smallint
  21999.     declare @scale int
  22000.     declare @isnullable tinyint
  22001.     declare @bi_objid int
  22002.     set nocount on
  22003.  
  22004.     select @tablenick = max(nickname) from sysmergearticles where objid = @objid
  22005.     if @tablenick is null 
  22006.         return (1)
  22007.  
  22008.     select @bi_objid = OBJECT_ID(@biname)        
  22009.     
  22010.     -- Loop over the columns and see which ones we include
  22011.     declare col_cursor CURSOR LOCAL FAST_FORWARD for select name, status, type_name(xtype), length,
  22012.          prec, scale, isnullable, colid from syscolumns
  22013.     where id = @objid and iscomputed <> 1 and type_name(xtype) <> 'timestamp' order by colid
  22014.     FOR READ ONLY
  22015.     
  22016.     open col_cursor
  22017.     fetch next from col_cursor into @colname, @status, @typename, @len, @prec, @scale, @isnullable, @colid
  22018.     while (@@fetch_status <> -1)
  22019.         begin
  22020.         set @include = 0
  22021.         set @colpat = '%' + @colname + '%'
  22022.  
  22023.         -- Is this column already in the before image table?
  22024.         if exists (select * from syscolumns where id = @bi_objid and name = @colname)
  22025.             begin
  22026.             goto fetchnext
  22027.             end
  22028.  
  22029.         -- does updating this column change membership in a partial replica? 
  22030.         if exists (select * from sysmergearticles 
  22031.             where objid = @objid and subset_filterclause like @colpat)
  22032.             set @include = 1
  22033.         else if exists (select * from sysmergesubsetfilters
  22034.             where art_nickname = @tablenick and join_filterclause like @colpat)
  22035.             set @include = 1
  22036.         else if exists (select * from sysmergesubsetfilters
  22037.             where join_nickname = @tablenick and join_filterclause like @colpat)
  22038.             set @include = 1
  22039.  
  22040.         -- If we want this column, map its type and insert a row to temp table
  22041.         if @include <> 1
  22042.             begin
  22043.             goto fetchnext
  22044.             end
  22045.         if @typename='nvarchar' or @typename='nchar' -- a unit of nchar takes 2 bytes
  22046.             set @len = @len/2
  22047.         exec @retcode = dbo.sp_MSmaptype @typename out, @len, @prec, @scale
  22048.         if @@ERROR<>0 or @retcode<>0 goto errlabel
  22049.         set @colname = QUOTENAME(@colname)
  22050.  
  22051.         -- Always make columns nullable when we add them because we might have
  22052.         -- existing rows in the before image table.
  22053.         set @command = 'alter table ' + @biname + ' ADD ' + @colname + ' ' + @typename + ' NULL '
  22054.         exec (@command)
  22055.         if @@error <> 0 goto errlabel
  22056.         
  22057.         -- Create an index
  22058.         set @colidstr =convert(nvarchar(3), @colid)
  22059.         set @command = 'create index ' + @biname + '_' + @colidstr + ' on ' + @biname +
  22060.             ' (' + @colname + ')'
  22061.         exec (@command)
  22062.         if @@error <> 0 goto errlabel
  22063.             
  22064. fetchnext:
  22065.         /* Repeat the loop with next column */
  22066.         fetch next from col_cursor into @colname, @status, @typename, @len, @prec, @scale, @isnullable, @colid
  22067.         end
  22068.     close col_cursor
  22069.     deallocate col_cursor
  22070.     return 0
  22071. errlabel:
  22072.     close col_cursor
  22073.     deallocate col_cursor
  22074.     return 1
  22075.  
  22076. go
  22077.  
  22078. --------------------------------------------------------------------------------
  22079. --. sp_MSgetbeforetableinsert
  22080. --------------------------------------------------------------------------------
  22081. if exists (select * from sysobjects    where type = 'P'
  22082.     and name = 'sp_MSgetbeforetableinsert')
  22083.     drop procedure sp_MSgetbeforetableinsert
  22084. go
  22085.  
  22086. raiserror('Creating procedure sp_MSgetbeforetableinsert', 0,1)
  22087. go
  22088.  
  22089. create procedure sp_MSgetbeforetableinsert
  22090.     @objid int,
  22091.     @inscommand nvarchar(2000) output
  22092. AS
  22093.     declare @before_objid int
  22094.     declare @before_name sysname
  22095.     declare @collist nvarchar(1000)
  22096.     declare @colname sysname
  22097.  
  22098.     -- Do we have a before table?
  22099.     select @before_objid = max(before_image_objid) from  sysmergearticles where objid = @objid and
  22100.             before_image_objid is not null
  22101.     select @before_name = OBJECT_NAME(@before_objid)
  22102.  
  22103.     if @before_name is null
  22104.         begin
  22105.         set @inscommand = ''
  22106.         return 0
  22107.         end
  22108.  
  22109.     set @collist = ''
  22110.     -- Loop over columns to make the column list for the insert / select command
  22111.     declare col_cursor CURSOR LOCAL FAST_FORWARD for select name from syscolumns
  22112.     where id = @before_objid and name <> 'generation' order by colid
  22113.     FOR READ ONLY
  22114.  
  22115.     open col_cursor
  22116.  
  22117.     fetch next from col_cursor into @colname
  22118.     while (@@fetch_status <> -1)
  22119.         begin
  22120.         set @collist = @collist + QUOTENAME(@colname) + ', '
  22121.         fetch next from col_cursor into @colname
  22122.         end
  22123.     close col_cursor
  22124.     deallocate col_cursor
  22125.  
  22126.     -- Our list has all of the columns except generation since that gets set to a local variable
  22127.     -- Make the insert command
  22128.     set @inscommand = 'insert into ' + QUOTENAME(@before_name) + ' ( ' + @collist +
  22129.         ' generation) select ' + @collist + ' @newgen from deleted'
  22130.  
  22131.     return 0
  22132.     
  22133. go
  22134. --------------------------------------------------------------------------------
  22135. --. sp_MSfixlineagemismatch
  22136. --------------------------------------------------------------------------------
  22137. if exists (select * from sysobjects
  22138.         where type = 'P'
  22139.             and name = 'sp_MSfixlineagemismatch')
  22140.     drop procedure sp_MSfixlineagemismatch
  22141.  
  22142. raiserror('Creating procedure sp_MSfixlineagemismatch', 0,1)
  22143. go
  22144.  
  22145. create procedure sp_MSfixlineagemismatch 
  22146. as
  22147.     if exists (select * from sysobjects where type = 'U' and name = 'MSmerge_contents')
  22148.         begin
  22149.         update MSmerge_contents set lineage = substring(lineage, 1, 4) + substring(lineage, 13, 4) + substring(lineage, 9, 240)
  22150.             where substring(lineage, 13, 1) > substring(lineage, 5, 1) and substring(lineage, 14, 3) = substring(lineage, 6, 3) or
  22151.             substring(lineage, 14, 1) > substring(lineage, 6, 1) and substring(lineage, 15, 2) = substring(lineage, 7, 2) or
  22152.             substring(lineage, 15, 1) > substring(lineage, 7, 1) and substring(lineage, 16, 1) = substring(lineage, 8, 1) or
  22153.             substring(lineage, 16, 1) > substring(lineage, 8, 1)
  22154.         end
  22155.         
  22156. go
  22157. exec dbo.sp_MS_marksystemobject sp_MSfixlineagemismatch 
  22158. go
  22159. grant exec on dbo.sp_MSfixlineagemismatch to public
  22160. go
  22161.  
  22162.  
  22163. --------------------------------------------------------------------------------
  22164. --. sp_MSinsertgenerationschemachanges
  22165. --------------------------------------------------------------------------------
  22166. if exists (select * from sysobjects
  22167.         where type = 'P'
  22168.             and name = 'sp_MSinsertgenerationschemachanges')
  22169.     drop procedure sp_MSinsertgenerationschemachanges
  22170. go
  22171.  
  22172. create procedure sp_MSinsertgenerationschemachanges
  22173.     @publication sysname
  22174. AS
  22175.     declare @mingen         int
  22176.     declare @lastrecgen        int
  22177.     declare @lastrecguid    uniqueidentifier
  22178.     declare @lastsentgen        int
  22179.     declare @lastsentguid    uniqueidentifier
  22180.     declare @db_name        sysname
  22181.     declare @repid             uniqueidentifier
  22182.     declare @pubid             uniqueidentifier
  22183.     declare @schemaversion  int 
  22184.     declare @schemaguid     uniqueidentifier
  22185.     declare @schematype     int
  22186.     declare @schematext     nvarchar(2000)
  22187.     declare @artid            uniqueidentifier
  22188.     declare @retcode        int
  22189.     set nocount on
  22190.  
  22191.     set @lastrecgen = NULL
  22192.     set @lastsentgen = NULL
  22193.     
  22194.     begin tran
  22195.     save TRAN MSinsertgenerationschemachanges    
  22196.  
  22197.     set @db_name = db_name()
  22198.     select @pubid = pubid from sysmergepublications where name = @publication and publisher = @@SERVERNAME and publisher_db = @db_name
  22199.     if @pubid IS NULL
  22200.         BEGIN
  22201.             RAISERROR (20026, 16, -1, @publication)
  22202.             RETURN (1)
  22203.         END
  22204.     
  22205.     SELECT @repid = subid FROM sysmergesubscriptions where pubid = @pubid and subid = @pubid
  22206.     if @repid is NULL
  22207.         begin
  22208.             RAISERROR(20021, 16, -1)
  22209.             return (1)
  22210.         end
  22211.  
  22212.     select @mingen = min(generation) from MSmerge_genhistory where guidlocal = '00000000-0000-0000-0000-000000000000'
  22213.     if @mingen IS NOT NULL
  22214.         select @lastrecgen = max(generation) from MSmerge_genhistory where generation < @mingen
  22215.     if @lastrecgen IS NOT NULL
  22216.         begin
  22217.             select @lastrecguid = guidsrc from MSmerge_genhistory where generation = @lastrecgen
  22218.  
  22219.             set @artid = NULL
  22220.             set @schematype = 5 /* last rec gen schema type */
  22221.             select @schematext = 'exec dbo.sp_MSsetlastrecgen ' + '''' + convert(nchar(36), @repid) + ''''  + ',' + '''' + convert(nvarchar(10), @lastrecgen) + '''' + ',' + '''' + convert(nchar(36), @lastrecguid) + ''''
  22222.  
  22223.             if exists (select *    from sysmergeschemachange
  22224.                     where pubid = @pubid 
  22225.                     AND schematype = @schematype)
  22226.                 begin
  22227.                     /* Select the existing schema guid */
  22228.                     select @schemaversion = schemaversion, @schemaguid = schemaguid from sysmergeschemachange
  22229.                         where pubid = @pubid 
  22230.                         AND schematype = @schematype
  22231.                     /*
  22232.                     ** Update the schema change version
  22233.                     */
  22234.                     exec @retcode = dbo.sp_MSupdateschemachange @pubid, @artid, @schemaversion, 
  22235.                         @schemaguid, @schematype, @schematext
  22236.                     if @@error <> 0    or @retcode <> 0
  22237.                         goto FAILURE
  22238.                 end
  22239.             else        
  22240.                 begin
  22241.                     /* Insert the schema change */
  22242.                     select @schemaversion = schemaversion from sysmergeschemachange
  22243.                     if (@schemaversion is NULL)
  22244.                         set @schemaversion = 1
  22245.                     else
  22246.                         select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange
  22247.                         
  22248.                     /* generate a new schema guid */
  22249.                     set @schemaguid = newid()
  22250.                     exec @retcode = dbo.sp_MSinsertschemachange @pubid, @artid, @schemaversion, 
  22251.                         @schemaguid, @schematype, @schematext
  22252.                     if @@error <> 0    or @retcode <> 0
  22253.                         goto FAILURE
  22254.                 end                
  22255.  
  22256.         end        
  22257.  
  22258.     select @lastsentgen = max(generation) from MSmerge_genhistory
  22259.         where guidlocal <> '00000000-0000-0000-0000-000000000000' and (art_nick = 0 or art_nick is NULL or
  22260.             art_nick in (select nickname from sysmergearticles where pubid = @pubid))
  22261.  
  22262.     if @lastsentgen IS NOT NULL
  22263.         begin
  22264.             select @lastsentguid = guidsrc from MSmerge_genhistory where generation = @lastsentgen
  22265.             set @artid = NULL
  22266.             set @schematype = 6 /* last sent gen schema type */
  22267.             select @schematext = 'exec dbo.sp_MSsetlastsentgen ' + '''' + convert(nchar(36), @repid) + ''''  + ',' + '''' + convert(nvarchar(10), @lastsentgen) + '''' + ',' + '''' + convert(nchar(36), @lastsentguid) + ''''
  22268.  
  22269.             if exists (select *    from sysmergeschemachange
  22270.                     where pubid = @pubid 
  22271.                     AND schematype = @schematype)
  22272.                 begin
  22273.                     /* Select the existing schema guid */
  22274.                     select @schemaversion = schemaversion, @schemaguid = schemaguid from sysmergeschemachange
  22275.                         where pubid = @pubid 
  22276.                         AND schematype = @schematype
  22277.                     /*
  22278.                     ** Update the schema change version
  22279.                     */
  22280.                     exec @retcode = dbo.sp_MSupdateschemachange @pubid, @artid, @schemaversion, 
  22281.                         @schemaguid, @schematype, @schematext
  22282.                     if @@error <> 0    or @retcode <> 0
  22283.                         goto FAILURE
  22284.                 end
  22285.             else        
  22286.                 begin
  22287.                     /* Insert the schema change */
  22288.                     select @schemaversion = schemaversion from sysmergeschemachange
  22289.                     if (@schemaversion is NULL)
  22290.                         set @schemaversion = 1
  22291.                     else
  22292.                         select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange
  22293.                         
  22294.                     /* generate a new schema guid */
  22295.                     set @schemaguid = newid()
  22296.                     exec @retcode = dbo.sp_MSinsertschemachange @pubid, @artid, @schemaversion, 
  22297.                         @schemaguid, @schematype, @schematext
  22298.                     if @@error <> 0    or @retcode <> 0
  22299.                         goto FAILURE
  22300.                 end                
  22301.                 
  22302.         end
  22303.     COMMIT TRAN            
  22304.     RETURN 0
  22305.  
  22306. FAILURE:
  22307.     /* UNDONE : This code is specific to 6.X nested transaction semantics */
  22308.     if @@TRANCOUNT > 0
  22309.     begin
  22310.         ROLLBACK TRANSACTION MSinsertgenerationschemachanges
  22311.         COMMIT TRANSACTION
  22312.     end
  22313.     
  22314.     RETURN 1
  22315. go
  22316.        
  22317. exec dbo.sp_MS_marksystemobject sp_MSinsertgenerationschemachanges
  22318. go
  22319.  
  22320. grant exec on dbo.sp_MSinsertgenerationschemachanges to public
  22321. go
  22322.  
  22323.        
  22324.  
  22325. --------------------------------------------------------------------------------
  22326. -- END OF FILE: Turn off marking of system objects.
  22327. --    DO NOT ADD ANYTHING AFTER THIS POINT
  22328. --------------------------------------------------------------------------------
  22329. exec sp_MS_upd_sysobj_category 2
  22330. go
  22331.  
  22332. exec sp_configure 'allow updates',0
  22333. go
  22334.  
  22335. reconfigure with override
  22336. go
  22337.  
  22338.  
  22339.