home *** CD-ROM | disk | FTP | other *** search
/ Enter 2001 April / EnterCD4.iso / Update / SQL Server SP3 / sql70sp3i.exe / INSTALL / repltran.sql < prev    next >
Encoding:
Text File  |  1999-12-01  |  417.5 KB  |  13,661 lines

  1. /*
  2. ** repltran.sql            1997/02/12 22:03
  3. **
  4. **
  5. ** Copyright Microsoft, Inc. 1998, 1999
  6. ** All Rights Reserved.
  7. ** Use, duplication, or disclosure by the United States Government
  8. ** is subject to restrictions as set forth in subdivision (c) (1) (ii)
  9. ** of the Rights in Technical Data and Computer Software clause
  10. ** at CFR 252.227-7013. Microsoft, Inc. One Microsoft Way, Redmond WA
  11. ** 98052.  SQL-Server 7.0.
  12. */
  13.  
  14. use master
  15. go
  16.  
  17. dump tran master with no_log
  18. go
  19.  
  20. exec dbo.sp_configure 'update',1
  21. go
  22. reconfigure with override
  23. go
  24.  
  25. set ANSI_NULLS off
  26. go
  27.  
  28. -- sp_MS_upd_sysobj_category is obsolete, use sp_MS_marksystemobject instead
  29. -- exec dbo.sp_MS_upd_sysobj_category 1 --Capture time for use at the end
  30. -- go
  31.  
  32. /* 
  33. ** Drop the stored procedures in this script using the old dropping SP 
  34. ** and then drop itself
  35. */
  36. if exists (select * from sysobjects
  37.     where type = 'P '
  38.             and name = 'sp_MSdrop_repltran')
  39. begin
  40.     exec dbo.sp_MSdrop_repltran
  41.     drop procedure sp_MSdrop_repltran
  42. end
  43.  
  44. /*
  45. ** Create stored procedures to drop the stored procedures
  46. ** created by this script
  47. */
  48.  
  49.  
  50. print ''
  51. print 'Creating procedure sp_MSdrop_repl_tran.'
  52. go
  53. create procedure sp_MSdrop_repltran
  54. as
  55.  
  56.     if exists( select * from sysobjects 
  57.         where type = 'P '
  58.             and name = 'sp_MSsetfilterparent' )
  59.         drop procedure sp_MSsetfilterparent
  60.  
  61.     if exists( select * from sysobjects 
  62.         where type = 'P '
  63.             and name = 'sp_MSdoesfilterhaveparent' )
  64.         drop procedure sp_MSdoesfilterhaveparent
  65.  
  66.     if exists( select * from sysobjects 
  67.         where type = 'P '
  68.             and name = 'sp_MSsetfilteredstatus' )
  69.         drop procedure sp_MSsetfilteredstatus
  70.  
  71.     if exists ( select * from sysobjects 
  72.         where type = 'P '
  73.             and name = 'sp_MSreplsup_table_has_pk' )
  74.         DROP PROC sp_MSreplsup_table_has_pk
  75.  
  76.     if exists (select * from sysobjects
  77.         where type = 'P '
  78.                 and name = 'sp_MScreate_pub_tables')
  79.         drop procedure sp_MScreate_pub_tables
  80.  
  81.     if exists (select * from sysobjects
  82.         where type = 'P '
  83.                 and name = 'sp_MSdrop_expired_subscription')
  84.         drop procedure sp_MSdrop_expired_subscription
  85.     
  86.     if exists (select * from sysobjects
  87.             where type = 'P '
  88.                 and name = 'sp_replsync')
  89.         drop procedure sp_replsync
  90.  
  91.     if exists (select * from sysobjects
  92.             where type = 'P '
  93.                 and name = 'sp_enumfullsubscribers')
  94.         drop procedure sp_enumfullsubscribers
  95.     
  96.     if exists (select * from sysobjects
  97.         where type = 'P '
  98.                 and name = 'sp_MSaddexecarticle')
  99.         drop procedure sp_MSaddexecarticle
  100.     
  101.  
  102.     if exists (select * from sysobjects
  103.         where type = 'P '
  104.                 and name = 'sp_MSscript_validate_subscription')
  105.         drop procedure sp_MSscript_validate_subscription 
  106.  
  107.     if exists (select * from sysobjects
  108.         where type = 'P '
  109.                 and name = 'sp_MSvalidate_subscription')
  110.         drop procedure sp_MSvalidate_subscription 
  111.  
  112.     dump tran master with no_log
  113.     
  114.  
  115.     if exists (select * from sysobjects
  116.             where type = 'P '
  117.                 and name = 'sp_addarticle')
  118.         drop procedure sp_addarticle
  119.     
  120.  
  121.     if exists (select * from sysobjects
  122.         where type = 'P '
  123.                 and name = 'sp_articlecolumn')
  124.         drop procedure sp_articlecolumn
  125.     
  126.  
  127.     dump tran master with no_log
  128.     
  129.  
  130.     if exists (select * from sysobjects
  131.             where type = 'P '
  132.                 and name = 'sp_articlefilter')
  133.         drop procedure sp_articlefilter
  134.        
  135.  
  136.  
  137.     if exists (select * from sysobjects
  138.         where type = 'P '
  139.                 and name = 'sp_MSarticletextcol')
  140.         drop procedure sp_MSarticletextcol
  141.     
  142.  
  143.     dump tran master with no_log
  144.     
  145.  
  146.     if exists (select * from sysobjects
  147.         where type = 'P '
  148.                 and name = 'sp_MStextcolstatus')
  149.         drop procedure sp_MStextcolstatus
  150.     
  151.  
  152.     if exists (select * from sysobjects
  153.             where type = 'P '
  154.                 and name = 'sp_articleview')
  155.         drop procedure sp_articleview
  156.     
  157.  
  158.     dump tran master with no_log
  159.     
  160.  
  161.     if exists (select * from sysobjects
  162.             where type = 'P '
  163.                 and name = 'sp_addpublication')
  164.         drop procedure sp_addpublication
  165.     
  166.  
  167.     dump tran master with no_log
  168.     
  169.  
  170.     if exists (select * from sysobjects
  171.             where type = 'P '
  172.                 and name = 'sp_addsubscription')
  173.         drop procedure sp_addsubscription
  174.     
  175.  
  176.     IF EXISTS (SELECT * FROM sysobjects
  177.             WHERE type = 'P '
  178.                 AND name = 'sp_changearticle')
  179.         DROP PROCEDURE sp_changearticle
  180.     
  181.  
  182.     dump tran master with no_log
  183.     
  184.  
  185.     IF EXISTS (SELECT * FROM sysobjects
  186.             WHERE type = 'P '
  187.                 AND name = 'sp_changepublication')
  188.         DROP PROCEDURE sp_changepublication
  189.     
  190.  
  191.  
  192.     IF EXISTS (SELECT * FROM sysobjects
  193.             WHERE type = 'P '
  194.                 AND name = 'sp_changesubscription')
  195.         DROP PROCEDURE sp_changesubscription
  196.     
  197.  
  198.     dump tran master with no_log
  199.     
  200.  
  201.     if exists (select * from sysobjects
  202.             where type = 'P '
  203.                 and name = 'sp_MShcchangesubstatus1')
  204.         drop procedure sp_MShcchangesubstatus1
  205.     
  206.  
  207.     if exists (select * from sysobjects
  208.             where type = 'P '
  209.                 and name = 'sp_MShcchangesubstatus2')
  210.         drop procedure sp_MShcchangesubstatus2
  211.     
  212.  
  213.     if exists (select * from sysobjects
  214.             where type = 'P '
  215.                 and name = 'sp_MShcchangesubstatus3')
  216.         drop procedure sp_MShcchangesubstatus3
  217.     
  218.  
  219.     dump tran master with no_log
  220.     
  221.  
  222.     if exists (select * from sysobjects
  223.             where type = 'P '
  224.                 and name = 'sp_changesubstatus')
  225.         drop procedure sp_changesubstatus
  226.     
  227.  
  228.     if exists (select * from sysobjects
  229.             where type = 'P '
  230.                 and name = 'sp_droparticle')
  231.         drop procedure sp_droparticle
  232.     
  233.  
  234.     dump tran master with no_log
  235.     
  236.  
  237.     if exists (select * from sysobjects
  238.             where type = 'P '
  239.                 and name = 'sp_droppublication')
  240.         drop procedure sp_droppublication
  241.     
  242.  
  243.     if exists (select * from sysobjects
  244.             where type = 'P '
  245.                 and name = 'sp_dropsubscription')
  246.         drop procedure sp_dropsubscription
  247.     
  248.  
  249.     dump tran master with no_log
  250.     
  251.  
  252.     if exists (select * from sysobjects
  253.             where type = 'P '
  254.                 and name = 'sp_helparticle')
  255.         drop procedure sp_helparticle
  256.     
  257.  
  258.     dump tran master with no_log
  259.     
  260.  
  261.     if exists (select * from sysobjects
  262.             where type = 'P '
  263.                 and name = 'sp_helparticlecolumns')
  264.         drop procedure sp_helparticlecolumns
  265.     
  266.  
  267.     if exists (select * from sysobjects
  268.             where type = 'P '
  269.                 and name = 'sp_helppublication')
  270.         drop procedure sp_helppublication
  271.     
  272.         
  273.     if exists (select * from sysobjects
  274.             where type = 'P '
  275.                 and name = 'sp_MSaddpub_snapshot')
  276.         drop procedure sp_MSaddpub_snapshot
  277.  
  278.     dump tran master with no_log
  279.     
  280.  
  281.     if exists (select * from sysobjects
  282.             where type = 'P '
  283.                 and name = 'sp_helpsubscription')
  284.         drop procedure sp_helpsubscription
  285.     
  286.  
  287.     if exists (select * from sysobjects
  288.             where type = 'P '
  289.                 and name = 'sp_subscribe')
  290.         drop procedure sp_subscribe
  291.     
  292.  
  293.     if exists (select * from sysobjects
  294.             where type = 'P '
  295.                 and name = 'sp_unsubscribe')
  296.         drop procedure sp_unsubscribe
  297.     
  298.  
  299.     if exists (select * from sysobjects
  300.             where type = 'P '
  301.                 and name = 'sp_refreshsubscriptions')
  302.         drop procedure sp_refreshsubscriptions
  303.     
  304.  
  305.     dump tran master with no_log
  306.     
  307.  
  308.     if exists (select * from sysobjects
  309.             where type = 'P '
  310.                 and name = 'sp_MSpublishdb')
  311.         drop procedure sp_MSpublishdb
  312.     
  313.  
  314.     if exists (select * from sysobjects
  315.             where type = 'P '
  316.                 and name = 'sp_MSactivate_auto_sub')
  317.         drop procedure sp_MSactivate_auto_sub
  318.     
  319.  
  320.     if exists (select * from sysobjects
  321.             where type = 'P '
  322.                 and name = 'sp_MSget_synctran_commands')
  323.         drop procedure sp_MSget_synctran_commands
  324.  
  325.  
  326.     if exists (select * from sysobjects
  327.         where type = 'P '
  328.                 and name = 'sp_MSdrop_pub_tables')
  329.     begin
  330.         -- Don't drop the system tables here. repltran.sql should not
  331.         -- delete any data in the master database (see bug 34219).
  332.         -- exec dbo.sp_MSdrop_pub_tables
  333.         drop procedure sp_MSdrop_pub_tables
  334.     end
  335.  
  336.     -- SyncTran
  337.     if exists (select * from sysobjects
  338.         where type = 'P '
  339.                 and name = 'sp_MSis_col_replicated')
  340.         drop procedure  sp_MSis_col_replicated
  341.  
  342.     if exists (select * from sysobjects
  343.         where type = 'P '
  344.                 and name = 'sp_MSis_pk_col')
  345.         drop procedure  sp_MSis_pk_col
  346.  
  347.    if exists (select * from sysobjects
  348.         where type = 'P '
  349.                 and name = 'sp_MSscript_insert_statement')
  350.         drop procedure sp_MSscript_insert_statement 
  351.  
  352.    if exists (select * from sysobjects
  353.         where type = 'P '
  354.                 and name = 'sp_MSscript_update_statement')
  355.         drop procedure sp_MSscript_update_statement
  356.  
  357.    if exists (select * from sysobjects
  358.         where type = 'P '
  359.                 and name = 'sp_MSscript_delete_statement')
  360.         drop procedure sp_MSscript_delete_statement
  361.  
  362.    if exists (select * from sysobjects
  363.         where type = 'P '
  364.                 and name = 'sp_MSscript_beginproc')
  365.         drop procedure sp_MSscript_beginproc
  366.  
  367.    if exists (select * from sysobjects
  368.         where type = 'P '
  369.                 and name = 'sp_MSscript_security')
  370.         drop procedure sp_MSscript_security
  371.  
  372.    if exists (select * from sysobjects
  373.         where type = 'P '
  374.                 and name = 'sp_MSscript_endproc')
  375.         drop procedure sp_MSscript_endproc
  376.  
  377.   if exists (select * from sysobjects
  378.         where type = 'P '
  379.                 and name = 'sp_MStable_not_modifiable')
  380.         drop procedure sp_MStable_not_modifiable
  381.  
  382.    if exists (select * from sysobjects
  383.         where type = 'P '
  384.                 and name = 'sp_MSscript_sync_ins_proc')
  385.         drop procedure sp_MSscript_sync_ins_proc
  386.  
  387.    if exists (select * from sysobjects
  388.         where type = 'P '
  389.                 and name = 'sp_MSscript_sync_upd_proc')
  390.         drop procedure sp_MSscript_sync_upd_proc 
  391.  
  392.    if exists (select * from sysobjects
  393.         where type = 'P '
  394.                 and name = 'sp_MSscript_sync_del_proc')
  395.         drop procedure sp_MSscript_sync_del_proc
  396.  
  397.    if exists (select * from sysobjects
  398.         where type = 'P '
  399.                 and name = 'sp_MSgen_sync_tran_procs')
  400.         drop procedure sp_MSgen_sync_tran_procs 
  401.  
  402.     if exists (select * from sysobjects
  403.         where type = 'P '
  404.                 and name = 'sp_MSmark_proc_norepl')
  405.         drop procedure sp_MSmark_proc_norepl 
  406.  
  407.     if exists (select * from sysobjects
  408.         where type = 'P '
  409.                 and name = 'sp_articlesynctranprocs')
  410.         drop procedure sp_articlesynctranprocs
  411.  
  412.     if exists (select * from sysobjects
  413.         where type = 'P '
  414.                 and name = 'sp_reinitsubscription')
  415.         drop procedure sp_reinitsubscription
  416.  
  417.     dump tran master with no_log
  418.  
  419.     if exists( select * from sysobjects 
  420.         where type = 'P ' and name = N'sp_getarticlepkcolbitmap')
  421.     begin
  422.         drop procedure sp_getarticlepkcolbitmap
  423.     end
  424.  
  425.     if exists( select * from sysobjects 
  426.         where type = 'P ' and name = N'sp_gettypestring' )
  427.     begin
  428.         drop procedure sp_gettypestring
  429.     end
  430.  
  431.     if exists( select * from sysobjects 
  432.         where type = 'P ' and name = N'sp_isarticlecolbitset' )
  433.     begin
  434.         drop procedure sp_isarticlecolbitset
  435.     end
  436.  
  437.     if exists( select * from sysobjects 
  438.         where type = 'P ' and name = N'sp_scriptpkwhereclause' )
  439.     begin
  440.         drop procedure sp_scriptpkwhereclause
  441.     end
  442.  
  443.     if exists( select * from sysobjects 
  444.         where type = 'P ' and name = N'sp_scriptupdateparams' )
  445.     begin
  446.         drop procedure sp_scriptupdateparams
  447.     end
  448.  
  449.     if exists( select * from sysobjects 
  450.         where type = 'P ' and name = N'sp_scriptinsproc' )
  451.     begin
  452.         drop procedure sp_scriptinsproc
  453.     end
  454.  
  455.     if exists( select * from sysobjects 
  456.         where type = 'P ' and name = N'sp_scriptdelproc' )
  457.     begin
  458.         drop procedure sp_scriptdelproc
  459.     end
  460.  
  461.     if exists( select * from sysobjects 
  462.         where type = 'P ' and name = N'sp_scriptupdproc' )
  463.     begin
  464.         drop procedure sp_scriptupdproc
  465.     end
  466.  
  467.     if exists ( select * from sysobjects 
  468.         where type = 'P ' and name = 'sp_scriptmappedupdproc' )
  469.     begin
  470.         drop procedure sp_scriptmappedupdproc
  471.     end
  472.  
  473.     if exists ( select * from sysobjects 
  474.         where type = 'P ' and name = 'sp_fetchshowcmdsinput' )
  475.     begin
  476.         drop procedure sp_fetchshowcmdsinput
  477.     end
  478.  
  479.     if exists ( select * from sysobjects 
  480.         where type = 'P ' and name = 'sp_replshowcmds' )
  481.     begin
  482.         drop procedure sp_replshowcmds
  483.     end
  484.  
  485.     if exists ( select * from sysobjects 
  486.         where type = 'P ' and name = 'sp_publication_validation' )
  487.     begin
  488.         drop procedure sp_publication_validation
  489.     end
  490.  
  491.     if exists ( select * from sysobjects 
  492.         where type = 'P ' and name = 'sp_article_validation' )
  493.     begin
  494.         drop procedure sp_article_validation
  495.     end
  496.  
  497.     if exists ( select * from sysobjects 
  498.         where type = 'P ' and name = 'sp_MSdrop_6x_replication_agent' )
  499.     begin
  500.         drop procedure sp_MSdrop_6x_replication_agent
  501.     end
  502.  
  503.     if exists ( select * from sysobjects 
  504.         where type = 'P ' and name = 'sp_script_synctran_commands' )
  505.     begin
  506.         drop procedure sp_script_synctran_commands
  507.     end
  508.  
  509.     dump tran master with no_log
  510. go
  511.  
  512. EXEC dbo.sp_MS_marksystemobject sp_MSdrop_repltran
  513. GO
  514.  
  515. EXEC dbo.sp_MSdrop_repltran
  516. GO
  517.  
  518. /* Create and execute dbo.sp_MSdrop_pub_tables */
  519.  
  520. print ''
  521. print 'Creating procedure sp_MSdrop_pub_tables'
  522. go
  523. CREATE PROCEDURE sp_MSdrop_pub_tables
  524. AS
  525.         
  526.     begin tran
  527.     save TRAN sp_drop_central_pub_tables
  528.     
  529.     /* drop 'sysarticles' */
  530.     IF exists (select * from sysobjects where name = 'sysarticles')
  531.     BEGIN
  532.         DROP TABLE sysarticles
  533.         IF @@ERROR <> 0
  534.         BEGIN
  535.             if @@trancount > 0
  536.             begin
  537.                 ROLLBACK TRAN sp_drop_central_pub_tables
  538.                 commit tran
  539.             end
  540.             RETURN(1)
  541.         END
  542.     END
  543.  
  544.     /* drop 'syspublications' */
  545.     IF exists (select * from sysobjects where name = 'syspublications')
  546.     BEGIN
  547.         DROP TABLE syspublications
  548.         IF @@ERROR <> 0
  549.         BEGIN
  550.             if @@trancount > 0
  551.             begin
  552.                 ROLLBACK TRAN sp_drop_central_pub_tables
  553.                 commit tran
  554.             end
  555.             RETURN(1)
  556.         END
  557.     END
  558.  
  559.     /* drop 'syssubscriptions' */
  560.     IF exists (select * from sysobjects where name = 'syssubscriptions')
  561.     BEGIN
  562.         DROP TABLE syssubscriptions
  563.         IF @@ERROR <> 0
  564.         BEGIN
  565.             if @@trancount > 0
  566.             begin
  567.                 ROLLBACK TRAN sp_drop_central_pub_tables
  568.                 commit tran
  569.             end
  570.             RETURN(1)
  571.         END
  572.     END
  573.  
  574.     -- SyncTran
  575.     /* drop 'sysarticleupdates' */
  576.     IF exists (select * from sysobjects where name = 'sysarticleupdates')
  577.     BEGIN
  578.         DROP TABLE sysarticleupdates
  579.         IF @@ERROR <> 0
  580.         BEGIN
  581.             if @@trancount > 0
  582.             begin
  583.                 ROLLBACK TRAN sp_drop_central_pub_tables
  584.                 commit tran
  585.             end
  586.             RETURN(1)
  587.         END
  588.     END
  589.     -- end SyncTran
  590.  
  591.  
  592.     COMMIT TRAN
  593. GO
  594.  
  595. EXEC dbo.sp_MS_marksystemobject sp_MSdrop_pub_tables
  596. GO
  597.  
  598. dump tran master with no_log
  599. go
  600.  
  601. --print ''
  602. --print 'Executing procedure dbo.sp_MSdrop_pub_tables.'
  603. --go
  604. --exec dbo.sp_MSdrop_pub_tables
  605. --go
  606.  
  607. --dump tran master with no_log
  608. --go
  609.  
  610. /* Create and execute dbo.sp_MScreate_pub_tables */
  611.  
  612. dump tran master with no_log
  613. go
  614.  
  615. print ''
  616. print 'Creating procedure sp_MScreate_pub_tables'
  617. go
  618. CREATE PROCEDURE sp_MScreate_pub_tables
  619. AS
  620.     DECLARE @fError int
  621.     SELECT @fError = 0
  622.  
  623.     -- enable 'create tables as pseudo system tables
  624.  
  625.     -- sp_MS_upd_sysobj_category is obsolete, use sp_MS_marksystemobject instead
  626.     -- exec dbo.sp_MS_upd_sysobj_category 1
  627.  
  628.  
  629.     /* 
  630.     ** Msg 226, Level 16, State 9
  631.     ** CREATE TABLE system-table command not allowed within multi-statement transaction.
  632.     */
  633.     /*
  634.     BEGIN TRAN sp_create_central_pub_tables
  635.     */
  636.     
  637.     /* Creating 'sysarticles' */
  638.     IF not exists (select * from sysobjects where name = 'sysarticles')
  639.     BEGIN
  640.         create table dbo.sysarticles
  641.         (
  642.         artid               int                 identity NOT NULL,
  643.         columns             varbinary(32)       NULL,
  644.         creation_script     nvarchar(255)       NULL,
  645.         del_cmd             nvarchar(255)       NULL,
  646.         description         nvarchar(255)       NULL,
  647.         dest_table          sysname             NOT NULL,
  648.         filter              int                 NOT NULL,
  649.         filter_clause       ntext               NULL,
  650.         ins_cmd             nvarchar(255)       NULL,
  651.         name                sysname             NOT NULL,
  652.         objid               int                 NOT NULL,
  653.         pubid               int                 NOT NULL,
  654.         pre_creation_cmd    tinyint             NOT NULL,
  655.         status              tinyint             NOT NULL,
  656.         sync_objid          int                 NOT NULL,
  657.         type                tinyint             NOT NULL,
  658.         upd_cmd             nvarchar(255)       NULL,
  659.         schema_option       binary(8)           NULL,
  660.     dest_owner          sysname             NULL
  661.         )
  662.  
  663.         EXEC dbo.sp_MS_marksystemobject 'sysarticles'
  664.  
  665.         IF @@error<>0
  666.         BEGIN
  667.             GOTO ERROR
  668.         END
  669.  
  670.         create unique nonclustered index unc1sysarticles
  671.             on sysarticles(artid, pubid) 
  672.         
  673.         IF @@error<>0
  674.         BEGIN
  675.             GOTO ERROR
  676.         END
  677.  
  678.     END
  679.  
  680.     /* Creating 'syspublications' */
  681.     IF NOT EXISTS (select * from sysobjects where name = 'syspublications')
  682.     BEGIN
  683.         CREATE TABLE dbo.syspublications (
  684.         description                    nvarchar(255)    NULL,
  685.         name                        sysname     NOT NULL,
  686.         pubid                        int    identity NOT NULL,
  687.         repl_freq                    tinyint         NOT NULL,
  688.         status                        tinyint         NOT NULL,
  689.         sync_method                    tinyint         NOT NULL,
  690.         snapshot_jobid                  binary(16)     NULL,
  691.         independent_agent            bit                NOT NULL,
  692.         immediate_sync                bit                NOT NULL,
  693.         enabled_for_internet        bit                NOT NULL,
  694.         allow_push                    bit                NOT NULL,
  695.         allow_pull                    bit                NOT NULL,
  696.         allow_anonymous                bit                NOT NULL,
  697.         immediate_sync_ready        bit                NOT NULL,
  698.         -- SyncTran
  699.         allow_sync_tran                bit                NOT NULL,
  700.         autogen_sync_procs            bit                NOT NULL,
  701.         retention                   int                 NULL
  702.         )
  703.  
  704.         EXEC dbo.sp_MS_marksystemobject 'syspublications'
  705.  
  706.         IF @@ERROR <> 0
  707.         BEGIN
  708.             GOTO ERROR
  709.         END
  710.  
  711.         create unique nonclustered index unc1syspublications
  712.             on syspublications (pubid) 
  713.         IF @@ERROR <> 0
  714.         BEGIN
  715.             GOTO ERROR
  716.         END
  717.  
  718.         create unique nonclustered index unc2syspublications
  719.             on syspublications (name)
  720.  
  721.         IF @@ERROR <> 0
  722.         BEGIN
  723.             GOTO ERROR
  724.         END
  725.  
  726.     END
  727.  
  728.        /* Creating 'syssubscriptions' */
  729.     IF not exists (select * from sysobjects where name = 'syssubscriptions')
  730.     BEGIN
  731.  
  732.         CREATE TABLE dbo.syssubscriptions
  733.         (
  734.         artid                    int                NOT NULL,
  735.         srvid                    smallint        NOT NULL,
  736.         dest_db                    sysname        NOT NULL,
  737.         status                    tinyint            NOT NULL,
  738.         sync_type                tinyint            NOT NULL,
  739.         login_name                sysname        NOT NULL,
  740.         subscription_type        int                NOT NULL,
  741.         distribution_jobid      binary(16)          NULL,
  742.         timestamp NOT NULL,
  743.         -- SyncTran
  744.         update_mode             tinyint            NOT NULL, -- 0 (read only), 1 (Sync Tran), ...
  745.         loopback_detection      bit NOT NULL
  746.         )
  747.  
  748.         EXEC dbo.sp_MS_marksystemobject 'syssubscriptions'
  749.  
  750.         IF @@ERROR <> 0
  751.         BEGIN
  752.             GOTO ERROR
  753.         END
  754.  
  755.         create unique nonclustered index unc1syssubscriptions
  756.             on syssubscriptions (artid, srvid, dest_db)
  757.  
  758.         IF @@ERROR <> 0
  759.         BEGIN
  760.             GOTO ERROR
  761.         END
  762.  
  763.     END
  764.  
  765.     -- SyncTran
  766.     /* Creating 'sysarticleupdates' */
  767.  
  768.     IF not exists (select * from sysobjects where name = 'sysarticleupdates')
  769.     BEGIN
  770.  
  771.         CREATE TABLE dbo.sysarticleupdates
  772.         (
  773.         artid                  int       NOT NULL,
  774.         pubid                  int       NOT NULL,
  775.         sync_ins_proc          int       NOT NULL,     -- ID of sproc handling Insert Sync Transactions
  776.         sync_upd_proc          int       NOT NULL,     -- ID of sproc handling Update Sync Transactions
  777.         sync_del_proc          int       NOT NULL,
  778.         autogen                bit       NOT NULL)     -- ID of sproc handling Delete Sync Transactions
  779.  
  780.         IF @@ERROR <> 0
  781.         BEGIN
  782.             GOTO ERROR
  783.         END
  784.  
  785.         create unique nonclustered index unc1sysarticleupdates
  786.             on sysarticleupdates (artid, pubid)
  787.  
  788.         IF @@ERROR <> 0
  789.         BEGIN
  790.             GOTO ERROR
  791.         END
  792.  
  793.         -- mark the index as a system object
  794.         exec dbo.sp_MS_marksystemobject 'sysarticleupdates'
  795.  
  796.         IF @@ERROR <> 0
  797.         BEGIN
  798.             GOTO ERROR
  799.         END
  800.  
  801.     END
  802.     -- end SyncTran
  803.  
  804. CLEANUP:
  805.  
  806.     -- disable 'create tables as pseudo system tables
  807.     -- sp_MS_upd_sysobj_category is obsolete, use sp_MS_marksystemobject instead
  808.     -- exec dbo.sp_MS_upd_sysobj_category 2
  809.     RETURN( @fError )
  810.  
  811. ERROR:
  812.  
  813.     select @fError = 1
  814.     GOTO CLEANUP
  815.  
  816. GO
  817.  
  818. EXEC dbo.sp_MS_marksystemobject sp_MScreate_pub_tables
  819. GO
  820.  
  821. dump tran master with no_log
  822. go
  823.  
  824. /*
  825. ** Create replication stored procedures.
  826. ** Part 2:  create all other stored procedures.
  827. */
  828.  
  829. -- synctran supporting procs
  830. raiserror('Creating procedure sp_MSscript_validate_subscription', 0,1)
  831. go
  832. create procedure sp_MSscript_validate_subscription
  833.     @publication sysname,
  834.     @article sysname
  835. as
  836.  
  837.     declare @pubid int
  838.     declare @artid int
  839.     select @pubid = pubid from syspublications where name = @publication
  840.     select @artid = artid from sysarticles where pubid = @pubid and name = @article
  841.  
  842.     insert into #proctext(procedure_text) values
  843.         (N'exec @retcode = dbo.sp_MSvalidate_subscription @orig_server, @orig_db, '
  844.             + convert(nvarchar(10), @artid))
  845.     insert into #proctext(procedure_text) values
  846.         (N'if @@error <> 0 or @retcode <> 0 return -1 ' )
  847.                     
  848. go
  849.  
  850. EXEC dbo.sp_MS_marksystemobject sp_MSscript_validate_subscription
  851. GO
  852.  
  853. -- synctran supporting procs
  854. raiserror('Creating procedure sp_MSvalidate_subscription', 0,1)
  855. go
  856. create procedure sp_MSvalidate_subscription
  857.     @subscriber sysname,
  858.     @subscriber_db sysname,
  859.     @artid int
  860. as
  861.  
  862.     declare @srvid smallint
  863.     select @srvid = srvid from master..sysservers where srvname = @subscriber
  864.     if not exists (select * from syssubscriptions where artid = @artid and 
  865.         srvid = @srvid and dest_db = @subscriber_db)
  866.     begin
  867.         --  The subscription has been dropped from the publisher. Please run sp_subscription_cleanup to cleanup the triggers.
  868.         exec sp_MSreplraiserror 21161
  869.         return -1
  870.     end                    
  871. go
  872. EXEC dbo.sp_MS_marksystemobject sp_MSvalidate_subscription
  873. GO
  874.  
  875.  
  876. create proc sp_MSsetfilterparent @filter_name sysname, @parent_id int
  877. as
  878.    -- SQL SERVER 7.0 ONLY update sysobjects, set parent id = underlying
  879.    -- object id
  880.  
  881.     declare @retcode int
  882.     exec @retcode = dbo.sp_MSreplcheck_publish
  883.     if @@ERROR <> 0 or @retcode <> 0
  884.         return(1)
  885.  
  886.    BEGIN TRAN
  887.  
  888.    exec dbo.sp_replupdateschema @filter_name 
  889.    update sysobjects set parent_obj = @parent_id where id = object_id( @filter_name )
  890.  
  891.    COMMIT TRAN
  892.  
  893. go
  894.  
  895.  
  896. EXEC dbo.sp_MS_marksystemobject sp_MSsetfilterparent
  897. GO
  898.  
  899. create proc sp_MSdoesfilterhaveparent @filter_id int
  900. as
  901.     declare @retcode int
  902.     exec @retcode = dbo.sp_MSreplcheck_publish
  903.     if @@ERROR <> 0 or @retcode <> 0
  904.         return(1)
  905.  
  906.     if exists ( select * from sysobjects
  907.                 where id = @filter_id and
  908.                 parent_obj <> 0 )
  909.     BEGIN
  910.         return 1
  911.     END
  912.     ELSE
  913.     BEGIN
  914.         return 0
  915.     END
  916. go
  917.  
  918. EXEC dbo.sp_MS_marksystemobject sp_MSdoesfilterhaveparent
  919. GO
  920.  
  921.  
  922. create proc sp_MSsetfilteredstatus @object_id int
  923. as
  924.     declare @qualified_name nvarchar(512)
  925.  
  926.     declare @retcode int
  927.     exec @retcode = dbo.sp_MSreplcheck_publish
  928.     if @@ERROR <> 0 or @retcode <> 0
  929.         return(1)
  930.  
  931.     exec dbo.sp_MSget_qualified_name @object_id, @qualified_name output
  932.  
  933.    BEGIN TRANSACTION
  934.    
  935.    exec dbo.sp_replupdateschema @qualified_name
  936.         
  937.    if exists( select * from sysobjects where type = 'RF' and parent_obj = @object_id )
  938.       or exists( select * from sysarticles where objid = @object_id and ( upd_cmd like 'CALL%' OR upd_cmd like 'XCALL%' ) )
  939.    begin
  940.        update sysobjects set replinfo = replinfo | 32 where id = @object_id
  941.    end
  942.    else
  943.    begin
  944.        update sysobjects set replinfo = replinfo & ~32 where id = @object_id
  945.    end
  946.  
  947.    COMMIT TRANSACTION
  948.    
  949. go
  950.  
  951. EXEC dbo.sp_MS_marksystemobject sp_MSsetfilteredstatus
  952. GO
  953.  
  954. CREATE PROCEDURE sp_MSreplsup_table_has_pk @tabid INT
  955. as
  956.     IF NOT EXISTS (SELECT * FROM sysobjects
  957.                    WHERE parent_obj = @tabid
  958.                    AND xtype = 'PK')
  959.         RETURN 0
  960.     ELSE
  961.         RETURN 1
  962. go
  963.  
  964. EXEC dbo.sp_MS_marksystemobject sp_MSreplsup_table_has_pk
  965. GO
  966.  
  967. CREATE PROCEDURE sp_replsync (
  968.     @publisher sysname,    
  969.     @publisher_db sysname,        
  970.     @publication sysname,    
  971.     @article sysname = '%' 
  972.     ) AS
  973.  
  974.     SET NOCOUNT ON
  975.     RAISERROR (21023, 16, -1,'sp_replsync')
  976.     RETURN(1)
  977. GO
  978.  
  979. EXEC dbo.sp_MS_marksystemobject sp_replsync
  980. GO
  981.  
  982.  
  983. print ''
  984. print 'Creating procedure sp_enumfullsubscriber'
  985. go
  986.  
  987. CREATE PROCEDURE sp_enumfullsubscribers (
  988.         @publication sysname = '%'      /* The publication name */
  989.     ) AS
  990.  
  991.     /*
  992.     ** Declarations.
  993.     */
  994.  
  995.     DECLARE @retcode int
  996.  
  997.     /*
  998.     ** Security Check
  999.     */
  1000.     exec @retcode = dbo.sp_MSreplcheck_publish
  1001.     if @@ERROR <> 0 or @retcode <> 0
  1002.         return(1)
  1003.  
  1004.     /*
  1005.     ** Parameter Check: @publication.
  1006.     ** Check to make sure that the publication exists and that it conforms
  1007.     ** to the rules for identifiers.
  1008.     */
  1009.  
  1010.     IF @publication IS NOT NULL
  1011.         BEGIN
  1012.  
  1013.             IF @publication <> '%'
  1014.                 BEGIN
  1015.                     EXECUTE @retcode = dbo.sp_validname @publication
  1016.  
  1017.                     IF @retcode <> 0
  1018.                     RETURN (1)
  1019.                 END
  1020.  
  1021.             IF NOT EXISTS (SELECT * FROM syspublications WHERE name LIKE @publication)
  1022.                 BEGIN
  1023.                     RAISERROR (20026, 11, -1, @publication)
  1024.                     RETURN (1)
  1025.                 END
  1026.  
  1027.         END
  1028.  
  1029.     ELSE
  1030.         BEGIN
  1031.             RAISERROR (14043, 16, -1, '@publication')
  1032.             RETURN (1)
  1033.         END
  1034.  
  1035.     /*
  1036.     ** Select all subscribers who subscribe to all articles in the desired
  1037.     ** publication.
  1038.     */
  1039.  
  1040.     SELECT DISTINCT 'subscriber' = sv.srvname
  1041.       FROM syspublications p,
  1042.            sysarticles s,
  1043.            syssubscriptions ss,
  1044.            master..sysservers sv
  1045.      WHERE p.name LIKE @publication
  1046.        AND p.pubid = s.pubid
  1047.        AND s.artid = ss.artid
  1048.        AND ss.srvid = sv.srvid
  1049.        AND NOT EXISTS (SELECT *
  1050.                          FROM sysarticles s2
  1051.                         WHERE s2.pubid = p.pubid
  1052.                           AND NOT EXISTS (SELECT *
  1053.                                             FROM syssubscriptions ss2,
  1054.                                                  master..sysservers sv2
  1055.                                            WHERE s2.artid = ss2.artid
  1056.                                              AND ss2.srvid = sv2.srvid
  1057.                                              AND sv2.srvid = sv.srvid))
  1058. go
  1059.  
  1060.  
  1061. EXEC dbo.sp_MS_marksystemobject sp_enumfullsubscribers
  1062. GO
  1063.  
  1064. print ''
  1065. print 'Creating procedure sp_addpublication.'
  1066. go
  1067.  
  1068.  
  1069. CREATE PROCEDURE sp_addpublication (
  1070.     @publication sysname,                           /* publication name */
  1071.     @taskid int = 0,                                /* backward compatible */
  1072.     @restricted nvarchar (10) = 'false',            /* publication security */
  1073.     @sync_method nvarchar(13) = 'native',           /* (bcp) native, (bcp) character */
  1074.     @repl_freq nvarchar(10) = 'continuous',         /* continuous, snapshot */
  1075.     @description nvarchar (255) = NULL,             /* publication description */
  1076.     @status nvarchar(8) = 'inactive',               /* publication status; 0=inactive, 1=active */
  1077.     @independent_agent nvarchar(5) = 'false',       /* true or false */
  1078.     @immediate_sync nvarchar(5) = 'false',          /* true or false */
  1079.     @enabled_for_internet nvarchar(5) = 'false',    /* true or false */
  1080.     @allow_push nvarchar(5) = 'true',               /* true or false */
  1081.     @allow_pull nvarchar(5) = 'false',              /* true or false */
  1082.     @allow_anonymous nvarchar(5) = 'false',         /* true or false */
  1083.     -- SyncTran
  1084.     @allow_sync_tran nvarchar(5) = 'false',        /* true or false */
  1085.     @autogen_sync_procs nvarchar(5) = 'true',        /* auto gen sync tran procs per article */
  1086.     @retention  int = 72                          /* over weekend - 3 days */
  1087.     ) AS
  1088.  
  1089.     SET NOCOUNT ON
  1090.  
  1091.     /*
  1092.     ** Declarations.
  1093.     */
  1094.  
  1095.     DECLARE @retcode    int         /* return code value for procedure execution */
  1096.     DECLARE @rfid tinyint           /* identifier for replication frequency */
  1097.     DECLARE @publish_bit smallint   /* publication bit (flag) in sysobjects */
  1098.     DECLARE @smid tinyint           /* identifier for sync method */
  1099.     DECLARE @statid tinyint         /* status id based on @status */
  1100.     DECLARE @subs_type_id tinyint   /* subscription type id based on @subscription_type */
  1101.     DECLARE @distributor sysname
  1102.     DECLARE @distribdb sysname
  1103.     DECLARE @distproc nvarchar (255)
  1104.     DECLARE @agentname nvarchar (40)
  1105.     DECLARE @dbname sysname
  1106.     DECLARE @mergepublish_bit smallint
  1107.     DECLARE @found int
  1108.     DECLARE @independent_agent_id bit
  1109.     DECLARE @immediate_sync_id bit
  1110.     DECLARE @enabled_for_internet_id bit
  1111.     DECLARE @allow_push_id bit
  1112.     DECLARE @allow_pull_id bit
  1113.     DECLARE @allow_anonymous_id bit
  1114.     DECLARE @pubid int
  1115.     declare @distgroup sysname
  1116.  
  1117.     -- SyncTran
  1118.     DECLARE @allow_sync_tran_id bit
  1119.     DECLARE @autogen_sync_procs_id bit
  1120.  
  1121.     select @allow_sync_tran_id = 0, @autogen_sync_procs_id = 0
  1122.     -- end SyncTran
  1123.  
  1124.     declare @qv_replication varchar(10)
  1125.     declare @qv_replication_unlimited integer
  1126.     declare @qv_value_replication integer
  1127.  
  1128.     select @qv_replication = '2745196162', @qv_replication_unlimited = 0
  1129.  
  1130.     /*
  1131.     ** The default value for TRAN publication is always 72 hours
  1132.     */
  1133.     if @retention is NULL
  1134.     BEGIN
  1135.         RAISERROR(20081, 16, -1, 'retention')
  1136.         RETURN (1)
  1137.     END
  1138.     
  1139.     /*
  1140.     ** A @retention value of zero means an infinite retention period
  1141.     */
  1142.     if @retention < 0
  1143.     BEGIN
  1144.         RAISERROR (20050, 16, -1, 1)
  1145.         RETURN(1)
  1146.     END
  1147.  
  1148.     SELECT @publish_bit         = 32
  1149.     SELECT @mergepublish_bit    = 4
  1150.  
  1151.     /*
  1152.     ** Security Check
  1153.     */
  1154.  
  1155.     exec @retcode = dbo.sp_MSreplcheck_publish
  1156.     if @@ERROR <> 0 or @retcode <> 0
  1157.         return(1)
  1158.  
  1159.     /*
  1160.     ** Check to see if the database has been activated for publication.
  1161.     */
  1162.  
  1163.     IF (SELECT category & 1
  1164.           FROM master..sysdatabases
  1165.          WHERE name = DB_NAME()) = 0
  1166.  
  1167.     BEGIN
  1168.         RAISERROR (14013, 16, -1)
  1169.         RETURN (1)
  1170.     END
  1171.  
  1172.     IF @taskid <> 0
  1173.     BEGIN
  1174.         -- No longer supported
  1175.         RAISERROR (21023, 16, -1,'@taskid')
  1176.         RETURN(1)
  1177.     END
  1178.  
  1179.     /*
  1180.     ** Parameter Check: @publication.
  1181.     ** The @publication name must conform to the rules for identifiers,
  1182.     ** and must not be the keyword 'all'.
  1183.     */
  1184.  
  1185.     IF @publication IS NULL
  1186.         BEGIN
  1187.             RAISERROR (14043, 16, -1, '@publication')
  1188.             RETURN (1)
  1189.         END
  1190.  
  1191.     exec @retcode = dbo.sp_MSreplcheck_name @publication
  1192.     if @@ERROR <> 0 or @retcode <> 0
  1193.         return(1)
  1194.  
  1195.     IF LOWER (@publication) = 'all'
  1196.         BEGIN
  1197.             RAISERROR (14034, 16, -1)
  1198.             RETURN (1)
  1199.         END
  1200.  
  1201.     /*
  1202.     **  Check if the publication already exists.
  1203.     **  1. Check transaction-level publications
  1204.     **  2. Check merge publications
  1205.     */
  1206.  
  1207.     IF EXISTS (SELECT * FROM syspublications WHERE name = @publication)
  1208.         BEGIN
  1209.             RAISERROR (14016, 16, -1, @publication)
  1210.             RETURN (1)
  1211.         END
  1212.     
  1213.     if (select category & @mergepublish_bit from master..sysdatabases where name = DB_NAME()) <> 0
  1214.         begin
  1215.             EXEC @retcode = dbo.sp_helpmergepublication @publication, @found output
  1216.  
  1217.             IF @@ERROR <> 0 OR @retcode <> 0
  1218.             BEGIN
  1219.                 RETURN (1)
  1220.             END
  1221.  
  1222.             IF @found <> 0 
  1223.             BEGIN
  1224.                 RAISERROR (20025, 16, -1, @publication)
  1225.                 RETURN (1)
  1226.             END
  1227.         end
  1228.  
  1229.     /*
  1230.     ** Get distribution server information for remote RPC
  1231.     ** agent verification.
  1232.     */
  1233.     EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  1234.                  @distribdb = @distribdb OUTPUT
  1235.  
  1236.     IF @@error <> 0 OR @retcode <> 0
  1237.         BEGIN
  1238.         RAISERROR (14071, 16, -1)
  1239.             RETURN (1)
  1240.     END
  1241.  
  1242.  
  1243.     /*
  1244.     ** Parameter Check: @sync_method
  1245.     ** The synchronization method must be one of the following:
  1246.     **
  1247.     **      0  [bcp] native
  1248.     **      1  [bcp] character
  1249.     */
  1250.  
  1251.     SELECT @sync_method = LOWER(@sync_method)
  1252.     IF @sync_method IS NULL OR @sync_method NOT IN ('native', 'character', 'bcp native', 'bcp character')
  1253.         BEGIN
  1254.             RAISERROR (14014, 16, -1)
  1255.             RETURN (1)
  1256.         END
  1257.  
  1258.     IF @sync_method IN ('character', 'bcp character')
  1259.         SELECT @smid = 1
  1260.     ELSE
  1261.         SELECT @smid = 0
  1262.  
  1263.     /*
  1264.     ** Parameter Check: @repl_freq.
  1265.     ** Make sure that the replication frequency is one of the following:
  1266.     **
  1267.     **  id  frequency
  1268.     **  ==  ==========
  1269.     **   0  continuous
  1270.     **   1  snapshot
  1271.     */
  1272.  
  1273.     SELECT @repl_freq = LOWER(@repl_freq)
  1274.     IF @repl_freq IS NULL OR @repl_freq NOT IN ('continuous', 'snapshot')
  1275.         BEGIN
  1276.             RAISERROR (14015, 16, -1)
  1277.             RETURN (1)
  1278.         END
  1279.  
  1280.     IF @repl_freq = 'snapshot' SELECT @rfid = 1
  1281.     ELSE SELECT @rfid = 0
  1282.  
  1283.     -- disable tran publishing on REPLICATION_LIMITED sku
  1284.     exec @qv_value_replication = master.dbo.xp_qv @qv_replication     
  1285.     if (@rfid = 0) and ( @qv_value_replication != @qv_replication_unlimited ) 
  1286.     begin
  1287.         raiserror(21108, 16, -1)
  1288.         return (1)
  1289.     end
  1290.  
  1291.     /*
  1292.     ** Parameter Check:  @restricted.
  1293.     */
  1294.  
  1295.     IF (@restricted IS NULL) OR (LOWER(@restricted) NOT IN ('true', 'false'))
  1296.         BEGIN
  1297.             RAISERROR (14017, 16, -1)
  1298.             RETURN (1)
  1299.         END
  1300.  
  1301.     /*
  1302.     ** Restricted publications are no longer supported
  1303.     */
  1304.     IF LOWER(@restricted) = 'true'
  1305.     BEGIN
  1306.         RAISERROR (14147, 16, -1)
  1307.         RETURN(1)
  1308.     END
  1309.  
  1310.     /*
  1311.     ** Parameter Check:  @status.
  1312.     ** The @status value can be:
  1313.     **
  1314.     **      statid  status
  1315.     **      ======  ========
  1316.     **           0  inactive
  1317.     **           1  active
  1318.     */
  1319.  
  1320.     IF @status IS NULL OR LOWER(@status) NOT IN ('inactive', 'active')
  1321.         BEGIN
  1322.             RAISERROR (14012, 16, -1)
  1323.             RETURN (1)
  1324.         END
  1325.  
  1326.     IF LOWER(@status) = 'active' SELECT @statid = 1
  1327.     ELSE SELECT @statid = 0
  1328.  
  1329.     /*
  1330.     ** Parameter Check:  @independent_agent.
  1331.     */
  1332.  
  1333.     IF @independent_agent IS NULL OR LOWER(@independent_agent) NOT IN ('true', 'false')
  1334.         BEGIN
  1335.             RAISERROR (14148, 16, -1, '@independent_agent')
  1336.             RETURN (1)
  1337.         END
  1338.  
  1339.     IF LOWER(@independent_agent) = 'true' SELECT @independent_agent_id = 1
  1340.     ELSE SELECT @independent_agent_id = 0
  1341.  
  1342.     /*
  1343.     ** Parameter Check:  @immediate_sync.
  1344.     */
  1345.  
  1346.     IF @immediate_sync IS NULL OR LOWER(@immediate_sync) NOT IN ('true', 'false')
  1347.         BEGIN
  1348.             RAISERROR (14148, 16, -1, '@immediate_sync')
  1349.             RETURN (1)
  1350.         END
  1351.  
  1352.     IF LOWER(@immediate_sync) = 'true' SELECT @immediate_sync_id = 1
  1353.     ELSE SELECT @immediate_sync_id = 0
  1354.  
  1355.     /*
  1356.     ** Parameter Check:  @enabled_for_internet.
  1357.     */
  1358.  
  1359.     IF @enabled_for_internet IS NULL OR LOWER(@enabled_for_internet) NOT IN ('true', 'false')
  1360.         BEGIN
  1361.             RAISERROR (14148, 16, -1, '@enabled_for_internet')
  1362.             RETURN (1)
  1363.         END
  1364.  
  1365.     IF LOWER(@enabled_for_internet) = 'true' SELECT @enabled_for_internet_id = 1
  1366.     ELSE SELECT @enabled_for_internet_id = 0
  1367.  
  1368.     /*
  1369.     ** Parameter Check:  @allow_push.
  1370.     */
  1371.  
  1372.     IF @allow_push IS NULL OR LOWER(@allow_push) NOT IN ('true', 'false')
  1373.         BEGIN
  1374.             RAISERROR (14148, 16, -1, '@allow_push')
  1375.             RETURN (1)
  1376.         END
  1377.     IF LOWER(@allow_push) = 'true' SELECT @allow_push_id = 1
  1378.     ELSE SELECT @allow_push_id = 0
  1379.  
  1380.     /*
  1381.     ** Parameter Check:  @allow_pull.
  1382.     */
  1383.  
  1384.     IF @allow_pull IS NULL OR LOWER(@allow_pull) NOT IN ('true', 'false')
  1385.         BEGIN
  1386.             RAISERROR (14148, 16, -1, '@allow_pull')
  1387.             RETURN (1)
  1388.         END
  1389.     IF LOWER(@allow_pull) = 'true' SELECT @allow_pull_id = 1
  1390.     ELSE SELECT @allow_pull_id = 0
  1391.  
  1392.     /*
  1393.     ** Parameter Check:  @allow_anonymous.
  1394.     */
  1395.  
  1396.     IF @allow_anonymous IS NULL OR LOWER(@allow_anonymous) NOT IN ('true', 'false')
  1397.         BEGIN
  1398.             RAISERROR (14148, 16, -1, '@allow_anonymous')
  1399.             RETURN (1)
  1400.         END
  1401.     IF LOWER(@allow_anonymous) = 'true' SELECT @allow_anonymous_id = 1
  1402.     ELSE SELECT @allow_anonymous_id = 0
  1403.  
  1404.     /* Immediate_sync publications have to be independent_agent */
  1405.     IF @immediate_sync_id = 1 AND @independent_agent_id = 0
  1406.     BEGIN
  1407.             RAISERROR (21022, 16, -1)
  1408.             RETURN (1)
  1409.     END
  1410.  
  1411.  
  1412.     /* 
  1413.     ** Non-immediate sync do not support anonymous subscriptions.
  1414.     */
  1415.  
  1416.     IF @immediate_sync_id = 0 AND @allow_anonymous_id = 1
  1417.     BEGIN
  1418.             RAISERROR (20011, 16, -1)
  1419.             RETURN (1)
  1420.     END
  1421.  
  1422.     -- SyncTran
  1423.     /*
  1424.     ** Parameter Check:  @allow_sync_tran
  1425.     */
  1426.  
  1427.     IF @allow_sync_tran IS NULL OR LOWER(@allow_sync_tran) NOT IN ('true', 'false')
  1428.     BEGIN
  1429.         RAISERROR (14148, 16, -1, '@allow_sync_tran')
  1430.         RETURN (1)
  1431.     END
  1432.  
  1433.     IF LOWER(@allow_sync_tran) = 'true' 
  1434.     BEGIN
  1435.         SELECT @allow_sync_tran_id = 1
  1436.  
  1437.         --Parameter Check:  @autogen_sync_procs
  1438.         IF @autogen_sync_procs IS NULL OR LOWER(@autogen_sync_procs) NOT IN ('true', 'false')
  1439.         BEGIN
  1440.             RAISERROR (14148, 16, -1, '@autogen_sync_procs')
  1441.             RETURN (1)
  1442.         END
  1443.  
  1444.         IF LOWER(@autogen_sync_procs) = 'true' 
  1445.             SELECT @autogen_sync_procs_id = 1
  1446.         ELSE 
  1447.             SELECT @autogen_sync_procs_id = 0
  1448.  
  1449.     END
  1450.     ELSE 
  1451.     BEGIN
  1452.         SELECT @allow_sync_tran_id = 0
  1453.         SELECT @autogen_sync_procs_id = 0
  1454.     END
  1455.     -- end SyncTran
  1456.  
  1457.     /*
  1458.     ** Get distribution server information for remote RPC call.
  1459.     */
  1460.     EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  1461.        @distribdb   = @distribdb OUTPUT
  1462.     IF @@ERROR <> 0 or @retcode <> 0
  1463.     BEGIN
  1464.         GOTO UNDO
  1465.     END
  1466.  
  1467.     /*
  1468.     **  Add publication to syspublications.
  1469.     */
  1470.     begin tran
  1471.     save TRAN sp_addpublication
  1472.  
  1473.     select @dbname = db_name()
  1474.     
  1475.     /*
  1476.     ** Construct Log Reader agent name.
  1477.     */
  1478.  
  1479.     IF @rfid = 0 and NOT EXISTS (SELECT * FROM syspublications where repl_freq = 0)
  1480.     BEGIN
  1481.         /*
  1482.         ** Schedule Log Reader agent for the database
  1483.         */
  1484.         SELECT @distproc = RTRIM(@distributor) + '.' + @distribdb +'.dbo.sp_MSadd_logreader_agent'
  1485.  
  1486.  
  1487.         EXECUTE @retcode = @distproc
  1488.             @publisher = @@SERVERNAME,
  1489.             @publisher_db = @dbname,
  1490.             @publication = 'ALL',  
  1491.             @local_job = 1 
  1492.         IF @@ERROR <> 0 or @retcode <> 0
  1493.             GOTO UNDO
  1494.     END            
  1495.  
  1496.     INSERT syspublications(description, name, repl_freq,
  1497.                            status, sync_method, snapshot_jobid, independent_agent,
  1498.                            immediate_sync, enabled_for_internet, 
  1499.                            allow_push, allow_pull, allow_anonymous, immediate_sync_ready,
  1500.                            -- SyncTran
  1501.                            allow_sync_tran, autogen_sync_procs, retention)
  1502.  
  1503.     VALUES (@description, @publication, @rfid, @statid, @smid, NULL, 
  1504.             @independent_agent_id, 
  1505.             @immediate_sync_id, @enabled_for_internet_id, @allow_push_id,
  1506.             @allow_pull_id, @allow_anonymous_id, 0,
  1507.             -- SyncTran
  1508.             @allow_sync_tran_id, @autogen_sync_procs_id, @retention)
  1509.  
  1510.     IF @@ERROR <> 0
  1511.     BEGIN
  1512.         RAISERROR (14018, 16, -1)
  1513.         GOTO UNDO
  1514.     END
  1515.  
  1516.     SELECT @pubid = @@IDENTITY
  1517.  
  1518.     DECLARE @false bit
  1519.     SELECT @false = 0
  1520.  
  1521.     DECLARE @null sysname
  1522.     SELECT @null = NULL
  1523.  
  1524.     /*
  1525.     ** Add the publication to the distributor side
  1526.     */
  1527.     SELECT @distproc = RTRIM(@distributor) + '.' + @distribdb + 
  1528.         '.dbo.sp_MSadd_publication'
  1529.     EXECUTE @retcode = @distproc
  1530.     @publisher = @@SERVERNAME,
  1531.     @publisher_db = @dbname,
  1532.     @publication = @publication,
  1533.     @publication_type = @rfid,
  1534.     @independent_agent = @independent_agent_id,
  1535.     @immediate_sync = @immediate_sync_id,
  1536.     @allow_push = @allow_push_id,
  1537.     @allow_pull = @allow_pull_id,
  1538.     @allow_anonymous = @allow_anonymous_id,
  1539.     @snapshot_agent = @null,
  1540.     @logreader_agent = @agentname,
  1541.     @description = @description,
  1542.     @retention = @retention
  1543.  
  1544.     IF @@ERROR <> 0 or @retcode <> 0
  1545.         BEGIN
  1546.             GOTO UNDO
  1547.         END
  1548.  
  1549.     -- Populate the initial list.
  1550.     exec @retcode = dbo.sp_grant_publication_access 
  1551.         @publication = @publication,
  1552.         @login = null,
  1553.         @reserved = 'init'
  1554.     IF @@error <> 0 OR @retcode <> 0
  1555.         GOTO UNDO
  1556.  
  1557.     COMMIT TRAN
  1558.  
  1559.     RETURN(0)
  1560.  
  1561. UNDO:
  1562.     IF @@TRANCOUNT > 0
  1563.     begin
  1564.         ROLLBACK TRAN sp_addpublication
  1565.         COMMIT TRAN   
  1566.     end
  1567.     return 1
  1568. go
  1569.  
  1570. EXEC dbo.sp_MS_marksystemobject sp_addpublication
  1571. GO
  1572.  
  1573. print ''
  1574. print 'Creating procedure sp_changepublication'
  1575. go
  1576.  
  1577. CREATE PROCEDURE sp_changepublication (
  1578.     @publication sysname = NULL,        /* Publication name */
  1579.     @property nvarchar(20) = NULL,           /* The property to change */
  1580.     @value nvarchar(255) = NULL              /* The new property value */
  1581.     ) AS
  1582.  
  1583.     SET NOCOUNT ON
  1584.  
  1585.     /*
  1586.     ** Declarations.
  1587.     */
  1588.  
  1589.     DECLARE @cmd nvarchar(255)
  1590.     DECLARE @cmd2 nvarchar(255)
  1591.     DECLARE @pubid int
  1592.     DECLARE @replfreqid tinyint
  1593.     DECLARE @retcode int
  1594.     DECLARE @statusid tinyint
  1595.     DECLARE @syncmethodid tinyint
  1596.     DECLARE @distributor sysname
  1597.     DECLARE @distproc nvarchar (255)
  1598.     DECLARE @subscribed int    
  1599.     DECLARE @virtual_id smallint
  1600.     DECLARE @prev_value_bit bit
  1601.     DECLARE @value_bit bit
  1602.     DECLARE @allow_anonymous bit
  1603.     DECLARE @push int
  1604.     DECLARE @pull int
  1605.     DECLARE @independent_agent bit
  1606.     DECLARE @immediate_sync bit
  1607.     DECLARE @distribdb sysname
  1608.     DECLARE @dbname sysname
  1609.     DECLARE @taskid int
  1610.     DECLARE @add_virtual_back bit
  1611.  
  1612.  
  1613.     SELECT @add_virtual_back = 0
  1614.     SELECT @push = 0
  1615.     SELECT @pull = 1
  1616.  
  1617.     SELECT @subscribed = 1
  1618.     SELECT @virtual_id = -1
  1619.  
  1620.     /*
  1621.     ** Security Check
  1622.     */
  1623.  
  1624.     exec @retcode = dbo.sp_MSreplcheck_publish
  1625.     if @@ERROR <> 0 or @retcode <> 0
  1626.         return(1)
  1627.  
  1628.     /*
  1629.     ** Check to see if the database has been activated for publication.
  1630.     */
  1631.  
  1632.     IF (SELECT category & 1
  1633.           FROM master..sysdatabases
  1634.          WHERE name = DB_NAME()) = 0
  1635.  
  1636.     BEGIN
  1637.         RAISERROR (14013, 16, -1)
  1638.         RETURN (1)
  1639.     END
  1640.  
  1641.     
  1642.     /*
  1643.     ** Parameter Check:  @property.
  1644.     ** If the @property parameter is NULL, print the options.
  1645.     */
  1646.  
  1647.     IF @property IS NULL
  1648.         BEGIN
  1649.             CREATE TABLE #tab1 (properties sysname NOT NULL)
  1650.             INSERT INTO #tab1 VALUES ('description')
  1651.             --INSERT INTO #tab1 VALUES ('taskid')
  1652.             INSERT INTO #tab1 VALUES ('sync_method')
  1653.             INSERT INTO #tab1 VALUES ('status')
  1654.             INSERT INTO #tab1 VALUES ('repl_freq')
  1655.             INSERT INTO #tab1 VALUES ('independent_agent')
  1656.             INSERT INTO #tab1 VALUES ('immediate_sync')
  1657.             INSERT INTO #tab1 VALUES ('enabled_for_internet')
  1658.             INSERT INTO #tab1 VALUES ('allow_push')
  1659.             INSERT INTO #tab1 VALUES ('allow_pull')
  1660.             INSERT INTO #tab1 VALUES ('allow_anonymous')
  1661.             INSERT INTO #tab1 VALUES ('retention')
  1662.             PRINT ''
  1663.             SELECT * FROM #tab1
  1664.             RETURN (0)
  1665.         END
  1666.  
  1667.     /*
  1668.     ** Parameter Check:  @publication.
  1669.     ** Make sure that the publication exists.
  1670.     */
  1671.  
  1672.     IF @publication IS NULL
  1673.         BEGIN
  1674.             RAISERROR (14043, 16, -1, '@publication')
  1675.             RETURN (1)
  1676.         END
  1677.  
  1678.     EXECUTE @retcode = dbo.sp_validname @publication
  1679.  
  1680.     IF @@ERROR <> 0 OR @retcode <> 0
  1681.     RETURN (1)
  1682.  
  1683.     SELECT @allow_anonymous = allow_anonymous, @pubid = pubid,
  1684.         @immediate_sync = immediate_sync,
  1685.         @independent_agent = independent_agent
  1686.         FROM syspublications 
  1687.         WHERE name = @publication
  1688.  
  1689.     IF @pubid IS NULL
  1690.         BEGIN
  1691.             RAISERROR (20026, 11, -1, @publication)
  1692.             RETURN (1)
  1693.         END
  1694.     ELSE
  1695.  
  1696.     /*
  1697.     ** Parameter Check:  @property.
  1698.     ** Check to make sure that @property is a valid property in
  1699.     ** syspublications.
  1700.     */
  1701.  
  1702.     -- Note: must change message 14078 when adding a new property.
  1703.     IF LOWER(@property) NOT IN ( 'taskid','description', 'sync_method',
  1704.      'status', 'repl_freq','immediate_sync', 'independent_agent', 
  1705.      'enabled_for_internet', 'allow_push', 'allow_pull', 'allow_anonymous', 'retention')
  1706.         BEGIN
  1707.             RAISERROR (14078, 16, -1)
  1708.             RETURN (1)
  1709.         END
  1710.  
  1711.     /*
  1712.     ** Change the property.
  1713.     */
  1714.     begin tran
  1715.     save TRAN sp_changepublication
  1716.  
  1717.     IF LOWER(@property) ='description'
  1718.         BEGIN
  1719.             UPDATE syspublications SET description = @value
  1720.                 WHERE pubid = @pubid
  1721.             IF @@ERROR <> 0 GOTO UNDO
  1722.         END
  1723.         
  1724.     IF LOWER(@property) ='retention'
  1725.         BEGIN
  1726.             if @value is NULL 
  1727.                 BEGIN
  1728.                     RAISERROR(20081, 16, -1, @property)
  1729.                     GOTO UNDO
  1730.                 END
  1731.                 
  1732.             UPDATE syspublications SET retention = convert(int, @value)
  1733.                 WHERE pubid = @pubid
  1734.             IF @@ERROR <> 0 GOTO UNDO
  1735.         END
  1736.    
  1737.  
  1738.     IF LOWER(@property) = 'taskid'
  1739.        BEGIN
  1740.             -- No longer supported
  1741.             RAISERROR (21023, 16, -1,'@taskid')
  1742.             RETURN(1)
  1743.        END
  1744.  
  1745.     IF LOWER(@property) = 'sync_method'
  1746.         BEGIN
  1747.  
  1748.             /*
  1749.             ** Check for a valid synchronization method.
  1750.             */
  1751.  
  1752.             IF LOWER(@value) NOT IN ('native', 'character', 'bcp native', 'bcp character')
  1753.                 BEGIN
  1754.                     RAISERROR (14014, 16, -1)
  1755.                     GOTO UNDO
  1756.                 END
  1757.  
  1758.             /*
  1759.             ** Determine the integer value for the sync_method.
  1760.             */
  1761.  
  1762.             IF LOWER(@value) IN ('native', 'bcp native')
  1763.                 SELECT @syncmethodid = 0
  1764.             ELSE IF LOWER(@value) IN ('character', 'bcp character')
  1765.                 SELECT @syncmethodid = 1
  1766.  
  1767.             /*
  1768.             ** Update the publication with the new synchronization method.
  1769.             */
  1770.  
  1771.             UPDATE syspublications
  1772.                SET sync_method = @syncmethodid
  1773.              WHERE pubid = @pubid
  1774.  
  1775.             IF @@ERROR <> 0 GOTO UNDO
  1776.  
  1777.         END
  1778.  
  1779.     IF LOWER(@property) = 'status'
  1780.         BEGIN
  1781.             
  1782.             /*
  1783.             ** Check to make sure that we have a valid status.
  1784.             */
  1785.  
  1786.             IF LOWER(@value) NOT IN ('active', 'inactive')
  1787.                 BEGIN
  1788.                     RAISERROR (14012, 16, -1)
  1789.                     GOTO UNDO
  1790.                 END
  1791.  
  1792.             /*
  1793.             ** Determine the integer value for the status.
  1794.             */
  1795.  
  1796.             IF LOWER(@value) = 'active'
  1797.                 SELECT @statusid = 1
  1798.             ELSE
  1799.                 SELECT @statusid = 0
  1800.  
  1801.             /* If status changed */
  1802.             IF EXISTS (SELECT * FROM syspublications
  1803.                 WHERE  pubid = @pubid  AND
  1804.                  status <> @statusid)
  1805.             BEGIN
  1806.     
  1807.                 /* 
  1808.                 ** If change the status of the publication,
  1809.                 ** virtual anonymous subscription have to be recreated.
  1810.                 **
  1811.                 */
  1812.                 IF @allow_anonymous = 1
  1813.                 BEGIN
  1814.                     /* Drop virtual subscriptions */
  1815.                     EXEC @retcode = dbo.sp_dropsubscription 
  1816.                         @publication = @publication, 
  1817.                         @article = 'all', 
  1818.                         @subscriber = NULL,
  1819.                         @reserved = 'internal'
  1820.                     IF @@ERROR <> 0 OR @retcode <> 0
  1821.                     BEGIN
  1822.                         GOTO UNDO
  1823.                     END
  1824.                 END
  1825.  
  1826.                 /*
  1827.                 ** Update the publication with the new status.
  1828.                 */
  1829.  
  1830.                 UPDATE syspublications
  1831.                    SET status = @statusid
  1832.                  WHERE pubid = @pubid
  1833.  
  1834.                 IF @@ERROR <> 0 
  1835.                 BEGIN
  1836.                     GOTO UNDO                
  1837.                 END
  1838.                 
  1839.                 IF @allow_anonymous = 1
  1840.                     SELECT @add_virtual_back = 1
  1841.             END
  1842.         END
  1843.  
  1844.     IF LOWER(@property) = 'repl_freq'
  1845.         BEGIN
  1846.  
  1847.             /*
  1848.             ** Check for a valid replication frequency value.
  1849.             */
  1850.  
  1851.             IF LOWER(@value) NOT IN ('continuous', 'snapshot')
  1852.                 BEGIN
  1853.                     RAISERROR (14015, 16, -1)
  1854.                     GOTO UNDO
  1855.                 END
  1856.  
  1857.  
  1858.             /*
  1859.             ** Determine the integer value for the replication frequency.
  1860.             */
  1861.  
  1862.             IF LOWER(@value) = 'continuous'
  1863.                 SELECT @replfreqid = 0
  1864.             ELSE
  1865.                 SELECT @replfreqid = 1
  1866.  
  1867.             /*
  1868.             ** Only unsubscribed publications may have this modified.
  1869.             */
  1870.             IF EXISTS (SELECT * FROM syssubscriptions
  1871.             WHERE 
  1872.                 status <> @subscribed AND
  1873.                 srvid >= 0 AND
  1874.                 artid IN (SELECT artid FROM sysarticles where pubid
  1875.                = @pubid))
  1876.             BEGIN
  1877.                 RAISERROR (14033, 11, -1)
  1878.                 GOTO UNDO
  1879.             END
  1880.  
  1881.  
  1882.             IF @immediate_sync = 1
  1883.             BEGIN
  1884.                 /* Drop virtual subscriptions */
  1885.                 EXEC @retcode = dbo.sp_dropsubscription 
  1886.                     @publication = @publication, 
  1887.                     @article = 'all', 
  1888.                     @subscriber = NULL,
  1889.                     @reserved = 'internal'
  1890.                 IF @@ERROR <> 0 OR @retcode <> 0
  1891.                 BEGIN
  1892.                     GOTO UNDO                
  1893.                 END
  1894.             END
  1895.             /*
  1896.             ** Update the publication with the new replication frequency.
  1897.             */
  1898.  
  1899.             UPDATE syspublications
  1900.                SET repl_freq = @replfreqid
  1901.              WHERE pubid = @pubid
  1902.  
  1903.             IF @@ERROR <> 0 
  1904.             BEGIN
  1905.                 GOTO UNDO
  1906.             END
  1907.  
  1908.             IF @immediate_sync = 1
  1909.                 SELECT @add_virtual_back = 1
  1910.         END
  1911.  
  1912.     
  1913.     IF LOWER(@property) IN ('independent_agent', 'immediate_sync','enabled_for_internet',
  1914.             'allow_push', 'allow_pull', 'allow_anonymous')
  1915.     BEGIN
  1916.  
  1917.     
  1918.         /*
  1919.         ** Check for a valid  value.
  1920.         */
  1921.  
  1922.         IF LOWER(@value) NOT IN ('true', 'false')
  1923.         BEGIN
  1924.             RAISERROR (14137, 16, -1)
  1925.             GOTO UNDO
  1926.         END
  1927.  
  1928.         /*
  1929.         ** set value bit
  1930.         */
  1931.  
  1932.         IF LOWER(@value) = 'true'
  1933.             SELECT @value_bit = 1
  1934.         ELSE 
  1935.             SELECT @value_bit = 0
  1936.  
  1937.  
  1938.         IF LOWER(@property) = 'independent_agent'
  1939.         BEGIN
  1940.  
  1941.  
  1942.             SELECT @prev_value_bit = independent_agent
  1943.               FROM syspublications 
  1944.              WHERE name = @publication
  1945.  
  1946.             IF @prev_value_bit <> @value_bit
  1947.             BEGIN
  1948.  
  1949.                IF @immediate_sync = 1 AND @value_bit = 0
  1950.                BEGIN
  1951.                     RAISERROR (21022, 16, -1)
  1952.                     GOTO UNDO
  1953.                END    
  1954.  
  1955.                /* 
  1956.                ** no subscriptions are allowed
  1957.                */
  1958.                IF EXISTS (SELECT * FROM syssubscriptions ss, sysarticles sa
  1959.                         WHERE ss.artid = sa.artid
  1960.                         AND   sa.pubid = @pubid
  1961.                         AND   ss.srvid <> @virtual_id )
  1962.                 BEGIN
  1963.                     RAISERROR (20013, 16, -1, @property)
  1964.                     GOTO UNDO
  1965.                 END
  1966.             
  1967.                 /* Update the publication type */
  1968.                 UPDATE syspublications 
  1969.                     SET independent_agent = @value_bit
  1970.                     WHERE pubid = @pubid
  1971.                 IF @@error <> 0
  1972.                 BEGIN
  1973.                     GOTO UNDO
  1974.                 END
  1975.             END
  1976.         END
  1977.  
  1978.         IF LOWER(@property) = 'immediate_sync'
  1979.         BEGIN
  1980.  
  1981.  
  1982.             SELECT @prev_value_bit = immediate_sync
  1983.               FROM syspublications 
  1984.              WHERE name = @publication
  1985.  
  1986.             IF @prev_value_bit <> @value_bit
  1987.             BEGIN
  1988.  
  1989.                IF @independent_agent = 0 AND @value_bit = 1
  1990.                BEGIN
  1991.                     RAISERROR (21022, 16, -1)
  1992.                     GOTO UNDO
  1993.                END    
  1994.  
  1995.                /* 
  1996.                ** The publication has to be immediate_sync type to
  1997.                ** allow anonymous subscriptions
  1998.                */
  1999.                 IF @value_bit = 0 AND
  2000.                     EXISTS (SELECT * FROM syspublications
  2001.                         WHERE pubid = @pubid
  2002.                         AND   allow_anonymous = 1 )
  2003.                 BEGIN
  2004.                     RAISERROR (20011, 16, -1, @property)
  2005.                     GOTO UNDO
  2006.                 END
  2007.  
  2008.             
  2009.                 /* 
  2010.                 ** If turn on immediate_sync, we need to add virtual subscriptions,
  2011.                 ** Otherwise, we need to drop them
  2012.                 ** When adding, we need to change publication bit first
  2013.                 ** When dropping, we need to change publication bit second
  2014.                 */
  2015.                 IF @value_bit = 0
  2016.                 BEGIN
  2017.                     -- Drop virtual subscriptions 
  2018.                     EXEC @retcode = dbo.sp_dropsubscription 
  2019.                         @publication = @publication, 
  2020.                         @article = 'all', 
  2021.                         @subscriber = NULL,
  2022.                         @reserved = 'internal'
  2023.                     IF @@ERROR <> 0 OR @retcode <> 0
  2024.                     BEGIN
  2025.                         GOTO UNDO
  2026.                     END
  2027.  
  2028.                     -- Reset the immediate_sync ready bit
  2029.                     UPDATE syspublications 
  2030.                         SET immediate_sync_ready = 0
  2031.                         WHERE pubid = @pubid
  2032.  
  2033.                 END
  2034.  
  2035.                 /* Update the publication type */
  2036.                 UPDATE syspublications 
  2037.                     SET immediate_sync = @value_bit
  2038.                     WHERE pubid = @pubid
  2039.                 IF @@error <> 0
  2040.                 BEGIN
  2041.                     GOTO UNDO
  2042.                 END
  2043.  
  2044.  
  2045.                 IF @value_bit = 1
  2046.                     SELECT @add_virtual_back = 1
  2047.             END
  2048.         END
  2049.  
  2050.         IF LOWER(@property) = 'allow_anonymous'
  2051.         BEGIN
  2052.  
  2053.             SELECT @prev_value_bit = allow_anonymous
  2054.               FROM syspublications 
  2055.              WHERE name = @publication
  2056.  
  2057.             IF @prev_value_bit <> @value_bit
  2058.             BEGIN
  2059.                 /* 
  2060.                 ** The publication has to be immediate_sync type to
  2061.                 ** allow anonymous subscriptions
  2062.                 */
  2063.                 IF @value_bit = 1 AND
  2064.                     NOT EXISTS (SELECT * FROM syspublications
  2065.                         WHERE pubid = @pubid
  2066.                         AND   immediate_sync = 1 )
  2067.                 BEGIN
  2068.                     RAISERROR (20011, 16, -1, @property)
  2069.                     GOTO UNDO
  2070.                 END
  2071.                 
  2072.                 
  2073.  
  2074.                 /* Drop virtual subscriptions */
  2075.                 EXEC @retcode = dbo.sp_dropsubscription 
  2076.                     @publication = @publication, 
  2077.                     @article = 'all', 
  2078.                     @subscriber = NULL,
  2079.                     @reserved = 'internal'
  2080.                 IF @@ERROR <> 0 OR @retcode <> 0
  2081.                 BEGIN
  2082.                     GOTO UNDO
  2083.                 END
  2084.  
  2085.                 /* Update the publication type */
  2086.                 UPDATE syspublications 
  2087.                     SET allow_anonymous = @value_bit
  2088.                     WHERE pubid = @pubid
  2089.                 IF @@error <> 0
  2090.                 BEGIN
  2091.                    GOTO UNDO
  2092.                 END
  2093.  
  2094.                 /* 
  2095.                 ** add virtual subscriptions back again to enable 
  2096.                 ** anonymous subscription.
  2097.                 */
  2098.                 SELECT @add_virtual_back = 1
  2099.  
  2100.             END
  2101.  
  2102.         END
  2103.  
  2104.         IF LOWER(@property) = 'enabled_for_internet'
  2105.         BEGIN
  2106.  
  2107.             /* Update the publication type */
  2108.             UPDATE syspublications 
  2109.                 SET enabled_for_internet = @value_bit
  2110.                 WHERE pubid = @pubid
  2111.             IF @@error <> 0
  2112.             BEGIN
  2113.                GOTO UNDO
  2114.             END
  2115.         END
  2116.  
  2117.         IF LOWER(@property) = 'allow_push'
  2118.         BEGIN
  2119.  
  2120.            /* 
  2121.            ** If turn it off, make sure there's no push subscriptions left
  2122.            */
  2123.            IF @value_bit = 0 AND
  2124.             EXISTS (SELECT * FROM syssubscriptions ss, sysarticles sa
  2125.                     WHERE ss.artid = sa.artid
  2126.                     AND   sa.pubid = @pubid
  2127.                     AND      ss.subscription_type = @push
  2128.                     AND   ss.srvid <> @virtual_id )
  2129.             BEGIN
  2130.                 RAISERROR (20012, 16, -1)
  2131.                 GOTO UNDO
  2132.             END
  2133.  
  2134.             
  2135.             /* Update the publication type */
  2136.             UPDATE syspublications 
  2137.                 SET allow_push = @value_bit
  2138.                 WHERE pubid = @pubid
  2139.             IF @@error <> 0
  2140.             BEGIN
  2141.                GOTO UNDO
  2142.             END
  2143.         END
  2144.  
  2145.         IF LOWER(@property) = 'allow_pull'
  2146.         BEGIN
  2147.            /* 
  2148.            ** If turn it off, make sure there's no pull subscriptions left
  2149.            */
  2150.            IF @value_bit = 0 AND
  2151.             EXISTS (SELECT * FROM syssubscriptions ss, sysarticles sa
  2152.                     WHERE ss.artid = sa.artid
  2153.                     AND   sa.pubid = @pubid
  2154.                     AND      ss.subscription_type = @pull
  2155.                     AND   ss.srvid <> @virtual_id )
  2156.             BEGIN
  2157.                 RAISERROR (20013, 16, -1, @property)
  2158.                 GOTO UNDO
  2159.             END
  2160.             /* Update the publication type */
  2161.             UPDATE syspublications 
  2162.                 SET allow_pull = @value_bit
  2163.                 WHERE pubid = @pubid
  2164.             IF @@error <> 0
  2165.             BEGIN
  2166.                GOTO UNDO
  2167.             END
  2168.         END
  2169.  
  2170.     END
  2171.  
  2172.     /* Update publication property at the distributor side if necessary */
  2173.     IF LOWER(@property) IN ('description', 'repl_freq', 'independent_agent',
  2174.         'immediate_sync', 'allow_push',
  2175.         'allow_pull', 'allow_anonymous','retention')
  2176.     BEGIN
  2177.         /* Translate the property names and values  */
  2178.         IF LOWER(@property) = 'repl_freq'
  2179.         BEGIN
  2180.             SELECT @property = 'publication_type'
  2181.             SELECT @value = STR(@replfreqid)
  2182.         END
  2183.  
  2184.         /* Translate values */
  2185.         IF LOWER(@value) = 'true'
  2186.             SELECT @value = '1'
  2187.         ELSE IF LOWER(@value) = 'false'
  2188.             SELECT @value = '0'
  2189.  
  2190.         /*
  2191.         ** Get distribution server information for remote RPC call.
  2192.         */
  2193.         EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  2194.            @distribdb   = @distribdb OUTPUT
  2195.         IF @@ERROR <> 0 or @retcode <> 0
  2196.             BEGIN
  2197.                 GOTO UNDO
  2198.             END
  2199.  
  2200.         SELECT @dbname =  DB_NAME()
  2201.         
  2202.         SELECT @distproc = RTRIM(@distributor) + '.' + @distribdb + 
  2203.             '.dbo.sp_MSchange_publication'
  2204.     
  2205.         EXECUTE @retcode = @distproc
  2206.             @publisher = @@SERVERNAME,
  2207.             @publisher_db = @dbname,
  2208.             @publication = @publication,
  2209.             @property = @property,
  2210.             @value = @value
  2211.  
  2212.         IF @@ERROR <> 0 OR @retcode <> 0
  2213.         BEGIN
  2214.             GOTO UNDO
  2215.         END
  2216.     END
  2217.     
  2218.     IF @add_virtual_back = 1    
  2219.     BEGIN
  2220.         /* Add virtual subscriptions back*/
  2221.         EXEC @retcode = dbo.sp_addsubscription 
  2222.             @publication = @publication, 
  2223.             @article = 'all',
  2224.             @subscriber = NULL,
  2225.             @destination_db = 'virtual',
  2226.             @sync_type = 'automatic',
  2227.             @status = NULL, 
  2228.             @reserved = 'internal'
  2229.         IF @@ERROR <> 0 OR @retcode <> 0
  2230.         BEGIN
  2231.             GOTO UNDO                    
  2232.         END
  2233.     END
  2234.  
  2235.     COMMIT TRAN
  2236.  
  2237.  
  2238.     /*
  2239.     ** Return succeed.
  2240.     */
  2241.  
  2242.     RAISERROR (14077, 10, -1)
  2243.     RETURN (0)
  2244.  
  2245. UNDO:
  2246.     IF @@TRANCOUNT > 0
  2247.     begin 
  2248.         ROLLBACK TRAN sp_changepublication
  2249.         COMMIT TRAN
  2250.     end
  2251. GO
  2252.  
  2253. EXEC dbo.sp_MS_marksystemobject sp_changepublication
  2254. GO
  2255.  
  2256. print ''
  2257. print 'Creating procedure sp_changesubscription'
  2258. GO
  2259. /* This function should be disallowed */
  2260. CREATE PROCEDURE sp_changesubscription (
  2261.     @publication sysname = NULL,        /* Publication name */
  2262.     @article sysname = NULL,            /* Article name */
  2263.     @subscriber sysname,              /* Subscriber name */
  2264.     @property nvarchar(15) = NULL,           /* The property to change */
  2265.     @value nvarchar(255) = NULL              /* The new property value */
  2266.     ) AS
  2267.  
  2268.     SET NOCOUNT ON
  2269.     RAISERROR (21023, 16, -1,'sp_changesubscription')
  2270.     RETURN(1)
  2271. go
  2272.  
  2273. dump tran master with no_log
  2274. go
  2275.  
  2276. EXEC dbo.sp_MS_marksystemobject sp_changesubscription
  2277. GO
  2278.  
  2279.  
  2280. print ''
  2281. print 'Creating procedure sp_helparticle'
  2282. go
  2283.  
  2284. CREATE PROCEDURE sp_helparticle (
  2285.     @publication sysname,         /* The publication name */
  2286.     @article sysname = '%',       /* The article name */
  2287.     @returnfilter bit = 1         /* Return filter flag */
  2288.     ) AS
  2289.  
  2290.     SET NOCOUNT ON
  2291.  
  2292.     /*
  2293.     ** Declarations.
  2294.     */
  2295.  
  2296.     DECLARE @pubid int
  2297.     DECLARE @retcode int
  2298.     DECLARE @subscriber_bit smallint
  2299.     DECLARE @publish_bit int
  2300.     DECLARE @source_object  sysname
  2301.     DECLARE @source_owner   sysname
  2302.     
  2303.     SELECT @publish_bit = 1
  2304.  
  2305.     /*
  2306.     ** Security Check. To public.
  2307.     
  2308.     */
  2309.     /*
  2310.     ** Check if the database is published.
  2311.     */
  2312.     IF NOT EXISTS (SELECT * FROM master..sysdatabases
  2313.         WHERE name = db_name()
  2314.         AND (category & @publish_bit) = @publish_bit)
  2315.         RETURN(0)
  2316.  
  2317.     /*
  2318.     ** Initializations.
  2319.     */
  2320.  
  2321.     SELECT @subscriber_bit = 4
  2322.  
  2323.     IF @publication IS NOT NULL
  2324.         SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  2325.  
  2326.     /*
  2327.     ** Create a temporary table to hold all information.
  2328.     */
  2329.  
  2330.     CREATE TABLE #tab1 (
  2331.         artid               int             NOT NULL,
  2332.         columns             varbinary(32)   NOT NULL,
  2333.         creation_script     nvarchar(255)   NULL,
  2334.         del_cmd             nvarchar(255)   NULL,
  2335.         description         nvarchar(255)   NULL,
  2336.         dest_table          sysname         NULL,
  2337.         old_filter          int             NULL,
  2338.         ins_cmd             nvarchar(255)   NULL,
  2339.         name                sysname         NOT NULL,
  2340.         objid               int             NOT NULL,
  2341.         pubid               int             NOT NULL,
  2342.         status              tinyint         NOT NULL,
  2343.         sync_objid          int             NOT NULL,
  2344.         type                tinyint         NOT NULL,
  2345.         upd_cmd             nvarchar(255)   NULL,
  2346.         source_table        nvarchar(257)   NULL,      /* converted from objid */
  2347.         filter              nvarchar(257)   NULL,      /* converted from old_filter */
  2348.         sync_object         nvarchar(257)   NULL,      /* converted from sync_objid */
  2349.         vpartition          bit             NOT NULL,   /* computed */
  2350.         pre_creation_cmd    tinyint     NOT NULL,
  2351.         filter_clause       ntext           NULL,
  2352.         schema_option       binary(8)       NULL,
  2353.         dest_owner          sysname         NULL,
  2354.         source_owner        sysname         NULL,   /* these two columns are for 7.0 use only */
  2355.         unqua_source_object sysname         NULL,   /* column source_table stays due to backward compatibility */
  2356.         sync_object_owner   sysname         NULL,
  2357.         unqua_sync_object   sysname         NULL,
  2358.         filter_owner        sysname         NULL,
  2359.         unqua_filter        sysname         NULL
  2360.     )
  2361.  
  2362.     CREATE UNIQUE INDEX idx1 ON #tab1 (name, pubid)
  2363.  
  2364.     /*
  2365.     ** Parameter Check:  @publication.
  2366.     ** Check to make sure that there are some articles
  2367.     ** to display.
  2368.     */
  2369.  
  2370.     IF @publication IS NULL
  2371.         BEGIN
  2372.             RAISERROR (14043, 16, -1, '@publication')
  2373.             RETURN (1)
  2374.         END
  2375.  
  2376.     EXECUTE @retcode = dbo.sp_validname @publication
  2377.  
  2378.     IF @retcode <> 0
  2379.     RETURN (1)
  2380.  
  2381.     IF NOT EXISTS (SELECT * FROM syspublications WHERE name = @publication)
  2382.         BEGIN
  2383.             RAISERROR (20026, 11, -1, @publication)
  2384.             RETURN (1)
  2385.         END
  2386.  
  2387.     /*
  2388.     ** Parameter Check:  @article.
  2389.     ** Check to make sure that the article exists, that it conforms
  2390.     ** to the rules for identifiers, and that it isn't NULL.
  2391.     */
  2392.  
  2393.     IF @article IS NULL
  2394.         BEGIN
  2395.             RAISERROR (14043, 16, -1, '@article')
  2396.             RETURN (1)
  2397.         END
  2398.  
  2399.     IF @article <> '%'
  2400.         BEGIN
  2401.  
  2402.             /*
  2403.             EXECUTE @retcode = dbo.sp_validname @article
  2404.  
  2405.             IF @retcode <> 0
  2406.             RETURN (1)
  2407.             */
  2408.  
  2409.             IF NOT EXISTS (SELECT *
  2410.                              FROM sysarticles
  2411.                             WHERE name = @article
  2412.                               AND pubid IN (SELECT pubid
  2413.                                               FROM syspublications
  2414.                                              WHERE name = @publication))
  2415.                 BEGIN
  2416.                     RAISERROR (20027, 11, -1, @article)
  2417.                     RETURN (1)
  2418.                 END
  2419.  
  2420.         END
  2421.  
  2422.         
  2423.     IF @returnfilter = 1
  2424.     BEGIN
  2425.         INSERT INTO #tab1 (artid, columns, creation_script, del_cmd,
  2426.                            description, dest_table, old_filter,
  2427.                            ins_cmd, name, objid, pubid, status,
  2428.                            sync_objid, type, upd_cmd, source_table,
  2429.                            filter, vpartition, pre_creation_cmd,
  2430.                filter_clause, schema_option, dest_owner, source_owner, unqua_source_object, 
  2431.                sync_object_owner, unqua_sync_object, filter_owner, unqua_filter)
  2432.                
  2433.          (SELECT artid, columns, creation_script, del_cmd, a.description,
  2434.                  dest_table, filter, ins_cmd, a.name, objid, a.pubid,
  2435.                  a.status, sync_objid, a.type, upd_cmd, NULL, NULL, 0,
  2436.                 a.pre_creation_cmd, a.filter_clause, a.schema_option, a.dest_owner, 
  2437.                 user_name(o.uid), o.name, 
  2438.                 user_name(sync.uid), sync.name,
  2439.                 user_name(fltr.uid), fltr.name
  2440.             FROM syspublications b, sysobjects o, sysobjects sync, sysarticles a LEFT JOIN sysobjects fltr on a.filter = fltr.id
  2441.            WHERE a.name LIKE @article
  2442.              AND a.objid = o.id
  2443.              AND a.sync_objid = sync.id
  2444.              AND a.pubid = b.pubid
  2445.              AND b.name = @publication)
  2446.     END
  2447.     ELSE
  2448.     BEGIN
  2449.         INSERT INTO #tab1 (artid, columns, creation_script, del_cmd,
  2450.                            description, dest_table, old_filter,
  2451.                            ins_cmd, name, objid, pubid, status,
  2452.                            sync_objid, type, upd_cmd, source_table,
  2453.                            filter, vpartition, pre_creation_cmd,
  2454.                filter_clause, schema_option, dest_owner, source_owner, unqua_source_object, 
  2455.                sync_object_owner, unqua_sync_object, filter_owner, unqua_filter)
  2456.          (SELECT artid, columns, creation_script, del_cmd, a.description,
  2457.                  dest_table, filter, ins_cmd, a.name, objid, a.pubid,
  2458.                  a.status, sync_objid, a.type, upd_cmd, NULL, NULL, 0,
  2459.                  a.pre_creation_cmd, NULL, schema_option, dest_owner, 
  2460.                  user_name(o.uid), o.name,
  2461.                  user_name(sync.uid), sync.name,
  2462.                  user_name(fltr.uid), fltr.name
  2463.            FROM syspublications b, sysobjects o, sysobjects sync, sysarticles a LEFT JOIN sysobjects fltr on a.filter = fltr.id
  2464.            WHERE a.name LIKE @article
  2465.              AND a.objid = o.id
  2466.              AND a.sync_objid = sync.id
  2467.              AND a.pubid = b.pubid
  2468.              AND b.name = @publication)
  2469.     END
  2470.  
  2471.     UPDATE #tab1
  2472.        SET source_table = QUOTENAME(u.name) + '.' + QUOTENAME(o.name)
  2473.       FROM #tab1, sysobjects o, sysusers u
  2474.      WHERE o.id = #tab1.objid
  2475.        AND o.uid = u.uid
  2476.  
  2477.     UPDATE #tab1
  2478.         SET unqua_sync_object = sysobjects.name
  2479.         from sysobjects 
  2480.         where sysobjects.id = sync_objid
  2481.  
  2482.     UPDATE #tab1
  2483.        SET sync_object = QUOTENAME(sysusers.name) + '.' + QUOTENAME(sysobjects.name)
  2484.       FROM sysobjects, sysusers
  2485.      WHERE sysobjects.id = sync_objid
  2486.        AND sysobjects.uid = sysusers.uid
  2487.  
  2488.     UPDATE #tab1 SET filter = (SELECT sysusers.name + '.' + sysobjects.name
  2489.                                  FROM sysobjects, sysusers
  2490.                                 WHERE sysobjects.id = #tab1.old_filter
  2491.                                   AND sysobjects.uid = sysusers.uid)
  2492.       FROM #tab1
  2493.  
  2494.     DECLARE hC  CURSOR LOCAL FAST_FORWARD FOR SELECT name, pubid FROM #tab1
  2495.     OPEN hC
  2496.     FETCH hC INTO @article, @pubid
  2497.     WHILE (@@fetch_status <> -1)
  2498.         BEGIN
  2499.             IF EXISTS (SELECT *
  2500.                          FROM sysarticles a, syscolumns b
  2501.                          WHERE 
  2502.                           ( 
  2503.                            convert(bit, convert( varbinary, substring( convert( nvarchar, a.columns ), 16 - floor((colid-1)/16),1 )) & power( 2, ((colid-1)%16))) = 0
  2504.                            OR convert(bit, convert( varbinary, substring( convert( nvarchar, a.columns ), 16 - floor((colid-1)/16),1 )) & power( 2, ((colid-1)%16))) IS NULL
  2505.                           )
  2506.                           AND a.objid = b.id
  2507.                           AND a.name = @article
  2508.                           AND a.pubid = @pubid)
  2509.  
  2510.                 UPDATE #tab1
  2511.                    SET vpartition = 1
  2512.                  WHERE name = @article
  2513.                    AND pubid = @pubid
  2514.  
  2515.             FETCH hC INTO @article, @pubid
  2516.         END
  2517.     CLOSE hC
  2518.     DEALLOCATE hC
  2519.  
  2520.     IF @returnfilter = 1
  2521.         SELECT 'article id'                = artid,
  2522.            'article name'              = name,
  2523.            'base object'                = source_table,
  2524.            'destination object'         = dest_table,
  2525.            'synchronization object'    = sync_object,
  2526.            'type'                      = type,
  2527.            'status'                    = status,
  2528.            'filter'                    = filter,
  2529.            'description'               = description,
  2530.            'insert_command'            = ins_cmd,
  2531.            'update_command'            = upd_cmd,
  2532.            'delete_command'            = del_cmd,
  2533.            'creation script path'      = creation_script,
  2534.            'vertical partition'        = vpartition,
  2535.            'pre_creation_cmd'       = pre_creation_cmd,
  2536.            'filter_clause'           = filter_clause,
  2537.            'schema_option'            = schema_option,
  2538.            'dest_owner'             = dest_owner,
  2539.            'source_owner'           = source_owner,
  2540.            'unqua_source_object'    = unqua_source_object,
  2541.            'sync_object_owner'      = sync_object_owner,
  2542.            'unqualified_sync_object' = unqua_sync_object,
  2543.            'filter_owner'           = filter_owner,
  2544.            'unqua_filter'           = unqua_filter
  2545.           FROM #tab1
  2546.          ORDER BY 2
  2547.     ELSE
  2548.         SELECT 'article id'                = artid,
  2549.            'article name'                   = name,
  2550.            'base object'                 = source_table,
  2551.            'destination object'          = dest_table,
  2552.            'synchronization object'      = sync_object,
  2553.            'type'                          = type,
  2554.            'status'                     = status,
  2555.            'filter'                        = filter,
  2556.            'description'                   = description,
  2557.            'insert_command'              = ins_cmd,
  2558.            'update_command'              = upd_cmd,
  2559.            'delete_command'              = del_cmd,
  2560.            'creation script path'        = creation_script,
  2561.            'vertical partition'          = vpartition,
  2562.            'pre_creation_cmd'            = pre_creation_cmd,
  2563.            'filter_clause'                = NULL,
  2564.            'schema_option'                = schema_option,
  2565.            'dest_owner'                 = dest_owner,
  2566.            'source_owner'               = source_owner,
  2567.            'unqualified_source_object'  = unqua_source_object,
  2568.            'sync_object_owner'      = sync_object_owner,
  2569.            'unqualified_sync_object' = unqua_sync_object,
  2570.            'filter_owner'           = filter_owner,
  2571.            'unqualified_filter'         = unqua_filter
  2572.            
  2573.        FROM #tab1
  2574.          ORDER BY 2
  2575.     RETURN (0)
  2576. go
  2577.  
  2578. dump tran master with no_log
  2579. go
  2580.  
  2581. EXEC dbo.sp_MS_marksystemobject sp_helparticle
  2582. GO
  2583.  
  2584. print ''
  2585. print 'Creating procedure sp_articlecolumn'
  2586. go
  2587. CREATE PROCEDURE sp_articlecolumn (
  2588.         @publication sysname,           /* The publication name */
  2589.         @article sysname,               /* The article name */
  2590.         @column sysname = NULL,         /* The column name */
  2591.         @operation nvarchar(4) = 'add'      /* Add or delete a column */
  2592.         -- synctran
  2593.         , @refresh_synctran_procs bit = 1      -- refresh synctran procs or not
  2594.         , @ignore_distributor bit = 0
  2595.         ) AS
  2596.  
  2597.     /*
  2598.     ** Declarations.
  2599.     */
  2600.  
  2601.     DECLARE @bit tinyint                /* Bit offset */
  2602.     --DECLARE @byte tinyint               /* Byte offset */
  2603.     DECLARE @word tinyint               /* word offset */
  2604.     DECLARE @cnt tinyint, @idx tinyint  /* Loop counter, index */
  2605.     DECLARE @columns binary(32)         /* Temporary storage for the converted column */
  2606.     DECLARE @mask binary(2)              /* Bit mask to set the bit on */
  2607.     DECLARE @mval int
  2608. --    DECLARE @newbyte binary(1)          /* New byte to replace old byte with */
  2609. --    DECLARE @oldbyte binary(1)          /* Temporary storage for original byte */
  2610.     DECLARE @newword binary(2)
  2611.     DECLARE @oldword binary(2)
  2612.     DECLARE @pubid int                  /* Publication identification number */
  2613.     DECLARE @retcode int                /* Return code for stored procedures */
  2614. --    DECLARE @zero binary(32)            /* Constant:  0 */
  2615.     DECLARE @artid int
  2616.     DECLARE @inactive tinyint
  2617.     DECLARE @objid int            /* Article base table id */    
  2618.     DECLARE @tablename  sysname
  2619.  
  2620.     select @inactive = 0
  2621.  
  2622.     /*
  2623.     ** Security Check
  2624.     */
  2625.     exec @retcode = dbo.sp_MSreplcheck_publish
  2626.     if @@ERROR <> 0 or @retcode <> 0
  2627.         return(1)
  2628.  
  2629.     /*
  2630.     ** Check to see if the database has been activated for publication.
  2631.     ** Do not check if @ignore_distributor indicates brute force cleanup.
  2632.     */
  2633.  
  2634.     IF ( (SELECT category & 1
  2635.           FROM master..sysdatabases
  2636.          WHERE name = DB_NAME()) = 0 )  and ( @ignore_distributor = 0 )
  2637.  
  2638.     BEGIN
  2639.             RAISERROR (14013, 16, -1)
  2640.         RETURN (1)
  2641.     END
  2642.  
  2643.     /*
  2644.     ** Parameter Check:  @publication.
  2645.     ** Make sure that the publication exists and that it conforms to the
  2646.     ** rules for identifiers.
  2647.     */
  2648.  
  2649.     IF @publication IS NULL
  2650.         BEGIN
  2651.             RAISERROR (14043, 16, -1, '@publication')
  2652.             RETURN (1)
  2653.         END
  2654.  
  2655.     EXECUTE @retcode = dbo.sp_validname @publication
  2656.  
  2657.     IF @retcode <> 0
  2658.             RETURN (1)
  2659.  
  2660.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  2661.  
  2662.     IF @pubid IS NULL
  2663.         BEGIN
  2664.             RAISERROR (20026, 11, -1, @publication)
  2665.             RETURN (1)
  2666.         END
  2667.     ELSE
  2668.  
  2669.     /*
  2670.     ** Parameter Check:  @article.
  2671.     ** Check to make sure that the article exists in the publication.
  2672.     */
  2673.  
  2674.     IF @article IS NULL
  2675.         BEGIN
  2676.             RAISERROR (14043, 16, -1, '@article')
  2677.             RETURN (1)
  2678.         END
  2679.  
  2680.     /*
  2681.     EXECUTE @retcode = dbo.sp_validname @article
  2682.  
  2683.     IF @@ERROR <> 0 OR @retcode <> 0
  2684.     RETURN (1)
  2685.     */
  2686.  
  2687.     /*
  2688.     ** Make sure the article exists.
  2689.     */
  2690.     SELECT @artid = artid FROM sysarticles
  2691.        WHERE pubid = @pubid AND name = @article
  2692.     IF @artid IS NULL
  2693.         BEGIN
  2694.             RAISERROR (20027, 11, -1, @article)
  2695.             RETURN (1)
  2696.         END
  2697.  
  2698.     /*
  2699.     ** Only unsubscribed articles may be modified. (excluding virtual subscriptions)
  2700.     */
  2701.     IF EXISTS (SELECT * FROM syssubscriptions WHERE artid = @artid
  2702.        AND status <> @inactive
  2703.        AND srvid >= 0)
  2704.         BEGIN
  2705.             RAISERROR (14092, 11, -1)
  2706.             RETURN (1)
  2707.         END
  2708.  
  2709.     /*
  2710.     ** Error out if this is a not a table based article
  2711.     */
  2712.     IF NOT EXISTS ( SELECT * FROM sysarticles WHERE artid = @artid
  2713.                       AND pubid = @pubid
  2714.                       AND (type & 1) = 1 )
  2715.         BEGIN
  2716.             RAISERROR (14112, 11, -1 )
  2717.             RETURN (1)
  2718.         END
  2719.  
  2720.     /*
  2721.     ** Parameter Check:  @column.
  2722.     ** Check to make sure that the column exists and conforms to the rules
  2723.     ** for identifiers.
  2724.     */
  2725.  
  2726.     /*
  2727.     IF @column IS NOT NULL
  2728.         BEGIN
  2729.             EXECUTE @retcode = dbo.sp_validname @column
  2730.             IF @@ERROR <> 0 OR @retcode <> 0
  2731.             RETURN (1)
  2732.         END
  2733.     */
  2734.  
  2735.     /*
  2736.     ** Parameter Check:  @operation.
  2737.     ** The operation can be either 'add' or 'drop'.
  2738.     */
  2739.  
  2740.     IF LOWER(@operation) NOT IN ('add', 'drop')
  2741.         BEGIN
  2742.             RAISERROR (14019, 16, -1)
  2743.             RETURN (1)
  2744.         END
  2745.         
  2746.     SELECT @objid = (SELECT objid FROM sysarticles WHERE artid = @artid)
  2747.     SELECT @tablename = OBJECT_NAME(@objid)
  2748.     
  2749.      if @column is not null
  2750.     begin
  2751.         -- If the publication is allow_sync_tran, we cannot drop the timestamp
  2752.         -- column from the partition.
  2753.         if exists (select * from syspublications where name = @publication and
  2754.             allow_sync_tran = 1) and LOWER(@operation) = 'drop'
  2755.         begin
  2756.             declare @ts_col sysname
  2757.             exec dbo.sp_MSis_col_replicated @publication, @article, 
  2758.                 'timestamp', @ts_col OUTPUT 
  2759.             if @ts_col = @column
  2760.             BEGIN
  2761.                 if @@trancount > 0
  2762.                 begin
  2763.                     ROLLBACK TRANSACTION articlecolumn
  2764.                     commit tran
  2765.                 end
  2766.                 RAISERROR (21080, 16, -1)
  2767.                 RETURN (1)
  2768.             END
  2769.         end
  2770.     end
  2771.  
  2772.     begin tran
  2773.     save TRANSACTION articlecolumn
  2774.  
  2775.     /*
  2776.     ** Make sure that the columns column is not NULL.
  2777.     */
  2778.  
  2779.     IF EXISTS (SELECT *
  2780.                  FROM sysarticles
  2781.                 WHERE name = @article
  2782.                   AND pubid = @pubid
  2783.                   AND columns IS NULL)
  2784.  
  2785.             UPDATE sysarticles
  2786.               SET columns = 0x00
  2787.             WHERE name = @article
  2788.               AND pubid = @pubid
  2789.  
  2790.     /*
  2791.     ** If no columns are specified, or if NULL is specified, set all
  2792.     ** the bits in the 'columns' column so all columns will be included.
  2793.     */
  2794.  
  2795.     IF @column IS NULL
  2796.     BEGIN
  2797.        DECLARE hCartcolumn CURSOR LOCAL FAST_FORWARD FOR
  2798.             SELECT name FROM syscolumns where
  2799.                 id = @objid
  2800.     END
  2801.     ELSE
  2802.     BEGIN
  2803.        DECLARE hCartcolumn CURSOR LOCAL FAST_FORWARD FOR 
  2804.             SELECT @column
  2805.     END
  2806.  
  2807.  
  2808.     OPEN hCartcolumn
  2809.  
  2810.     FETCH hCartcolumn INTO @column
  2811.  
  2812.     WHILE (@@fetch_status <> -1)
  2813.     BEGIN
  2814.  
  2815.         DECLARE @columnid smallint   /* Columnid-1 = bit to set */
  2816.  
  2817.         /*
  2818.         ** Get the column id for this column.  We'll use the column id
  2819.         ** to determine the bit in the 'columns' column.  The bit we want
  2820.         ** is equal to the columnid - 1.
  2821.         */
  2822.  
  2823.         SELECT @columnid = colid
  2824.           FROM syscolumns
  2825.          WHERE id = @objid AND name = @column
  2826.  
  2827.         IF ((@@error <> 0) OR (@columnid IS NULL))
  2828.             BEGIN
  2829.                 if @@trancount > 0
  2830.                 begin
  2831.                     ROLLBACK TRANSACTION articlecolumn
  2832.                     commit tran
  2833.                 end
  2834.                 RAISERROR (14020, 16, -1)
  2835.                 RETURN (1)
  2836.             END        
  2837.  
  2838.         /*
  2839.         ** Obtain the byte offset and the bit offset, then set the
  2840.         ** mask column for the bit we want to turn on.
  2841.         */
  2842.  
  2843.         SELECT @word = CONVERT(tinyint, 16 - FLOOR((@columnid-1)/16))
  2844.         SELECT @bit = (@columnid-1) % 16
  2845.  
  2846.         IF LOWER(@operation) = 'add'
  2847.             SELECT @mval = POWER(2, @bit)
  2848.         ELSE
  2849.             SELECT @mval = ~POWER(2, @bit)
  2850.  
  2851.         select @mask = convert( binary(2), substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) )
  2852.  
  2853.         /*
  2854.         ** Save the columns column in a temporary local variable so we
  2855.         ** can twiddle the bit and then put it back into the table.
  2856.         */
  2857.  
  2858.         SELECT @columns = columns
  2859.           FROM sysarticles
  2860.          WHERE name = @article
  2861.            AND pubid = @pubid
  2862.  
  2863.         /*
  2864.         ** Fish out the byte we're interested in and save it in a
  2865.         ** a temporary local variable.  If it's NULL, just set it
  2866.         ** to 0.  Then apply the bitwise operator OR to twiddle the
  2867.         ** bit in the old byte and save it in another temporary
  2868.         ** local variable @newbyte.
  2869.         */
  2870.         SELECT @oldword = CONVERT( binary(2), SUBSTRING( CONVERT( nvarchar,@columns), @word, 1) )
  2871.  
  2872.         IF @oldword IS NULL SELECT @oldword = 0x0000
  2873.  
  2874.         IF LOWER(@operation) = 'add'
  2875.             SELECT @newword = CONVERT(binary(2), convert(smallint, @oldword) | @mask)
  2876.         ELSE
  2877.             SELECT @newword = CONVERT(binary(2), convert(smallint, @oldword ) & @mask)
  2878.  
  2879.         SELECT @columns = CONVERT(binary(32), STUFF( convert(nchar(16),@columns), @word, 1, convert( nchar(1), @newword)))
  2880.         SELECT @idx = @idx + 1
  2881.  
  2882.        IF LOWER(@operation) = 'drop'
  2883.        BEGIN
  2884.  
  2885.            /* Update Text\Image column status as not published */
  2886.           EXECUTE @retcode = dbo.sp_MSarticletextcol @artid, @columnid,
  2887.              'publish', @operation
  2888.           IF (@@error <> 0 OR @retcode <> 0)
  2889.           BEGIN
  2890.             if @@trancount > 0
  2891.             begin
  2892.                 ROLLBACK TRANSACTION articlecolumn
  2893.                 commit tran
  2894.             end
  2895.              RAISERROR (14021, 16, -1)
  2896.              RETURN (1)
  2897.           END
  2898.        END
  2899.  
  2900.         /*
  2901.         ** Update the sysarticles table.  Set the bit to 1 for the
  2902.         ** selected column.
  2903.         */
  2904.  
  2905.         UPDATE sysarticles
  2906.            SET columns = @columns
  2907.          WHERE name = @article
  2908.            AND pubid = @pubid
  2909.  
  2910.         IF @@error <> 0
  2911.             BEGIN
  2912.                 if @@trancount > 0
  2913.                 begin
  2914.                     ROLLBACK TRANSACTION articlecolumn
  2915.                     commit tran
  2916.                 end
  2917.                 RAISERROR (14021, 16, -1)
  2918.                 RETURN (1)
  2919.             END
  2920.  
  2921.        IF LOWER(@operation) = 'add'
  2922.        BEGIN
  2923.  
  2924.            /* Update Text\Image column status as not published */
  2925.           EXECUTE @retcode = dbo.sp_MSarticletextcol @artid, @columnid,
  2926.              'publish', @operation
  2927.           IF (@@error <> 0 OR @retcode <> 0)
  2928.           BEGIN
  2929.             if @@trancount > 0
  2930.             begin
  2931.                 ROLLBACK TRANSACTION articlecolumn
  2932.                 commit tran
  2933.             end
  2934.              RAISERROR (14021, 16, -1)
  2935.              RETURN (1)
  2936.           END
  2937.  
  2938.        END
  2939.        FETCH hCartcolumn INTO @column
  2940.     END
  2941.  
  2942.     -- Synctran
  2943.     /*
  2944.     ** If publication is enabled for Synctran and sprocs are auto-generated - regenerate them
  2945.     */
  2946.     declare @autogen_sync_procs_id bit
  2947.     declare @ins_proc_id int, @upd_proc_id int, @del_proc_id int
  2948.     declare @ins_proc sysname, @upd_proc sysname, @del_proc sysname, @owner sysname, @objname sysname
  2949.     declare @sync_pubid int
  2950.     declare @cmd nvarchar(4000)
  2951.  
  2952.     select @autogen_sync_procs_id = autogen_sync_procs, @sync_pubid = pubid
  2953.     from syspublications where name = @publication
  2954.  
  2955.     if  @autogen_sync_procs_id = 1 and @refresh_synctran_procs = 1 
  2956.     begin
  2957.         -- Drop existing synctran procs
  2958.         select @owner = user_name(OBJECTPROPERTY(objid, 'OwnerId')) from sysarticles a, syspublications p
  2959.         where a.name = @article and
  2960.               p.name = @publication and
  2961.               a.pubid = p.pubid
  2962.  
  2963.         select @ins_proc_id = sync_ins_proc, @upd_proc_id = sync_upd_proc, @del_proc_id = sync_del_proc
  2964.         from sysarticleupdates
  2965.         where pubid = @pubid and artid = @artid
  2966.  
  2967.         if @ins_proc_id is not null
  2968.         begin
  2969.             select @objname = object_name(@ins_proc_id)     
  2970.             exec @retcode = dbo.sp_MSdrop_object
  2971.                 @object_name = @objname,
  2972.                 @object_owner = @owner
  2973.             if @@error <> 0 or @retcode <> 0
  2974.                 return (1)
  2975.         end
  2976.  
  2977.         if @upd_proc_id is not null
  2978.         begin
  2979.             select @objname = object_name(@upd_proc_id)     
  2980.             exec @retcode = dbo.sp_MSdrop_object
  2981.                 @object_name = @objname,
  2982.                 @object_owner = @owner
  2983.             if @@error <> 0 or @retcode <> 0
  2984.                 return (1)
  2985.         end
  2986.  
  2987.         if @del_proc_id is not null
  2988.         begin
  2989.             select @objname = object_name(@del_proc_id)     
  2990.             exec @retcode = dbo.sp_MSdrop_object
  2991.                 @object_name = @objname,
  2992.                 @object_owner = @owner
  2993.             if @@error <> 0 or @retcode <> 0
  2994.                 return (1)
  2995.         end
  2996.  
  2997.         -- Now generate new ones        
  2998.         select @ins_proc = 'sp_MSsync_ins_' + SUBSTRING(RTRIM(@article), 1, 100) + '_' + rtrim(convert(varchar, @sync_pubid))
  2999.         select @upd_proc = 'sp_MSsync_upd_' + SUBSTRING(RTRIM(@article), 1, 100) + '_' + rtrim(convert(varchar, @sync_pubid))
  3000.         select @del_proc = 'sp_MSsync_del_' + SUBSTRING(RTRIM(@article), 1, 100) + '_' + rtrim(convert(varchar, @sync_pubid))
  3001.  
  3002.         -- check uniqueness of names and revert to ugly guid-based name if friendly name already exists
  3003.         if exists (select name from sysobjects where name in (@ins_proc, @upd_proc, @del_proc))
  3004.         begin
  3005.             declare @guid_name nvarchar(36)
  3006.             select @guid_name =  convert (nvarchar(36), newid())
  3007.             -- remove '-' from guid name because rpc can't handle '-'
  3008.             select @guid_name = replace (@guid_name,'-','_')
  3009.             select @ins_proc = 'sp_MSsync_ins_' + @guid_name
  3010.             select @upd_proc = 'sp_MSsync_upd_' + @guid_name
  3011.             select @del_proc = 'sp_MSsync_del_' + @guid_name
  3012.         end
  3013.  
  3014.         if @ins_proc IS NULL
  3015.         begin
  3016.             if @@trancount > 0
  3017.                 ROLLBACK TRANSACTION 
  3018.             RAISERROR (14043, 11, -1, '@ins_proc')
  3019.             RETURN (1)
  3020.         end
  3021.  
  3022.         if @upd_proc IS NULL
  3023.         begin
  3024.             if @@trancount > 0
  3025.                 ROLLBACK TRANSACTION 
  3026.             RAISERROR (14043, 11, -1, '@upd_proc')
  3027.             RETURN (1)
  3028.         end
  3029.  
  3030.         if @del_proc IS NULL
  3031.         begin
  3032.             if @@trancount > 0
  3033.                 ROLLBACK TRANSACTION 
  3034.             RAISERROR (14043, 11, -1, '@del_proc')
  3035.             RETURN (1)
  3036.         end
  3037.  
  3038.         exec @retcode = dbo.sp_MSgen_sync_tran_procs @publication, @article, @ins_proc, @upd_proc, @del_proc
  3039.  
  3040.         IF @@ERROR <> 0 OR @retcode <> 0
  3041.         BEGIN
  3042.             if @@trancount > 0
  3043.             begin
  3044.                 ROLLBACK TRAN articlecolumn
  3045.                 commit tran
  3046.             end
  3047.             RETURN (1)
  3048.         END
  3049.  
  3050.         --retrieve sproc id's, fail if they don't exist
  3051.         SELECT @ins_proc_id = id FROM sysobjects WHERE name = @ins_proc
  3052.         SELECT @upd_proc_id = id FROM sysobjects WHERE name = @upd_proc
  3053.         SELECT @del_proc_id = id FROM sysobjects WHERE name = @del_proc
  3054.  
  3055.         IF (@ins_proc_id IS NULL) OR (@upd_proc_id IS NULL) OR (@del_proc_id IS NULL)
  3056.         BEGIN
  3057.             if @ins_proc_id IS NULL RAISERROR (20500, 16, 1, @ins_proc)
  3058.             if @upd_proc_id IS NULL RAISERROR (20500, 16, 1, @upd_proc)
  3059.             if @del_proc_id IS NULL RAISERROR (20500, 16, 1, @del_proc)
  3060.             if @@trancount > 0
  3061.             begin
  3062.                 ROLLBACK tran articlecolumn
  3063.                 commit tran
  3064.             end
  3065.             RETURN (1)
  3066.         END
  3067.  
  3068.         -- perform update in sysarticleupdates
  3069.         update sysarticleupdates set sync_ins_proc = @ins_proc_id, sync_upd_proc = @upd_proc_id, 
  3070.             sync_del_proc = @del_proc_id
  3071.         where pubid = @pubid and artid = @artid
  3072.  
  3073.         IF @@ERROR <> 0
  3074.         BEGIN
  3075.             RAISERROR (20501, 16, -1)
  3076.             if @@trancount > 0
  3077.             begin
  3078.                 ROLLBACK tran articlecolumn
  3079.                 commit tran
  3080.             end
  3081.             RETURN (1)
  3082.          END
  3083.     end
  3084.     -- end synctran
  3085.  
  3086.     /*
  3087.     ** Force the article cache to be refreshed with the new definition.
  3088.     ** Nothing to flush if brute force cleanup.
  3089.     */
  3090.     if ( @ignore_distributor = 0 )
  3091.         EXECUTE dbo.sp_replflush
  3092.  
  3093.     COMMIT TRANSACTION
  3094.  
  3095.  
  3096. go
  3097.  
  3098. EXEC dbo.sp_MS_marksystemobject sp_articlecolumn
  3099. GO
  3100.  
  3101. print ''
  3102. print 'Creating procedure sp_helparticlecolumns'
  3103. go
  3104. CREATE PROCEDURE sp_helparticlecolumns (
  3105.     @publication sysname,            /* The publication name */
  3106.     @article    sysname              /* The article name */
  3107.     ) AS
  3108.  
  3109.     /*
  3110.     ** Declarations.
  3111.     */
  3112.  
  3113.     DECLARE @columns binary(32)
  3114.     DECLARE @pubid int
  3115.     DECLARE @retcode int
  3116.  
  3117.     /*
  3118.     ** Security Check. To public.
  3119.     */
  3120.  
  3121.     /*
  3122.     ** Parameter Check: @article.
  3123.     ** The @article name must conform to the rules for identifiers.
  3124.     */
  3125.  
  3126.     IF @article IS NULL
  3127.         BEGIN
  3128.             RAISERROR (14043, 16, -1, '@article')
  3129.             RETURN (1)
  3130.         END
  3131.     
  3132.     /*
  3133.     EXECUTE @retcode = dbo.sp_validname @article
  3134.  
  3135.     IF @retcode <> 0
  3136.     RETURN (1)
  3137.     */
  3138.  
  3139.     /*
  3140.     ** Parameter Check: @publication.
  3141.     ** The @publication name must conform to the rules for identifiers.
  3142.     */
  3143.  
  3144.     IF @publication IS NULL
  3145.         BEGIN
  3146.             RAISERROR (14043, 16, -1, '@publication')
  3147.             RETURN (1)
  3148.         END
  3149.     
  3150.     EXECUTE @retcode = dbo.sp_validname @publication
  3151.  
  3152.     IF @retcode <> 0
  3153.     RETURN (1)
  3154.     
  3155.     /*
  3156.     ** Get the pubid.
  3157.     */
  3158.  
  3159.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  3160.  
  3161.     IF @pubid IS NULL
  3162.         BEGIN
  3163.             RAISERROR (14043, 11, -1, '@pubid')
  3164.             RETURN (1)
  3165.         END
  3166.  
  3167.     /*
  3168.     ** Parameter Check:  @article, @publication.
  3169.     ** Check to make sure that the article exists in this publication.
  3170.     */
  3171.  
  3172.     IF NOT EXISTS (SELECT *
  3173.                      FROM sysarticles
  3174.                     WHERE pubid = @pubid
  3175.                       AND name = @article)
  3176.         BEGIN
  3177.             RAISERROR (20027, 11, -1, @article)
  3178.             RETURN (1)
  3179.         END
  3180.  
  3181.  
  3182.     /*
  3183.     ** Error out if this is a not a table based article
  3184.     */
  3185.     IF NOT EXISTS ( SELECT * FROM sysarticles WHERE name = @article
  3186.                           AND pubid = @pubid
  3187.                           AND (type & 1) = 1 )
  3188.         BEGIN
  3189.             RAISERROR (14112, 11, -1 )
  3190.             RETURN (1)
  3191.         END
  3192.  
  3193.  
  3194.     SELECT @columns = columns
  3195.       FROM sysarticles
  3196.      WHERE name = @article
  3197.        AND pubid = @pubid
  3198.  
  3199.     SELECT 'column id' = colid,
  3200.            'column'    = name,
  3201.        'published' = convert(bit, convert( varbinary, substring( convert( nvarchar, @columns ), 16 - floor((colid-1)/16),1 )) & power( 2, ((colid-1)%16)))
  3202.       FROM syscolumns
  3203.      WHERE id = (SELECT objid
  3204.                    FROM sysarticles
  3205.                   WHERE name = @article
  3206.                     AND pubid = @pubid)
  3207. go
  3208.  
  3209. EXEC dbo.sp_MS_marksystemobject sp_helparticlecolumns
  3210. GO
  3211.  
  3212. print ''
  3213. print 'Creating procedure sp_helppublication'
  3214. go
  3215.  
  3216.  
  3217. CREATE PROCEDURE sp_helppublication (
  3218.         @publication sysname = '%',     /* The publication name */
  3219.         @found int = 23456 OUTPUT            /* a flag indicate returning row */
  3220.         ) AS
  3221.  
  3222.     SET NOCOUNT ON
  3223.  
  3224.     /*
  3225.     ** Declarations.
  3226.     */
  3227.  
  3228.     DECLARE @pubid      int
  3229.     DECLARE @has_subscription bit
  3230.     DECLARE @retcode int
  3231.     DECLARE @no_row bit
  3232.     DECLARE @publish_bit int
  3233.     
  3234.     SELECT @publish_bit = 1
  3235.     
  3236.     /*
  3237.     ** Check if the database is published.
  3238.     */
  3239.     IF NOT EXISTS (SELECT * FROM master..sysdatabases
  3240.         WHERE name = db_name()
  3241.         AND (category & @publish_bit) = @publish_bit)
  3242.         RETURN(0)
  3243.  
  3244.     /*
  3245.     ** Security Check. To public.
  3246.     */
  3247.  
  3248.     /*
  3249.     ** Initializations.
  3250.     */
  3251.     IF @found = 23456 
  3252.     BEGIN
  3253.         SELECT @no_row=0
  3254.     END
  3255.     ELSE
  3256.     BEGIN
  3257.         SELECT @no_row=1
  3258.     END
  3259.  
  3260.     /*
  3261.     ** Parameter Check:  @publication.
  3262.     ** Check to make sure that there are some publications
  3263.     ** to display.
  3264.     */
  3265.  
  3266.     IF @publication IS NULL
  3267.         BEGIN
  3268.             RAISERROR (14043, 16, -1, '@publication')
  3269.             RETURN (1)
  3270.         END
  3271.     
  3272.     IF @publication <> '%'
  3273.         BEGIN
  3274.             
  3275.             EXECUTE @retcode = dbo.sp_validname @publication
  3276.  
  3277.             IF @retcode <> 0
  3278.             RETURN (1)
  3279.         END
  3280.  
  3281.     IF  NOT EXISTS (SELECT * FROM syspublications
  3282.         WHERE name like @publication)
  3283.  
  3284.     BEGIN
  3285.         SELECT @found = 0
  3286.         RETURN (0) 
  3287.     END
  3288.     ELSE
  3289.     BEGIN
  3290.         SELECT @found = 1
  3291.         IF @no_row <>0
  3292.             RETURN(0)
  3293.     END
  3294.  
  3295.     
  3296.  
  3297.  
  3298.     SELECT 'pubid'                  = pubid,
  3299.            'name'                   = name,
  3300.            'restricted'             = 0,
  3301.            'status'                 = status,
  3302.            -- using 'task' is for backward compatible
  3303.            'task'                   = convert(int, 1),
  3304.            'replication frequency'  = repl_freq,
  3305.            'synchronization method' = sync_method,
  3306.            'description'            = description,
  3307.            'immediate_sync'            = immediate_sync,
  3308.            'enabled_for_internet'    = enabled_for_internet,
  3309.            'allow_push'             = allow_push,
  3310.            'allow_pull'             = allow_pull,
  3311.            'allow_anonymous'        = allow_anonymous,
  3312.            'independent_agent'        = independent_agent,
  3313.            'immediate_sync_ready'    = immediate_sync_ready,
  3314.            -- SyncTran
  3315.            'allow_sync_tran'        = allow_sync_tran,
  3316.            'autogen_sync_procs'        = autogen_sync_procs,
  3317.            'snapshot_jobid'         = snapshot_jobid,
  3318.            'retention'              = retention,
  3319.            'has subscription'       =  case when EXISTS (select * from syssubscriptions where artid in 
  3320.                                         (select artid from sysarticles where pubid in 
  3321.                                         (select inside.pubid from syspublications inside where inside.name = outter.name))) then 1
  3322.                                        else 0 end
  3323.       FROM syspublications outter
  3324.      WHERE name LIKE @publication
  3325.      ORDER BY name
  3326.  
  3327.     RETURN (0)
  3328. go
  3329.  
  3330. EXEC dbo.sp_MS_marksystemobject sp_helppublication
  3331. GO
  3332.  
  3333. -- bug 44359 : sp_helppublication_snapshot not used anymore
  3334.  
  3335. print ''
  3336. print 'Creating procedure sp_helpsubscription'
  3337. go
  3338.  
  3339. CREATE PROCEDURE sp_helpsubscription
  3340.     @publication sysname = '%',    /* The publication name */
  3341.     @article sysname = '%',        /* The article name */
  3342.     @subscriber sysname = N'%',      /* The subscriber name */
  3343.     @destination_db sysname = '%',
  3344.     @found int = 23456 OUTPUT
  3345.     AS
  3346.  
  3347.     SET NOCOUNT ON
  3348.  
  3349.     /*
  3350.     ** Declarations.
  3351.     */
  3352.  
  3353.     DECLARE @retcode int
  3354.     DECLARE @subscriber_bit smallint
  3355.     DECLARE @no_row bit
  3356.     DECLARE @srvid smallint
  3357.     DECLARE @pubid int
  3358.     DECLARE @artid int
  3359.     DECLARE @immediate_sync bit
  3360.     DECLARE @subscription_type_id int
  3361.     DECLARE @sync_typeid int
  3362.     DECLARE @publish_bit int
  3363.     
  3364.     DECLARE @full_subscription bit
  3365.  
  3366.     SELECT @publish_bit = 1
  3367.  
  3368.  
  3369.     /* Security check. To public. */
  3370.  
  3371.     /*
  3372.     ** Check if the database is published.
  3373.     */
  3374.     IF NOT EXISTS (SELECT * FROM master..sysdatabases
  3375.                     WHERE name = db_name()
  3376.                       AND (category & @publish_bit) = @publish_bit)
  3377.         RETURN(0)
  3378.  
  3379.     /*
  3380.     ** Initializations of @now_row.
  3381.     */
  3382.     IF @found = 23456 
  3383.     BEGIN
  3384.         SELECT @no_row=0
  3385.     END
  3386.     ELSE
  3387.     BEGIN
  3388.         SELECT @no_row=1
  3389.     END
  3390.  
  3391.     /*
  3392.     ** Initializations.
  3393.     */
  3394.     SELECT @subscriber_bit = 4
  3395.  
  3396.     /*
  3397.     ** Parameter Check:  @subscriber.
  3398.     */
  3399.     IF @subscriber IS NULL
  3400.         BEGIN
  3401.             RAISERROR (14043, 16, -1, '@subscriber')
  3402.             RETURN (1)
  3403.         END
  3404.  
  3405.     /*
  3406.     ** Parameter Check:  @subscriber.
  3407.     ** Check if remote server is defined as a subscription server, and
  3408.     ** that the name conforms to the rules for identifiers.
  3409.     */
  3410.  
  3411.     IF @subscriber <> '%'
  3412.         BEGIN
  3413.  
  3414.             EXECUTE @retcode = dbo.sp_validname @subscriber
  3415.             select @subscriber = UPPER(@subscriber)
  3416.  
  3417.             IF @retcode <> 0
  3418.         RETURN (1)
  3419.  
  3420.             IF NOT EXISTS (SELECT *
  3421.                              FROM master..sysservers
  3422.                             WHERE UPPER(srvname) = UPPER(@subscriber)
  3423.                               AND (srvstatus & @subscriber_bit) <> 0)
  3424.                 BEGIN
  3425.                     RAISERROR (14010, 16, -1)
  3426.                     RETURN (1)
  3427.                 END
  3428.         END
  3429.  
  3430.     /*
  3431.     ** Parameter Check:  @publication.
  3432.     ** If the publication name is specified, check to make sure that it
  3433.     ** conforms to the rules for identifiers and that the publication
  3434.     ** actually exists.  Disallow NULL.
  3435.     */
  3436.  
  3437.     IF @publication IS NULL
  3438.         BEGIN
  3439.             RAISERROR (14043, 16, -1, '@publication')
  3440.             RETURN (1)
  3441.         END
  3442.  
  3443.     IF @publication <> '%'
  3444.         BEGIN
  3445.  
  3446.             EXECUTE @retcode = dbo.sp_validname @publication
  3447.  
  3448.             IF @retcode <> 0
  3449.                 RETURN (1)
  3450.  
  3451.             IF NOT EXISTS (SELECT * FROM syspublications WHERE name = @publication)
  3452.                 BEGIN
  3453.                    RAISERROR (20026, 11, -1, @publication)
  3454.                    RETURN (1)
  3455.                 END
  3456.  
  3457.         END
  3458.  
  3459.     /*
  3460.     ** Parameter Check:  @article.
  3461.     ** If the article name is specified, check to make sure that it
  3462.     ** conforms to the rules for identifiers and that the article
  3463.     ** actually exists.  Disallow NULL.
  3464.     **
  3465.     ** If @article is 'all', only return one entry for the whole publication
  3466.     ** for full subscriptions (subscriptions inlcluding all the articles in a
  3467.     ** publication).
  3468.     ** 
  3469.     */
  3470.  
  3471.     IF @article IS NULL
  3472.         BEGIN
  3473.             RAISERROR (14043, 16, -1, '@article')
  3474.             RETURN (1)
  3475.         END
  3476.  
  3477.     IF LOWER(@article) <> 'all' 
  3478.     BEGIN
  3479.         IF @article <> '%'
  3480.             BEGIN
  3481.                 
  3482.                 /*
  3483.                 EXECUTE @retcode = dbo.sp_validname @article
  3484.  
  3485.                 IF @retcode <> 0
  3486.                 RETURN (1)
  3487.                 */
  3488.  
  3489.                 IF NOT EXISTS (SELECT *
  3490.                                  FROM sysarticles
  3491.                                 WHERE name = @article
  3492.                                   AND pubid IN (SELECT pubid
  3493.                                                   FROM syspublications
  3494.                                                  WHERE name LIKE @publication))
  3495.                     BEGIN
  3496.                         RAISERROR (20027, 11, -1, @article)
  3497.                         RETURN (1)
  3498.                     END
  3499.  
  3500.             END
  3501.  
  3502.  
  3503.         IF EXISTS (SELECT * 
  3504.               FROM syssubscriptions sub,
  3505.                    master..sysservers ss,
  3506.                    syspublications pub,
  3507.                    sysarticles art
  3508.              WHERE ((@subscriber = N'%') OR (ss.srvname = @subscriber))
  3509.                AND sub.srvid = ss.srvid
  3510.                AND pub.name LIKE @publication
  3511.                AND art.name LIKE @article
  3512.                AND art.pubid = pub.pubid
  3513.                AND sub.artid = art.artid
  3514.                AND sub.dest_db LIKE @destination_db
  3515.                AND (sub.login_name = suser_sname(suser_sid()) OR 
  3516.                     is_srvrolemember('sysadmin') = 1 OR
  3517.                     is_member ('db_owner') = 1)
  3518.                 )
  3519.  
  3520.         BEGIN
  3521.             SELECT @found = 1
  3522.             IF @no_row <> 0 RETURN (0)
  3523.         END
  3524.         ELSE
  3525.         BEGIN
  3526.             SELECT @found = 0
  3527.             RETURN(0)
  3528.         END
  3529.     END
  3530.  
  3531. /*
  3532.         SELECT 'subscriber'           = ss.srvname,
  3533.                'publication'          = pub.name,
  3534.                'article'              = art.name,
  3535.                'destination database' = sub.dest_db,
  3536.                'subscription status'  = sub.status,
  3537.                'synchronization type' = sub.sync_type
  3538.           FROM syssubscriptions sub,
  3539.                master..sysservers ss,
  3540.                syspublications pub,
  3541.                sysarticles art
  3542.          WHERE UPPER(ss.srvname) LIKE UPPER(@subscriber)
  3543.            AND sub.srvid = ss.srvid
  3544.            AND pub.name LIKE @publication
  3545.            AND art.name LIKE @article
  3546.            AND art.pubid = pub.pubid
  3547.            AND sub.artid = art.artid
  3548.            AND (sub.login_name = suser_sname(suser_sid()) OR 
  3549.                     is_srvrolemember('sysadmin') = 1 OR
  3550.                     is_member ('db_owner') = 1)
  3551.                 )
  3552.          ORDER BY subscriber, publication, article
  3553. */    
  3554.  
  3555.     CREATE TABLE #helpsubscription 
  3556.     (
  3557.     /* Info that will be returned */
  3558.     subscriber sysname NOT NULL,
  3559.     publication sysname NOT NULL,
  3560.     article sysname NOT NULL,
  3561.     destination_db sysname NOT NULL,
  3562.     status tinyint NOT NULL,
  3563.     sync_type tinyint NOT NULL,
  3564.     subscription_type int NOT NULL,
  3565.     full_subscription bit NOT NULL, /* full subscription or not */
  3566.     distribution_jobid binary(16) NULL,
  3567.     subscription_name nvarchar(255) NOT NULL,
  3568.     -- SyncTran
  3569.     update_mode int NOT NULL,
  3570.     loopback_detection bit not null
  3571.     )
  3572.  
  3573.  
  3574.     /* Open a CURSOR LOCAL FOR subscriber/destination_db and publication pair 
  3575.     **
  3576.     ** Get subscriptions
  3577.     ** sa or dbo can see every subscriptions while
  3578.     ** others only see their own.
  3579.     */
  3580.  
  3581.     /* 
  3582.     ** Performance Optimization: Eliminate the 'LIKE' clause for publication name.
  3583.     **                           Empirical evidence shows almost 50% speed improvement when
  3584.     **                           opening the cursor if publication name is provided.
  3585.     */
  3586.     IF (@publication <> '%')
  3587.         DECLARE hChelpsubscription_pub CURSOR LOCAL FAST_FORWARD FOR
  3588.             SELECT DISTINCT ss.srvname,
  3589.                    pub.name,
  3590.                    sub.dest_db,
  3591.                    pub.pubid,
  3592.                    sub.srvid,
  3593.                    pub.immediate_sync
  3594.               FROM syssubscriptions sub,
  3595.                    master..sysservers ss,
  3596.                    syspublications pub,
  3597.                    sysarticles art
  3598.              WHERE ((@subscriber = N'%') OR (UPPER(ss.srvname) = UPPER(@subscriber)))
  3599.                AND sub.srvid = ss.srvid
  3600.                AND pub.name = @publication
  3601.                AND art.pubid = pub.pubid
  3602.                AND sub.artid = art.artid
  3603.                AND sub.dest_db LIKE @destination_db
  3604.                AND (sub.login_name = suser_sname(suser_sid()) OR 
  3605.                         is_srvrolemember('sysadmin') = 1 OR
  3606.                         is_member ('db_owner') = 1)       
  3607.                FOR READ ONLY
  3608.     ELSE 
  3609.         DECLARE hChelpsubscription_pub CURSOR LOCAL FAST_FORWARD FOR
  3610.             SELECT DISTINCT ss.srvname,
  3611.                    pub.name,
  3612.                    sub.dest_db,
  3613.                    pub.pubid,
  3614.                    sub.srvid,
  3615.                    pub.immediate_sync
  3616.               FROM syssubscriptions sub,
  3617.                    master..sysservers ss,
  3618.                    syspublications pub,
  3619.                    sysarticles art
  3620.              WHERE ((@subscriber = N'%') OR (UPPER(ss.srvname) = UPPER(@subscriber)))
  3621.                AND sub.srvid = ss.srvid
  3622.                AND art.pubid = pub.pubid
  3623.                AND sub.artid = art.artid
  3624.                AND sub.dest_db LIKE @destination_db
  3625.                AND (sub.login_name = suser_sname(suser_sid()) OR 
  3626.                         is_srvrolemember('sysadmin') = 1 OR
  3627.                         is_member ('db_owner') = 1)       
  3628.                FOR READ ONLY
  3629.  
  3630.     OPEN hChelpsubscription_pub
  3631.     FETCH hChelpsubscription_pub INTO @subscriber, @publication, 
  3632.         @destination_db, @pubid, @srvid, @immediate_sync
  3633.         
  3634.     WHILE (@@fetch_status <> -1)
  3635.     BEGIN
  3636.  
  3637.         /* 
  3638.         ** Is it a full subscription ? i.e. Does it include all the articles? 
  3639.         **
  3640.         */
  3641.  
  3642.         IF NOT EXISTS (SELECT * FROM sysarticles art WHERE
  3643.                 art.pubid = @pubid and 
  3644.                 NOT EXISTS (SELECT * from syssubscriptions sub WHERE
  3645.                     sub.artid = art.artid))
  3646.         BEGIN
  3647.             /* Do all the subscriptions on the publication have same
  3648.             ** sync_type and subscription_type ?
  3649.             */
  3650.   
  3651.               /* 
  3652.             ** Get subscription type on the publication
  3653.             */ 
  3654.             SELECT @subscription_type_id = subs.subscription_type,
  3655.                 @sync_typeid = subs.sync_type 
  3656.                 FROM 
  3657.                 sysarticles art, syssubscriptions subs  
  3658.                 WHERE
  3659.                 art.pubid = @pubid AND
  3660.                 subs.srvid = @srvid AND
  3661.                 subs.dest_db = @destination_db AND
  3662.                 subs.artid = art.artid
  3663.  
  3664.  
  3665.             /* 
  3666.             ** if the subscription all have the same subscription type
  3667.             ** and sync_type
  3668.             */
  3669.             IF NOT EXISTS (SELECT * from 
  3670.                 sysarticles art, syssubscriptions subs where 
  3671.                 art.pubid = @pubid AND
  3672.                 subs.srvid = @srvid AND
  3673.                 subs.dest_db = @destination_db AND
  3674.                 subs.artid = art.artid AND
  3675.                 (subscription_type <> @subscription_type_id OR
  3676.                 sync_type <> @sync_typeid))
  3677.                 
  3678.  
  3679.                 SELECT @full_subscription = 1
  3680.             ELSE
  3681.                 SELECT @full_subscription = 0
  3682.         END
  3683.         ELSE
  3684.         BEGIN
  3685.             SELECT @full_subscription = 0
  3686.         END
  3687.             
  3688.         /* 
  3689.         ** If it is a full subscription and the @article is 'all',
  3690.         ** only return one entry for the whole publication.
  3691.         ** Bug 22733: Always return one row per publication if @article is 'ALL'
  3692.         */
  3693.         IF    LOWER(@article) = 'all'
  3694.         BEGIN    
  3695.             INSERT INTO #helpsubscription 
  3696.                 SELECT TOP 1 @subscriber, @publication, @article, @destination_db,
  3697.                     sub.status, sub.sync_type, sub.subscription_type,
  3698.                     @full_subscription, sub.distribution_jobid,
  3699.                     @subscriber + ':' + @destination_db  ,
  3700.                     -- SyncTran
  3701.                     sub.update_mode,
  3702.                     sub.loopback_detection
  3703.                     -- end SyncTran
  3704.                     FROM syssubscriptions sub, sysarticles art 
  3705.                     WHERE sub.srvid = @srvid AND
  3706.                         sub.dest_db = @destination_db AND
  3707.                         sub.artid = art.artid and
  3708.                         art.pubid = @pubid
  3709.         END
  3710.         ELSE
  3711.         BEGIN
  3712.             /*
  3713.             ** Get subscriptions
  3714.             ** sa or dbo can see every subscriptions while
  3715.             ** others only see their own.
  3716.             */
  3717.  
  3718.             INSERT INTO #helpsubscription 
  3719.                 SELECT    @subscriber, @publication, art.name, @destination_db,
  3720.                     sub.status, sub.sync_type, sub.subscription_type,
  3721.                     @full_subscription, sub.distribution_jobid,
  3722.                     @subscriber + ':' + @destination_db + ':' + art.name,
  3723.                     -- SyncTran
  3724.                     sub.update_mode,
  3725.                     sub.loopback_detection
  3726.                     -- end SyncTran
  3727.                     FROM
  3728.                     syssubscriptions sub, sysarticles art WHERE
  3729.                         sub.srvid = @srvid AND
  3730.                         sub.dest_db = @destination_db AND
  3731.                         art.pubid = @pubid AND
  3732.                         art.name LIKE @article AND
  3733.                         sub.artid = art.artid AND
  3734.                         (sub.login_name = suser_sname(suser_sid()) OR 
  3735.                          is_srvrolemember('sysadmin') = 1 OR
  3736.                          is_member ('db_owner') = 1)     
  3737.         END
  3738.         FETCH hChelpsubscription_pub INTO @subscriber, @publication, 
  3739.             @destination_db, @pubid, @srvid, @immediate_sync
  3740.     END
  3741.  
  3742.     CLOSE hChelpsubscription_pub
  3743.     DEALLOCATE hChelpsubscription_pub
  3744.  
  3745.     /*
  3746.     ** Get subscriptions
  3747.     */
  3748.     SELECT 'subscriber'           = subscriber,
  3749.            'publication'          = publication,
  3750.            'article'              = article,
  3751.            'destination database' = destination_db,
  3752.            'subscription status'  = status,
  3753.            'synchronization type' = sync_type,
  3754.            'subscription type'    = subscription_type,
  3755.            'full subscription'    = full_subscription,
  3756.            'subscription_name'      = subscription_name,
  3757.               -- SyncTran
  3758.            'update mode'          = update_mode,
  3759.            'distribution job id' = distribution_jobid,
  3760.            'loopback_detection'  = loopback_detection
  3761.  
  3762.       FROM #helpsubscription 
  3763.       ORDER BY subscriber, publication, article
  3764. go
  3765.  
  3766. EXEC dbo.sp_MS_marksystemobject sp_helpsubscription
  3767. GO
  3768.  
  3769. print ''
  3770. print 'Creating procedure sp_articlefilter'
  3771. go
  3772. create procedure sp_articlefilter
  3773.     @publication sysname,           /* publication name */
  3774.     @article sysname,             /* article name */
  3775.     @filter_name nvarchar (386) = NULL,     /* name of filter procedure*/
  3776.     @filter_clause ntext = NULL               /* article's filter clause */
  3777.         
  3778. as
  3779.     
  3780.     declare @pubid smallint
  3781.     declare @table_name sysname
  3782.     declare @user_name sysname
  3783.     declare @qualified_table_name nvarchar (258)
  3784.     declare @filter_id int
  3785.     declare @type tinyint        
  3786.     declare @previous_proc sysname
  3787.     declare @retcode int
  3788.     declare @site sysname
  3789.     declare @db sysname
  3790.     declare @owner sysname
  3791.     declare @object sysname
  3792.     declare @artid int
  3793.     declare @inactive tinyint
  3794.     declare @obid int
  3795.  
  3796.     select @inactive = 0
  3797.  
  3798.     /*
  3799.     ** Security Check.
  3800.     */
  3801.     exec @retcode = dbo.sp_MSreplcheck_publish
  3802.     if @@ERROR <> 0 or @retcode <> 0
  3803.         return(1)
  3804.  
  3805.     /*
  3806.     ** Parameter Check:  @publication.
  3807.     ** Make sure that the publication exists and that it conforms to the
  3808.     ** rules for identifiers.
  3809.     */
  3810.     if @publication is null
  3811.            begin
  3812.               RAISERROR (14043, 16, -1, '@publication')
  3813.               return (1)
  3814.            END
  3815.     
  3816.     execute @retcode = dbo.sp_validname @publication
  3817.     if @retcode <> 0
  3818.     RETURN (1)
  3819.  
  3820.     select @pubid = pubid from syspublications where name = @publication
  3821.  
  3822.         if @pubid is null
  3823.            begin
  3824.             RAISERROR (20026, 11, -1, @publication)
  3825.             return (1)
  3826.            end
  3827.  
  3828.     /*
  3829.     ** Parameter Check:  @article.
  3830.     ** Check to make sure that the article exists in the publication.
  3831.     */
  3832.  
  3833.     if @article is null
  3834.        begin
  3835.               RAISERROR (14043, 16, -1, '@article')
  3836.               return (1)
  3837.            end
  3838.         /*
  3839.         execute @retcode = dbo.sp_validname @article
  3840.         if @retcode <> 0
  3841.        return (1)
  3842.        */
  3843.  
  3844.     /*
  3845.     ** Get the article information.
  3846.     */
  3847.     select @artid = art.artid, @table_name = so.name, @type = art.type,
  3848.        @filter_id = art.filter, @user_name = USER_NAME(so.uid)
  3849.        from sysarticles art, sysobjects so
  3850.        where art.pubid = @pubid
  3851.        and art.name = @article
  3852.        and art.objid = so.id
  3853.  
  3854.     /*
  3855.     ** Fail if there is no article information.
  3856.     */
  3857.     if @artid is null
  3858.        begin
  3859.               RAISERROR (20027, 11, -1, @article)
  3860.               return (1)
  3861.        end
  3862.  
  3863.         /*
  3864.         ** Only unsubscribed articles may be modified. (excluding virtual subscriptions)
  3865.         */
  3866.         if exists (select * from syssubscriptions where artid = @artid
  3867.           and status <> @inactive 
  3868.           and srvid >= 0)
  3869.           begin
  3870.          RAISERROR (14092, 11, -1)
  3871.              RETURN (1)
  3872.           end
  3873.  
  3874.  
  3875.         /*
  3876.         ** Error out if this is a not a table based article
  3877.         */
  3878.         IF NOT EXISTS ( SELECT * FROM sysarticles WHERE artid = @artid
  3879.                           AND pubid = @pubid
  3880.                           AND (type & 1) = 1 )
  3881.         BEGIN
  3882.             RAISERROR (14112, 11, -1 )
  3883.             RETURN (1)
  3884.         END
  3885.  
  3886.  
  3887.  
  3888.     /*
  3889.     ** Make sure a valid @filter_name was provided and it is
  3890.     ** a valid name.
  3891.     */
  3892.     if datalength(@filter_clause) > 0  
  3893.     begin
  3894.  
  3895.         /*
  3896.         ** Make sure a valid @filter_name was provided and it is
  3897.         ** a valid name.
  3898.         */
  3899.  
  3900.         if @filter_name is null
  3901.         begin
  3902.            RAISERROR (14043, 16, -1, '@filter_name')
  3903.            return (1)
  3904.         end
  3905.         
  3906.         select @object = PARSENAME( @filter_name, 1 )
  3907.         select @owner  = PARSENAME( @filter_name, 2 )
  3908.         select @db     = PARSENAME( @filter_name, 3 )
  3909.         select @site   = PARSENAME( @filter_name, 4 )
  3910.  
  3911.          if @object IS NULL
  3912.                return 1
  3913.     end
  3914.  
  3915.     /*
  3916.     ** If the article has a generated filter (not manually created), then
  3917.     ** drop the current filter before creating the new one.
  3918.     */
  3919.     if ((@type & 0x3) <> 0x3) and @filter_id <> 0
  3920.        begin
  3921.            select @previous_proc = object_name (@filter_id)
  3922.           if @previous_proc is not null and
  3923.              exists (select * from sysobjects where name = @previous_proc
  3924.                 and type = 'RF')
  3925.          begin
  3926.                 exec ('drop procedure ' + @previous_proc)
  3927.             if @@error <> 0
  3928.                return (1)
  3929.          end
  3930.  
  3931.        end
  3932.  
  3933.  
  3934.     /*
  3935.     ** make an owner qualified table name for these operations name
  3936.     */
  3937.  
  3938.     select @qualified_table_name = @user_name + '.' + @table_name
  3939.  
  3940.     -- Drop replication filter if it exists.
  3941.     -- Note: upgrade needs this logic
  3942.     if datalength(@filter_clause) > 0
  3943.         and exists (select * from sysobjects where id = object_id(@object)
  3944.                 and type = 'RF')
  3945.     begin
  3946.           exec ('drop procedure ' + @object)
  3947.         if @@error <> 0
  3948.            return (1)
  3949.     end
  3950.  
  3951.  
  3952.     /*
  3953.     ** If there is a @filter_clause, create the new filter and
  3954.     ** update the article filter id and filter_clause.
  3955.     **/
  3956.     if datalength(@filter_clause) > 0
  3957.        begin
  3958.         exec ('create procedure ' + @object +
  3959.             ' for replication as ' +
  3960.             'if exists (select * from ' + @qualified_table_name +
  3961.             ' where ' + @filter_clause +
  3962.             ') return 1 else return 0')
  3963.         if @@error <> 0
  3964.            return (1)
  3965.  
  3966.         exec ('sp_MS_marksystemobject ''' + @object + '''')
  3967.         if @@error <> 0
  3968.            return (1)
  3969.  
  3970.         select @filter_id = id  from sysobjects where name = @object
  3971.             and type = 'RF'
  3972.         if @filter_id is null or @filter_id = 0
  3973.            begin
  3974.               RAISERROR (15001, 11, -1, @object)
  3975.               return (1)
  3976.            end
  3977.  
  3978.         /*
  3979.         ** Update article
  3980.         */
  3981.         update sysarticles set filter = @filter_id,
  3982.            filter_clause = @filter_clause
  3983.            where pubid = @pubid
  3984.               and name = @article
  3985.  
  3986.        -------------------------------------------------------------
  3987.        -- SQL SERVER 7.0 ONLY: update sysobjects, set parent id = underlying
  3988.        -- object id
  3989.        -------------------------------------------------------------
  3990.  
  3991.         select @obid = object_id( @qualified_table_name )
  3992.         EXEC dbo.sp_MSsetfilterparent @object, @obid
  3993.         EXEC dbo.sp_MSsetfilteredstatus @obid
  3994.  
  3995.        end
  3996.     else
  3997.     BEGIN
  3998.         /*
  3999.         ** Clear the filter id and filter_clause.
  4000.         */
  4001.         update sysarticles set filter = 0,
  4002.            filter_clause = NULL
  4003.            where pubid = @pubid
  4004.               and name = @article
  4005.  
  4006.         ---------------------------------------------------
  4007.         -- SQL SERVER 7.0 ONLY:  remove parent_id from filter proc
  4008.         ---------------------------------------------------
  4009.  
  4010.         select @obid = object_id( @qualified_table_name )
  4011.         if exists ( select * from sysobjects where name = @object
  4012.                 and type = 'RF')
  4013.             EXEC dbo.sp_MSsetfilterparent @object, 0
  4014.         EXEC dbo.sp_MSsetfilteredstatus @obid
  4015.  
  4016.     END
  4017.  
  4018.     /*
  4019.     ** Force the article cache to be refreshed with the new definition.
  4020.     */
  4021.     EXECUTE dbo.sp_replflush
  4022. go
  4023.  
  4024. dump tran master with no_log
  4025. go
  4026.  
  4027. EXEC dbo.sp_MS_marksystemobject sp_articlefilter
  4028. GO
  4029.  
  4030. print ''
  4031. print 'Creating procedure sp_MSarticletextcol'
  4032. go
  4033. CREATE PROCEDURE sp_MSarticletextcol (
  4034.     @artid int,
  4035.     @colid smallint = NULL,
  4036.     @type nvarchar(10),      /* 'publish', 'nonsqlsub' */
  4037.     @operation nvarchar(5))  /* 'add', 'drop' */
  4038.     AS
  4039.  
  4040.     /*
  4041.     ** Declarations.
  4042.     */
  4043.     DECLARE @cmd nvarchar(255)
  4044.     DECLARE @cmd1 nvarchar(255)
  4045.     DECLARE @columns binary(32)    /* Temporary storage for the converted column */
  4046.     DECLARE @tabid int        /* Article base table id */
  4047.     DECLARE @retcode int
  4048.     DECLARE @status bit
  4049.     DECLARE @image tinyint        /* Constant: 0x22 */
  4050.     DECLARE @text tinyint        /* Constant: 0x23 */
  4051.     DECLARE @publish smallint        /* Constant: 0x1000 */
  4052.     DECLARE @nonsqlsub smallint        /* Constant: 0x2000 */
  4053.     DECLARE @tinycolid tinyint        /* hydra compatible colid */
  4054.  
  4055.     /* Constants */
  4056.     SELECT @image = 0x22
  4057.     SELECT @text = 0x23
  4058.     SELECT @publish = 0x1000
  4059.     SELECT @nonsqlsub = 0x2000
  4060.  
  4061.     SELECT @tinycolid = @colid
  4062.  
  4063.     SELECT @tabid = objid FROM sysarticles WHERE artid = @artid
  4064.  
  4065.     IF @colid IS NULL
  4066.     BEGIN
  4067.        DECLARE hCarttextcol CURSOR LOCAL FAST_FORWARD FOR
  4068.             SELECT colid FROM syscolumns, sysarticles
  4069.                 WHERE artid = @artid
  4070.                 AND id = @tabid
  4071.                 AND (syscolumns.type = 0x22 OR syscolumns.type = 0x23)
  4072.                 AND convert(bit, convert( varbinary, substring( convert( nvarchar, columns ), 16 - floor((colid-1)/16),1 )) & power( 2, ((colid-1)%16))) = 1
  4073.     END
  4074.     ELSE
  4075.     BEGIN
  4076.        DECLARE hCarttextcol CURSOR LOCAL FAST_FORWARD FOR 
  4077.             SELECT colid FROM syscolumns WHERE id = @tabid
  4078.                 AND colid = @colid
  4079.                 AND (type = 0x22 OR type = 0x23)
  4080.     END
  4081.  
  4082.  
  4083.     /* Process each Text\Image column in the article */
  4084.     OPEN hCarttextcol
  4085.  
  4086.     FETCH hCarttextcol INTO @colid
  4087.  
  4088.     WHILE (@@fetch_status <> -1)
  4089.     BEGIN
  4090.  
  4091.        IF LOWER(@operation) = 'add'
  4092.        BEGIN
  4093.           IF LOWER(@type) = 'publish'
  4094.           BEGIN
  4095.              UPDATE syscolumns
  4096.              SET colstat = colstat | @publish
  4097.              WHERE id = @tabid
  4098.              AND colid = @colid
  4099.           END
  4100.           ELSE
  4101.           BEGIN
  4102.              UPDATE syscolumns
  4103.              SET colstat = colstat | @nonsqlsub
  4104.              WHERE id = @tabid
  4105.              AND colid = @colid
  4106.           END
  4107.        END
  4108.        ELSE /* drop */
  4109.        BEGIN
  4110.           /*
  4111.           ** Is there another non-sql server subscription on the column?
  4112.           ** Or another article publishing the column?
  4113.           */
  4114.           EXEC @retcode = dbo.sp_MStextcolstatus @artid, @tabid, @colid,
  4115.           @type, @status OUTPUT
  4116.  
  4117.           IF @@error <> 0 OR @retcode <> 0
  4118.           BEGIN
  4119.              CLOSE hCarttextcol
  4120.             DEALLOCATE hCarttextcol
  4121.             RETURN (1)
  4122.           END
  4123.  
  4124.           IF (@status = 0)
  4125.           BEGIN
  4126.              IF LOWER(@type) = 'publish'
  4127.              BEGIN
  4128.                 /* Clear 'publish' bit */
  4129.                 UPDATE syscolumns
  4130.                 SET colstat = colstat & ~@publish
  4131.                 WHERE id = @tabid
  4132.                 AND colid = @colid
  4133.              END
  4134.              ELSE
  4135.              BEGIN
  4136.                 /* Clear 'non-sql server subscription' bit */
  4137.                 UPDATE syscolumns
  4138.                 SET colstat = colstat & ~@nonsqlsub
  4139.                 WHERE id = @tabid
  4140.                 AND colid = @colid
  4141.              END
  4142.           END
  4143.        END
  4144.  
  4145.        FETCH hCarttextcol INTO @colid
  4146.  
  4147.     END
  4148.  
  4149.  
  4150.     CLOSE hCarttextcol
  4151.     DEALLOCATE hCarttextcol
  4152.  
  4153. GO
  4154.  
  4155. EXEC dbo.sp_MS_marksystemobject sp_MSarticletextcol
  4156. GO
  4157.  
  4158. print ''
  4159. print 'Creating procedure sp_MStextcolstatus'
  4160. go
  4161. CREATE PROCEDURE sp_MStextcolstatus (
  4162.     @artid int,
  4163.     @tabid int,
  4164.     @colid int,
  4165.     @type nvarchar (10),      /* 'publish', 'nonsqlsub' */
  4166.     @status bit OUTPUT)
  4167.     AS
  4168.  
  4169.     /*
  4170.     ** Declarations.
  4171.     */
  4172.     DECLARE @cmd nvarchar(255)
  4173.     DECLARE @artid2 int
  4174.     DECLARE @columns binary(32)
  4175.     DECLARE @image tinyint        /* Constant: 0x22 */
  4176.     DECLARE @text tinyint        /* Constant: 0x23 */
  4177.  
  4178.     /* Constants */
  4179.     SELECT @image = 0x22
  4180.     SELECT @text = 0x23
  4181.  
  4182.     SELECT @status = 0
  4183.  
  4184.  
  4185.     IF LOWER(@type) = 'nonsqlsub'
  4186.     BEGIN
  4187.     /*
  4188.     ** Check all active or subscribed articles for the TEXT/IMAGE column.
  4189.     */    
  4190.         DECLARE hC4 CURSOR LOCAL FAST_FORWARD FOR
  4191.             SELECT sub.artid FROM sysarticles art, syssubscriptions sub
  4192.                 WHERE art.objid = @tabid
  4193.                 AND art.artid <> @artid
  4194.                 AND sub.artid = art.artid
  4195.                 AND sub.status = 1 OR sub.status = 2
  4196.     END
  4197.     ELSE
  4198.     BEGIN
  4199.     /*
  4200.     ** Check all articles for the TEXT/IMAGE column.
  4201.     */    
  4202.         DECLARE hC4 CURSOR LOCAL FAST_FORWARD FOR 
  4203.             SELECT artid FROM sysarticles 
  4204.                 WHERE objid = @tabid
  4205.                 AND artid <> @artid
  4206.     END
  4207.  
  4208.     EXECUTE (@cmd)
  4209.     OPEN hC4
  4210.     FETCH hC4 INTO @artid2
  4211.     WHILE (@@fetch_status <> -1)
  4212.     BEGIN
  4213.        SELECT @columns = columns FROM sysarticles WHERE artid = @artid2
  4214.  
  4215.        IF EXISTS (SELECT * FROM syscolumns
  4216.           WHERE id = @tabid
  4217.           AND colid = @colid
  4218.       AND CONVERT(bit, CONVERT( varbinary, SUBSTRING( CONVERT( nvarchar, @columns ), 16 - FLOOR((colid-1)/16),1 )) & POWER(2, ((colid-1)%16))) = 1
  4219.       AND (type = @image OR type = @text))
  4220.           BEGIN
  4221.          SELECT @status = 1    
  4222.          GOTO CLEANUP
  4223.           END
  4224.  
  4225.        FETCH hC4 INTO @artid2
  4226.     END
  4227.  
  4228. CLEANUP:
  4229.     CLOSE hC4
  4230.     DEALLOCATE hC4
  4231.  
  4232.     RETURN (0)
  4233. GO
  4234.  
  4235. EXEC dbo.sp_MS_marksystemobject sp_MStextcolstatus
  4236. GO
  4237.  
  4238. print ''
  4239. print 'Creating procedure sp_articleview'
  4240. go
  4241. create procedure sp_articleview
  4242.     @publication sysname,        /* Publication name */
  4243.     @article sysname,          /* Article name */
  4244.     @view_name nvarchar (386) = NULL,  /* View name */
  4245.     @filter_clause ntext = NULL            /* Article's filter clause */
  4246.         
  4247. as
  4248.     declare @pubid smallint
  4249.     declare @table_name sysname
  4250.     declare @user_id int
  4251.     declare @user_name sysname
  4252.     declare @qualified_table_name nvarchar (258)
  4253.     declare @columns varbinary (32)
  4254.     declare @name sysname
  4255.     /* 
  4256.     ** NOTE: A column clause of 4000 characters can hold about 27 128- 
  4257.     ** characters long column identifiers
  4258.     */
  4259.     declare @col_clause nvarchar(4000)
  4260.     declare @retcode int
  4261.     declare @view_id int
  4262.     declare @type tinyint
  4263.     declare @table_id int
  4264.     declare @previous_view sysname
  4265.     declare @quoted_prev_view sysname
  4266.     declare @colid int
  4267.     declare @object sysname
  4268.     declare @quoted_object sysname
  4269.     declare @artid int
  4270.     declare @inactive tinyint
  4271.  
  4272.     select @inactive = 0
  4273.  
  4274.     /*
  4275.     ** Security Check.
  4276.     */
  4277.     exec @retcode = dbo.sp_MSreplcheck_publish
  4278.     if @@ERROR <> 0 or @retcode <> 0
  4279.         return(1)
  4280.  
  4281.     /*
  4282.     ** Parameter Check:  @publication.
  4283.     ** Make sure that the publication exists and that it conforms to the
  4284.     ** rules for identifiers.
  4285.     */
  4286.     if @publication is null
  4287.            begin
  4288.               RAISERROR (14043, 16, -1, '@publication')
  4289.               return (1)
  4290.            END
  4291.  
  4292.     execute @retcode = dbo.sp_validname @publication
  4293.     if @retcode <> 0
  4294.             RETURN (1)
  4295.  
  4296.     select @pubid = pubid from syspublications where name = @publication
  4297.         if @pubid is null
  4298.            begin
  4299.             RAISERROR (20026, 11, -1, @publication)
  4300.             return (1)
  4301.            end
  4302.  
  4303.     /*
  4304.     ** Parameter Check:  @article.
  4305.     ** Check to make sure that the article exists in the publication.
  4306.     */
  4307.  
  4308.     if @article is null
  4309.        begin
  4310.               RAISERROR (14043, 16, -1, '@article')
  4311.               return (1)
  4312.            end
  4313.     
  4314.     /*
  4315.         execute @retcode = dbo.sp_validname @article
  4316.         if @retcode <> 0
  4317.        return (1)
  4318.        */
  4319.  
  4320.     /*
  4321.     ** Get the article information.
  4322.     */
  4323.     select @artid = art.artid, @table_name = so.name,
  4324.        @user_id = uid, @user_name = USER_NAME(so.uid),
  4325.        @columns = art.columns, @type = art.type,
  4326.        @view_id = art.sync_objid, @table_id = art.objid
  4327.        from sysarticles art, sysobjects so
  4328.        where art.pubid = @pubid
  4329.        and art.name = @article
  4330.        and art.objid = so.id
  4331.  
  4332.     /*
  4333.     ** Fail if there is no article information.
  4334.     */
  4335.     if @artid is null
  4336.        begin
  4337.               RAISERROR (20027, 11, -1, @article)
  4338.               return (1)
  4339.        end
  4340.  
  4341.         /*
  4342.         ** Only unsubscribed articles may be modified. (excluding virtual subscriptions)
  4343.         */
  4344.         if exists (select * from syssubscriptions where artid = @artid
  4345.           and status <> @inactive
  4346.           and srvid >= 0)
  4347.           begin
  4348.          RAISERROR (14092, 11, -1)
  4349.              RETURN (1)
  4350.           end
  4351.  
  4352.         /*
  4353.         ** Error out if this is a not a table based article
  4354.         */
  4355.         IF NOT EXISTS ( SELECT * FROM sysarticles WHERE artid = @artid
  4356.                           AND pubid = @pubid
  4357.                           AND (type & 1) = 1 )
  4358.             BEGIN
  4359.                 RAISERROR (14112, 11, -1 )
  4360.                 RETURN (1)
  4361.             END
  4362.  
  4363.     
  4364.     /*
  4365.     ** Create a table of all the articles columns.
  4366.     */
  4367.     create table #tmp (colid int NOT NULL, name sysname NOT NULL, published bit NOT NULL)
  4368.     if @@error <> 0
  4369.        return (1)
  4370.  
  4371.     create unique index ind1 on #tmp (colid)
  4372.     if @@error <> 0
  4373.        begin
  4374.         drop table #tmp
  4375.         return (1)
  4376.        end
  4377.  
  4378.     insert into #tmp select colid, name,
  4379.         convert(bit, convert( varbinary, substring( convert( nvarchar(16), @columns ), 16 - floor((colid-1)/16),1 )) & power( 2, ((colid-1)%16)))
  4380.         from syscolumns
  4381.         where id = (select id from sysobjects where name = @table_name and
  4382.            uid = @user_id and type = 'U')
  4383.     
  4384.     /* Break out the specified view name and get the non-ownerqual'd name, then validate that. */
  4385.     select @object = PARSENAME( @view_name, 1 )
  4386.     if @object IS NULL
  4387.        return 1
  4388.     select @quoted_object = QUOTENAME(@object)
  4389.  
  4390.     execute @retcode = dbo.sp_validname @object
  4391.     if @retcode <> 0
  4392.         return (1)
  4393.  
  4394.     /* If no non-published columns, we'll select all and avoid the 4000-char limit on column strings. */
  4395.     if not exists (select * from #tmp where published = 0) 
  4396.     begin
  4397.         select @col_clause = null
  4398.         goto CreateView
  4399.     end
  4400.  
  4401.     /*
  4402.     ** Construct the column list based on all published columns in the
  4403.     ** article.
  4404.     */
  4405.     declare hC  CURSOR LOCAL FAST_FORWARD FOR select colid, name from #tmp
  4406.         where published = 1
  4407.             order by colid asc
  4408.     open hC
  4409.     fetch hC into @colid, @name
  4410.     /* 
  4411.     ** Warning: A unicode character consists of two bytes!
  4412.     */
  4413.  
  4414.     while (@@fetch_status <> -1)
  4415.         begin
  4416.  
  4417.         if @col_clause is null or
  4418.            ((len(@name) + len(@col_clause) + 2) <= 4000)
  4419.             if @col_clause is null
  4420.                 select @col_clause = @name
  4421.             else
  4422.                 select @col_clause = @col_clause + ', ' + @name
  4423.         else
  4424.         /*
  4425.         ** The procedure only support ~4000 characters for the column list
  4426.         */
  4427.           begin
  4428.             RAISERROR (14039, 16, -1)
  4429.             close hC
  4430.             deallocate hC
  4431.             drop table #tmp
  4432.             return (1)
  4433.           end
  4434.         fetch hC into @colid, @name
  4435.         end            
  4436.  
  4437.     close hC
  4438.     deallocate hC
  4439.  
  4440. CreateView:
  4441.     /*
  4442.     ** If the article has a generated view (not manually created), then
  4443.     ** drop the current view before creating the new one.
  4444.     */
  4445.     if ((@type & 0x5) <> 0x5) and @view_id <> 0
  4446.             and @view_id <> @table_id
  4447.     begin
  4448.         select @previous_view = object_name (@view_id)
  4449.         if @previous_view is not null and
  4450.                 exists (select * from sysobjects where name = @previous_view
  4451.                 and type = 'V')
  4452.         begin
  4453.             select @quoted_prev_view = QUOTENAME(@previous_view)
  4454.             exec ('drop view ' + @quoted_prev_view)
  4455.         end
  4456.     end
  4457.  
  4458.  
  4459.     /*
  4460.     ** If a view is going to be created. Make sure a valid @view_name
  4461.     ** was provided.
  4462.     */
  4463.     if @col_clause is not null
  4464.       begin
  4465.           if @view_name is null
  4466.             begin
  4467.               RAISERROR (14043, 16, -1, '@view_name')
  4468.               return (1)
  4469.             end
  4470.       end
  4471.  
  4472.     /*
  4473.     ** make an owner qualified table name for these operations name
  4474.     */
  4475.  
  4476.     select @qualified_table_name = QUOTENAME(@user_name) + '.' + QUOTENAME(@table_name)
  4477.  
  4478.     /*
  4479.     ** Construct and execute the view creation command.
  4480.     */
  4481.     -- Drop the existing view.
  4482.     -- Note: upgrade needs this logic
  4483.     if datalength(@filter_clause) > 0 and
  4484.         exists (select * from sysobjects where id = object_id(@object)
  4485.     and type = 'V') 
  4486.     begin
  4487.         exec ('drop view ' + @quoted_object)
  4488.         if @@error <> 0
  4489.             return (1)
  4490.     end
  4491.  
  4492.     if @col_clause is not null
  4493.     begin
  4494.  
  4495.         if datalength(@filter_clause) > 0
  4496.             exec ('create view ' + @quoted_object + ' as select ' +
  4497.                 @col_clause + ' from ' +  @qualified_table_name +
  4498.                 ' where ' + @filter_clause)
  4499.         else
  4500.             exec ('create view ' + @quoted_object + ' as select ' +
  4501.                 @col_clause + ' from ' +  @qualified_table_name)
  4502.         if @@error <> 0
  4503.            return (1)
  4504.     end
  4505.     else
  4506.     begin
  4507.         if datalength(@filter_clause) > 0
  4508.         begin
  4509.             exec ('create view ' + @quoted_object + ' as select * from ' +
  4510.                    @qualified_table_name + ' where ' + @filter_clause)
  4511.             if @@error <> 0
  4512.               return (1)
  4513.         end
  4514.         else
  4515.         begin
  4516.             exec ('create view ' + @quoted_object + ' as select * from ' + @qualified_table_name )
  4517.             if @@error <> 0
  4518.               return (1)
  4519.         end
  4520.  
  4521.     end
  4522.  
  4523.     -----------------------------------------------------------
  4524.     -- Update the article's sync_objid with the new view id
  4525.     -----------------------------------------------------------
  4526.  
  4527.     select @view_id = id from sysobjects where name = @object and type = 'V'
  4528.     if @view_id is null or @view_id = 0
  4529.     begin
  4530.        RAISERROR (15001, 11, -1, @object)
  4531.        return (1)    
  4532.     end
  4533.     else
  4534.     begin
  4535.         EXEC dbo.sp_MS_marksystemobject @object
  4536.     end
  4537.  
  4538.     ---------------------------------------------
  4539.     --  Update article definition 
  4540.     --  Set new sync_objid and @filter_clause value
  4541.     ---------------------------------------------
  4542.  
  4543.     if datalength(@filter_clause) > 0
  4544.     begin
  4545.        update sysarticles set sync_objid = @view_id,
  4546.           filter_clause = @filter_clause
  4547.           where pubid = @pubid
  4548.           and name = @article
  4549.     end
  4550.     else
  4551.     begin
  4552.        update sysarticles set sync_objid = @view_id,
  4553.           filter_clause = NULL
  4554.           where pubid = @pubid
  4555.           and name = @article
  4556.     end
  4557.  
  4558.     drop table #tmp
  4559.  
  4560.     /*
  4561.     ** Force the article cache to be refreshed with the new definition.
  4562.     */
  4563.     EXECUTE dbo.sp_replflush
  4564. go
  4565.  
  4566. EXEC dbo.sp_MS_marksystemobject sp_articleview
  4567. GO
  4568.  
  4569. dump tran master with no_log
  4570. go
  4571.  
  4572. print ''
  4573. print 'Creating procedure sp_MSaddexearticle'
  4574. go
  4575. CREATE PROCEDURE sp_MSaddexecarticle
  4576.     @publication sysname,               /* publication name */
  4577.     @article     sysname,             /* article name */
  4578.     @source_proc nvarchar (92),                 /* table name */
  4579.     @destination_proc sysname = NULL,           /* destination table name */
  4580.     @type sysname = NULL,                       /* article type */
  4581.     @creation_script nvarchar (127) = NULL,           /* article schema script */
  4582.     @description nvarchar (255) = NULL,                 /* article description */
  4583.     @pre_creation_cmd nvarchar(10) = 'drop',           /* 'none', 'drop', 'delete', 'truncate' */
  4584.     @schema_option binary(8) = NULL,    /* script out stored procedure */
  4585.     @destination_owner sysname,
  4586.     @article_id int OUTPUT
  4587.  
  4588.     AS
  4589.  
  4590.  
  4591.     SET NOCOUNT ON
  4592.  
  4593.     /* variables for SP_NAMECRACK */
  4594.  
  4595.     DECLARE @site sysname
  4596.     DECLARE @db sysname
  4597.     DECLARE @owner sysname
  4598.     DECLARE @object sysname
  4599.  
  4600.     DECLARE @retcode   int
  4601.  
  4602.     DECLARE @procid    int
  4603.     DECLARE @procnum   smallint
  4604.     DECLARE @pubid     int
  4605.     DECLARE @precmdid  int
  4606.  
  4607.     DECLARE @typeid      smallint
  4608.     DECLARE @publish_bit smallint
  4609.     DECLARE @incompatible_typeid smallint
  4610.  
  4611.     DECLARE @cmd nvarchar(255)
  4612.     DECLARE @sysobj_colname  sysname
  4613.  
  4614.     SELECT  @typeid      = 24
  4615.  
  4616.  
  4617.     SELECT @sysobj_colname = 'replinfo'
  4618.     SELECT @publish_bit = 1
  4619.  
  4620.  
  4621.     /*
  4622.     ** Parameter Check: @article.
  4623.     ** The @article name cannot be NULL and must conform to the rules
  4624.     ** for identifiers.
  4625.     */
  4626.  
  4627.     IF @article IS NULL
  4628.         BEGIN
  4629.             RAISERROR (14043, 16, -1, '@article')
  4630.             RETURN (1)
  4631.         END
  4632.     
  4633.     /*
  4634.     EXECUTE @retcode = dbo.sp_validname @article
  4635.  
  4636.     IF @retcode <> 0
  4637.     return(1)
  4638.     */
  4639.  
  4640.     if LOWER(@article) = 'all'
  4641.         BEGIN
  4642.             RAISERROR (14032, 16, -1, '@article')
  4643.             RETURN (1)
  4644.         END
  4645.  
  4646.     /*
  4647.     ** Parameter Check: @publication.
  4648.     ** The @publication name cannot be NULL and must conform to the rules
  4649.     ** for identifiers.
  4650.     */
  4651.  
  4652.     IF @publication IS NULL
  4653.         BEGIN
  4654.             RAISERROR (14043, 16, -1, '@publication')
  4655.             RETURN (1)
  4656.         END
  4657.  
  4658.     EXECUTE @retcode = dbo.sp_validname @publication
  4659.  
  4660.     IF @retcode <> 0
  4661.     RETURN (1)
  4662.  
  4663.     /*
  4664.     ** Parameter Check: @source_proc.
  4665.     ** Check to see that the @source_proc is local, that it conforms
  4666.     ** to the rules for identifiers, and that it is a procedure
  4667.     */
  4668.  
  4669.     IF @source_proc IS NULL
  4670.     BEGIN
  4671.         RAISERROR (14043, 16, -1, '@source_proc')
  4672.         RETURN (1)
  4673.     END
  4674.  
  4675.    select @object = PARSENAME( @source_proc, 1 )
  4676.    select @owner  = PARSENAME( @source_proc, 2 )
  4677.    select @db     = PARSENAME( @source_proc, 3 )
  4678.    select @site   = PARSENAME( @source_proc, 4 )
  4679.  
  4680.    if @object IS NULL
  4681.          return 1
  4682.  
  4683.  
  4684.     IF @source_proc LIKE '%.%.%' AND @db <> DB_NAME()
  4685.     BEGIN
  4686.         RAISERROR (14004, 16, -1, @source_proc)
  4687.         RETURN (1)
  4688.     END
  4689.     
  4690.  
  4691.     /*
  4692.     **  Get the id of the @source_proc
  4693.     */
  4694.  
  4695.     SELECT @procid = id
  4696.       FROM sysobjects
  4697.      WHERE id = OBJECT_ID(@source_proc)
  4698.      AND   type = 'P'
  4699.  
  4700.     IF @procid IS NULL
  4701.     BEGIN
  4702.         RAISERROR (14027, 11, -1, @source_proc)
  4703.         RETURN (1)
  4704.     END
  4705.  
  4706.     IF EXISTS (SELECT * FROM syscomments WHERE
  4707.         id = @procid AND
  4708.         texttype = 4)
  4709.     BEGIN
  4710.         RAISERROR (21004, 16, -1, @source_proc)
  4711.         RETURN (1)
  4712.     END
  4713.     /*
  4714.     ** Parameter Check:  @destination_proc.
  4715.     ** If the destination proc is not specified, assume it's the same
  4716.     ** as the source.  Make sure that the name is not qualified.
  4717.     */
  4718.  
  4719.     IF @destination_proc LIKE '%.%.%'
  4720.     BEGIN
  4721.             RAISERROR (14001, 16, -1)
  4722.         RETURN (1)
  4723.     END
  4724.  
  4725.     /* Enable owner qualified dest name 
  4726.     IF @destination_proc LIKE '%.%'
  4727.     BEGIN
  4728.             RAISERROR (14044, 16, -1, '@destination_proc')
  4729.         RETURN (1)
  4730.     END
  4731.     */
  4732.     
  4733.     IF @destination_proc IS NULL
  4734.         SELECT @destination_proc = @source_proc
  4735.  
  4736.     select @object = PARSENAME( @destination_proc, 1 )
  4737.     select @owner  = PARSENAME( @destination_proc, 2 )
  4738.     select @db     = PARSENAME( @destination_proc, 3 )
  4739.     select @site   = PARSENAME( @destination_proc, 4 )
  4740.  
  4741.     if @object IS NULL
  4742.          return 1
  4743.  
  4744.     /*
  4745.     ** Get the pubid.
  4746.     */
  4747.  
  4748.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  4749.  
  4750.     IF @pubid IS NULL
  4751.         BEGIN
  4752.             RAISERROR (14027, 11, -1, @publication)
  4753.             RETURN (1)
  4754.         END
  4755.  
  4756.     /*
  4757.     ** Parameter Check:  @article, @publication.
  4758.     ** Check if the article already exists in this publication.
  4759.     */
  4760.  
  4761.     IF EXISTS (SELECT *
  4762.                  FROM sysarticles
  4763.                 WHERE pubid = @pubid
  4764.                   AND name = @article)
  4765.         BEGIN
  4766.             RAISERROR (14030, 16, -1, @article, @publication)
  4767.             RETURN (1)
  4768.         END
  4769.  
  4770.  
  4771.     /*
  4772.     ** Set the precmdid.  The default type is 'drop'.
  4773.     **
  4774.     **      @precmdid   pre_creation_cmd
  4775.     **      =========   ================
  4776.     **            0     none
  4777.     **          1     drop
  4778.     */
  4779.     IF LOWER(@pre_creation_cmd) NOT IN ('none', 'drop')
  4780.        BEGIN
  4781.           RAISERROR (14111, 16, -1)
  4782.           RETURN (1)
  4783.        END
  4784.  
  4785.     /*
  4786.     ** Determine the integer value for the pre_creation_cmd.
  4787.     */
  4788.  
  4789.     IF LOWER(@pre_creation_cmd) = 'none'
  4790.        SELECT @precmdid = 0
  4791.     ELSE IF LOWER(@pre_creation_cmd) = 'drop'
  4792.        SELECT @precmdid = 1
  4793.  
  4794.     /*  Determine 'type' value for article.
  4795.     **
  4796.     **            8     proc exec
  4797.     **           24     serializable proc exec
  4798.     */
  4799.  
  4800.     IF @type IS NULL
  4801.     BEGIN
  4802.         SELECT @type = 'serializable proc exec'
  4803.     END
  4804.     ELSE IF LOWER(@type) NOT IN ('proc exec', 'serializable proc exec')
  4805.     BEGIN
  4806.             RAISERROR (14118, 16, -1)
  4807.             RETURN (1)
  4808.     END
  4809.  
  4810.     IF LOWER(@type) = 'proc exec'
  4811.     BEGIN
  4812.        SELECT @typeid = 8
  4813.        SELECT @incompatible_typeid = 24
  4814.     END
  4815.     ELSE IF LOWER(@type) = 'serializable proc exec'
  4816.     BEGIN
  4817.        SELECT @typeid = 24
  4818.        SELECT @incompatible_typeid = 8
  4819.     END
  4820.  
  4821.     -- make sure we haven't already created an article of a different type
  4822.     -- on this proc
  4823.  
  4824.     IF EXISTS ( select * from sysobjects where id = @procid
  4825.                 and replinfo & @incompatible_typeid = @incompatible_typeid )
  4826.     BEGIN
  4827.        RAISERROR (21024, 16, -1, @source_proc )
  4828.        RETURN(1)
  4829.     END
  4830.  
  4831.     /*
  4832.     ** Parameter Check:  @creation_script and @schema_option
  4833.     ** @schema_option is null, set the default value
  4834.     ** If @schema_option is 0, there have to be @creation_script defined.
  4835.     */
  4836.     IF @schema_option IS NULL
  4837.     BEGIN
  4838.         SELECT @schema_option = 1
  4839.     /* 
  4840.         RAISERROR (14043, 16, -1, '@schema_option')
  4841.         RETURN (1)
  4842.         */
  4843.     END
  4844.  
  4845.     IF @schema_option <> 0x0000000000000000 AND 
  4846.         @schema_option <> 0x0000000000000001
  4847.     BEGIN
  4848.         RAISERROR (20014, 10, -1)
  4849.         RETURN (1)
  4850.     END
  4851.  
  4852.     /*
  4853.     **  Add article to sysarticles and update sysobjects category bit.
  4854.     */
  4855.  
  4856.     begin tran
  4857.     save TRAN sp_MSaddexecarticle
  4858.         INSERT sysarticles (columns, creation_script, del_cmd, description,
  4859.                             dest_table, filter, filter_clause, ins_cmd, name,
  4860.                 objid, pre_creation_cmd, pubid,
  4861.                             status, sync_objid, type, upd_cmd, schema_option,
  4862.                             dest_owner)
  4863.         VALUES (0, @creation_script, NULL, @description,
  4864.                 @destination_proc, 0, '', NULL, @article,
  4865.                 @procid, @precmdid, @pubid,
  4866.                 0, @procid, @typeid, NULL, @schema_option,
  4867.                 @destination_owner)
  4868.  
  4869.         IF @@ERROR <> 0
  4870.         BEGIN
  4871.             if @@trancount > 0
  4872.             begin
  4873.                 ROLLBACK TRAN sp_MSaddexecarticle
  4874.                 commit tran
  4875.             end
  4876.             RETURN (1)
  4877.         END
  4878.  
  4879.         SELECT @article_id = @@IDENTITY
  4880.  
  4881.         select @cmd = 'UPDATE sysobjects SET ' + @sysobj_colname
  4882.         select @cmd = @cmd + ' = ' + @sysobj_colname + ' | ' + CONVERT( nvarchar, @publish_bit )
  4883.         select @cmd = @cmd + ' WHERE id = (SELECT objid FROM sysarticles WHERE name = '''
  4884.         select @cmd = @cmd + @article + ''' and pubid = ' + CONVERT( nvarchar, @pubid ) + ')'
  4885.  
  4886.         EXEC (@cmd)
  4887.  
  4888.         IF @@ERROR <> 0
  4889.         BEGIN
  4890.             if @@trancount > 0
  4891.             begin
  4892.                 ROLLBACK TRAN sp_MSaddexecarticle
  4893.                 commit tran
  4894.             end
  4895.             RETURN (1)
  4896.         END
  4897.  
  4898.  
  4899.     COMMIT TRAN
  4900. go
  4901.  
  4902. EXEC dbo.sp_MS_marksystemobject sp_MSaddexecarticle
  4903. GO
  4904.  
  4905. print ''
  4906. print 'Creating procedure sp_addarticle'
  4907. go
  4908. CREATE PROCEDURE sp_addarticle
  4909.     @publication sysname,               /* publication name */
  4910.     @article sysname,             /* article name */
  4911.     @source_table nvarchar (386) = NULL,         /* table name */
  4912.     @destination_table sysname = NULL, /* destination table name */
  4913.     @vertical_partition nchar(5) = 'false',  /* vertical partition */
  4914.     @type sysname = NULL,        /* article type */
  4915.     @filter nvarchar (386) = NULL,        /* stored procedure used to filter table */
  4916.     @sync_object nvarchar (386) = NULL,        /* view or table used for synchronization */
  4917.     @ins_cmd nvarchar (255) = NULL,        /* insert format string */
  4918.     @del_cmd nvarchar (255) = NULL,        /* delete format string */
  4919.     @upd_cmd nvarchar (255) = NULL,        /* update format string */
  4920.     @creation_script nvarchar (127) = NULL,  /* article schema script */
  4921.     @description nvarchar (255) = NULL,        /* article description */
  4922.     @pre_creation_cmd nvarchar(10) = 'drop', /* 'none', 'drop', 'delete', 'truncate' */
  4923.     @filter_clause ntext    = NULL,            /* where clause */
  4924.     @schema_option binary(8) = NULL,
  4925.     @destination_owner sysname = NULL,
  4926.     @status tinyint = 16,                        /* Default: binary command format */
  4927.     @source_owner    sysname = NULL,             /* NULL for 6.5 users, not NULL for 7.0 users */
  4928.     @sync_object_owner sysname = NULL,             /* NULL for 6.5 users, not NULL for 7.0 users */
  4929.     @filter_owner    sysname = NULL,                /* NULL for 6.5 users, not NULL for 7.0 users */
  4930.     @source_object    sysname = NULL                /* if @source_table is NULL, this parameter can not be NULL */
  4931.     AS
  4932.  
  4933.     SET NOCOUNT ON
  4934.  
  4935.     /*
  4936.     ** Declarations.
  4937.     */    
  4938.     DECLARE @bak_source sysname
  4939.     DECLARE @num_columns int
  4940.     DECLARE @accessid smallint
  4941.     DECLARE @db sysname
  4942.     DECLARE @filterid int
  4943.     DECLARE @object sysname
  4944.     DECLARE @owner sysname
  4945.     DECLARE @pubid int
  4946.     DECLARE @publish_bit smallint
  4947.     DECLARE @retcode int
  4948.     DECLARE @site sysname
  4949.     DECLARE @syncid int
  4950.     DECLARE @tabid int
  4951.     DECLARE @typeid smallint
  4952.     DECLARE @pkkey sysname
  4953.     DECLARE @i int
  4954.     DECLARE @indid int
  4955.     DECLARE @precmdid int
  4956.     DECLARE @object_type nchar(2)
  4957.     DECLARE @push tinyint
  4958.     DECLARE @dbname sysname
  4959.     DECLARE @cmd nvarchar(255)
  4960.     DECLARE @fHasPk int
  4961.     DECLARE @no_sync tinyint
  4962.     DECLARE @immediate_sync bit
  4963.     DECLARE @is_filter_in_use int
  4964.     DECLARE @distributor sysname
  4965.     DECLARE @distribdb sysname
  4966.     DECLARE @distproc nvarchar (255)
  4967.     DECLARE @article_id int
  4968.     DECLARE @sync_method tinyint
  4969.     -- SyncTran
  4970.     DECLARE @autogen_sync_procs_id int
  4971.     DECLARE @custom_proc_name varchar(32)
  4972.     DECLARE @guid varbinary(16)
  4973.     declare @allow_sync_tran bit
  4974.     DECLARE @repl_freq int
  4975.  
  4976.  
  4977.     SELECT @push = 0
  4978.     SELECT @dbname = DB_NAME()
  4979.  
  4980.     SELECT @publish_bit = 1
  4981.  
  4982.     SELECT @no_sync = 2 /* no sync type in syssubscriptions */
  4983.  
  4984.     /*
  4985.     ** Security Check.
  4986.     */
  4987.     exec @retcode = dbo.sp_MSreplcheck_publish
  4988.     if @@ERROR <> 0 or @retcode <> 0
  4989.         return(1)
  4990.  
  4991.     /*
  4992.     ** Parameter Check: @article.
  4993.     ** The @article name cannot be NULL and must conform to the rules
  4994.     ** for identifiers.
  4995.     */
  4996.  
  4997.     IF @article IS NULL
  4998.         BEGIN
  4999.             RAISERROR (14043, 16, -1, '@article')
  5000.             RETURN (1)
  5001.         END
  5002.  
  5003.     exec @retcode = dbo.sp_MSreplcheck_name @article
  5004.     if @@ERROR <> 0 or @retcode <> 0
  5005.         return(1)
  5006.  
  5007.     if LOWER(@article) = 'all'
  5008.         BEGIN
  5009.             RAISERROR (14032, 16, -1, '@article')
  5010.             RETURN (1)
  5011.         END
  5012.  
  5013.     /*
  5014.     ** Parameter Check: @publication.
  5015.     ** The @publication name cannot be NULL and must conform to the rules
  5016.     ** for identifiers.
  5017.     */
  5018.  
  5019.     IF @publication IS NULL
  5020.     BEGIN
  5021.         RAISERROR (14043, 16, -1, '@publication')
  5022.         RETURN (1)
  5023.     END
  5024.  
  5025.     EXECUTE @retcode = dbo.sp_validname @publication
  5026.  
  5027.     IF @retcode <> 0
  5028.     RETURN (1)
  5029.  
  5030.     /*
  5031.     ** Parameter Check: @destination_owner.
  5032.     ** The @destination_owner must conform to the rules
  5033.     ** for identifiers.
  5034.     */
  5035.  
  5036.     if @destination_owner is not null
  5037.     BEGIN
  5038.         -- native bcp mode publications are for odbc subscribers. Destination
  5039.         -- owner name is not supported.
  5040.         if exists (select * from syspublications where name = @publication and
  5041.             sync_method = 1)
  5042.         begin
  5043.             raiserror(21039,16, -1)
  5044.             return(1)
  5045.         end
  5046.         EXECUTE @retcode = dbo.sp_validname @destination_owner
  5047.  
  5048.         IF @retcode <> 0
  5049.             RETURN (1)
  5050.     END
  5051.  
  5052.     /*
  5053.     ** Parameter Check: @source_table.
  5054.     ** Check to see that the @source_table is local, that it conforms
  5055.     ** to the rules for identifiers, and that it is a table, and not
  5056.     ** a view or another database object.
  5057.     */
  5058.  
  5059.     IF @source_table IS NULL
  5060.         BEGIN
  5061.             if @source_object is NOT NULL
  5062.                 select @source_table = @source_object
  5063.             else
  5064.                 begin
  5065.                     RAISERROR (14043, 16, -1, '@source_table')
  5066.                     RETURN (1)
  5067.                 end
  5068.         END
  5069.  
  5070.     IF @source_owner is NULL -- 6.5 users only
  5071.     begin
  5072.         IF @source_table LIKE '%.%.%' AND PARSENAME(@source_table, 3) <> DB_NAME()
  5073.                BEGIN
  5074.                   RAISERROR (14004, 16, -1, @source_table)
  5075.                   RETURN (1)
  5076.                END
  5077.     end
  5078.  
  5079.     -- For 7.0 users, @source_owner is not nullable.
  5080.     
  5081.     select @bak_source = @source_table
  5082.     
  5083.     IF @source_owner is not NULL
  5084.         begin
  5085.             select @source_table = QUOTENAME(@source_owner) + '.' + QUOTENAME(@source_table)
  5086.             IF @destination_table IS NULL
  5087.                 SELECT @destination_table = @bak_source
  5088.         end
  5089.     ELSE IF @destination_table IS NULL
  5090.         -- Set destination_table if not provided or default by now.
  5091.         -- If @source_table is qualified (6.x behavior) only use table name for destination name.
  5092.         SELECT @destination_table = PARSENAME(@source_table, 1)    
  5093.         
  5094.     select @num_columns=count(*) from syscolumns where id = object_id(@source_table)
  5095.     if @num_columns > 255
  5096.         begin
  5097.             RAISERROR (20068, 16, @source_table, 255)
  5098.             RETURN (1)
  5099.         end
  5100.  
  5101.     /*
  5102.     **  Get the id of the @source_table
  5103.     */
  5104.     SELECT @tabid = id, @object_type = type
  5105.     FROM sysobjects
  5106.     WHERE id = OBJECT_ID(@source_table)
  5107.  
  5108.     IF @tabid IS NULL
  5109.         BEGIN
  5110.             RAISERROR (14027, 11, -1, @source_table)
  5111.             RETURN (1)
  5112.         END
  5113.  
  5114.     -- at this point, we've done all the common parameter checks.
  5115.     -- If this is a procedure, branch to the proc execution publishing
  5116.     -- routine, otherwise continue processing as if it were a table
  5117.  
  5118.     IF @object_type = 'P'
  5119.     BEGIN
  5120.         begin tran
  5121.         save TRAN sp_addarticle
  5122.  
  5123.         EXECUTE @retcode = dbo.sp_MSaddexecarticle @publication,
  5124.             @article,
  5125.             @source_table,
  5126.             @destination_table,
  5127.             @type,
  5128.             @creation_script,
  5129.             @description,
  5130.             @pre_creation_cmd,
  5131.             @schema_option,
  5132.             @destination_owner,
  5133.             @article_id OUTPUT
  5134.  
  5135.         IF @retcode <> 0
  5136.         BEGIN
  5137.             if @@trancount > 0
  5138.             begin
  5139.                 ROLLBACK TRAN sp_addarticle
  5140.                 commit tran
  5141.             end
  5142.             RETURN (1)
  5143.         END
  5144.         ELSE
  5145.             GOTO DONE
  5146.     END
  5147.  
  5148.     /*
  5149.     ** Make sure that the table name specified is a table and not a view.
  5150.     */
  5151.  
  5152.     IF NOT EXISTS (SELECT * FROM sysobjects
  5153.         WHERE id = (SELECT OBJECT_ID(@source_table))
  5154.         AND type = 'U')
  5155.     BEGIN
  5156.         RAISERROR (14028, 16, -1)
  5157.         RETURN (1)
  5158.     END
  5159.  
  5160.     /*
  5161.     ** Parameter Check:  @destination_table.
  5162.     ** If the destination table is not specified, assume it's the same
  5163.     ** as the source table.  Make sure that the table name is not qualified.
  5164.     */
  5165.  
  5166.     IF @destination_table LIKE '%.%.%'
  5167.     BEGIN
  5168.         RAISERROR (14001, 16, -1)
  5169.         RETURN (1)
  5170.     END
  5171.  
  5172.     IF @destination_table LIKE '%.%'
  5173.     BEGIN
  5174.         RAISERROR (14044, 16, -1, '@destination_table')
  5175.         RETURN (1)
  5176.     END
  5177.  
  5178.     /*
  5179.     ** Parameter Check: @vertical_partition
  5180.     ** Check to make sure that the vertical partition is either TRUE or FALSE.
  5181.     */
  5182.  
  5183.     SELECT @vertical_partition = LOWER(@vertical_partition)
  5184.     IF @vertical_partition NOT IN ('true', 'false')
  5185.     BEGIN
  5186.         RAISERROR (14029, 16, -1)
  5187.         RETURN (1)
  5188.     END
  5189.  
  5190.     --
  5191.     -- parameter check: @status
  5192.     --
  5193.  
  5194.     IF (@status & ~24 ) <> 0
  5195.     BEGIN
  5196.         RAISERROR( 21061, 16, -1, @status, @article )
  5197.         RETURN (1)
  5198.     END
  5199.  
  5200.     /*
  5201.     ** Parameter Check: @filter
  5202.     ** Make sure that the filter is a valid stored procedure.
  5203.     */
  5204.     IF @filter IS NOT NULL
  5205.     BEGIN
  5206.         IF @filter_owner IS NULL
  5207.         BEGIN
  5208.             select @object = PARSENAME( @filter, 1 )
  5209.             select @owner  = PARSENAME( @filter, 2 )
  5210.             select @db     = PARSENAME( @filter, 3 )
  5211.             select @site   = PARSENAME( @filter, 4 )
  5212.  
  5213.             if @object IS NULL
  5214.               return 1
  5215.         END  
  5216.         ELSE
  5217.         BEGIN
  5218.             select @filter = QUOTENAME(@filter_owner) + '.' + QUOTENAME(@filter)
  5219.         END
  5220.  
  5221.         /*
  5222.         ** Get the id of the @filter
  5223.         */
  5224.         select @filterid = id from sysobjects where
  5225.             id = OBJECT_ID(@filter) and type = 'RF'
  5226.         IF @filterid IS NULL
  5227.         BEGIN
  5228.             RAISERROR (14027, 11, -1, @filter)
  5229.             RETURN (1)
  5230.         END
  5231.  
  5232.         EXEC @is_filter_in_use = dbo.sp_MSdoesfilterhaveparent @filterid
  5233.         if( @is_filter_in_use <> 0 )
  5234.         BEGIN
  5235.             RAISERROR( 21009, 11, -1 )
  5236.             RETURN (1)
  5237.         END
  5238.     END
  5239.     ELSE
  5240.         select @filterid = 0
  5241.  
  5242.  
  5243.     /*
  5244.     ** Get the pubid.
  5245.     */
  5246.  
  5247.     -- SyncTran
  5248.     -- SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  5249.     SELECT @pubid = pubid, @autogen_sync_procs_id = autogen_sync_procs, @sync_method = sync_method,
  5250.         @allow_sync_tran = allow_sync_tran 
  5251.     FROM syspublications WHERE name = @publication
  5252.     -- end SyncTran
  5253.  
  5254.     IF @pubid IS NULL
  5255.         BEGIN
  5256.             RAISERROR (14027, 11, -1, @publication)
  5257.             RETURN (1)
  5258.         END
  5259.  
  5260.     /*
  5261.     ** Parameter Check:  @article, @publication.
  5262.     ** Check if the article already exists in this publication.
  5263.     */
  5264.  
  5265.     IF EXISTS (SELECT *
  5266.                  FROM sysarticles
  5267.                 WHERE pubid = @pubid
  5268.                   AND name = @article)
  5269.         BEGIN
  5270.             RAISERROR (14030, 16, -1, @article, @publication)
  5271.             RETURN (1)
  5272.         END
  5273.  
  5274.     /*
  5275.     ** Set the typeid.  The default type is logbased.  Anything else is
  5276.     ** currently undefined (reserved for future use).
  5277.     **
  5278.     **      @typeid     type
  5279.     **      =======     ========
  5280.     **          1     logbased
  5281.     **          3     logbased manualfilter
  5282.     **          5     logbased manualview
  5283.     **          7     logbased manualboth
  5284.     **          8     proc exec              (valid in dbo.sp_MSaddexecarticle)
  5285.     **          24    serializable proc exec (valid in dbo.sp_MSaddexecarticle)
  5286.     */
  5287.  
  5288.  
  5289.     IF @type IS NULL
  5290.     BEGIN
  5291.     SELECT @type = 'logbased'
  5292.     END
  5293.     ELSE IF LOWER(@type) NOT IN ('logbased', 'logbased manualfilter', 'logbased manualview', 'logbased manualboth')
  5294.     BEGIN
  5295.         RAISERROR (14023, 16, -1)
  5296.         RETURN (1)
  5297.     END
  5298.  
  5299.     IF LOWER(@type) = 'logbased'
  5300.         SELECT @typeid = 1
  5301.     ELSE IF LOWER(@type) = 'logbased manualfilter'
  5302.        SELECT @typeid = 3
  5303.     ELSE IF LOWER(@type) = 'logbased manualview'
  5304.        SELECT @typeid = 5
  5305.     ELSE IF LOWER(@type) = 'logbased manualboth'
  5306.         SELECT @typeid = 7
  5307.  
  5308.     /*
  5309.     ** Set the precmdid.  The default type is 'drop'.
  5310.     **
  5311.     **      @precmdid   pre_creation_cmd
  5312.     **      =========   ================
  5313.     **            0     none
  5314.     **          1     drop
  5315.     **          2     delete
  5316.     **          3     truncate
  5317.     */
  5318.     IF LOWER(@pre_creation_cmd) NOT IN ('none', 'drop', 'delete', 'truncate')
  5319.     BEGIN
  5320.         RAISERROR (14061, 16, -1)
  5321.         RETURN (1)
  5322.     END
  5323.  
  5324.     /*
  5325.     ** Determine the integer value for the pre_creation_cmd.
  5326.     */
  5327.     IF LOWER(@pre_creation_cmd) = 'none'
  5328.         SELECT @precmdid = 0
  5329.     ELSE IF LOWER(@pre_creation_cmd) = 'drop'
  5330.         SELECT @precmdid = 1
  5331.     ELSE IF LOWER(@pre_creation_cmd) = 'delete'
  5332.         SELECT @precmdid = 2
  5333.     ELSE IF LOWER(@pre_creation_cmd) = 'truncate'
  5334.         SELECT @precmdid = 3
  5335.  
  5336.     IF @sync_object IS NULL
  5337.         select @syncid = @tabid
  5338.     ELSE
  5339.     BEGIN
  5340.  
  5341.     IF @sync_object_owner is NULL  -- 6.5 only
  5342.     BEGIN
  5343.  
  5344.         /*
  5345.         ** Parameter Check: @sync_object.
  5346.         ** Check to see that the sync_object is local and that it
  5347.         ** conforms to the rules for identifiers.
  5348.         */
  5349.  
  5350.         select @object = PARSENAME( @sync_object, 1 )
  5351.         select @owner  = PARSENAME(  @sync_object, 2 )
  5352.         select @db     = PARSENAME(  @sync_object, 3 )
  5353.         select @site   = PARSENAME(  @sync_object, 4 )
  5354.  
  5355.         if @object IS NULL
  5356.               return 1
  5357.  
  5358.  
  5359.         IF @sync_object LIKE '%.%.%' AND @db <> DB_NAME()
  5360.         BEGIN
  5361.             RAISERROR (14004, 16, -1, @sync_object)
  5362.             RETURN (1)
  5363.         END
  5364.  
  5365.     END -- end of 65 processing
  5366.     else -- for sphinx, @sync_object_owner can not be null
  5367.         select @sync_object = QUOTENAME(@sync_object_owner) + '.' + QUOTENAME(@sync_object)
  5368.         
  5369.         /*
  5370.         **  Get the id of the @sync_object
  5371.         */
  5372.  
  5373.         SELECT @syncid = id FROM sysobjects WHERE id = OBJECT_ID(@sync_object)
  5374.  
  5375.         IF @syncid IS NULL
  5376.         BEGIN
  5377.             RAISERROR (14027, 11, -1, @sync_object)
  5378.             RETURN (1)
  5379.         END
  5380.  
  5381.         /*
  5382.         ** Make sure the sync object specified is a table or a view.
  5383.         */
  5384.  
  5385.         IF NOT EXISTS (SELECT * FROM sysobjects
  5386.                 WHERE id = (SELECT OBJECT_ID(@sync_object))
  5387.                 AND (type = 'U' or
  5388.                      type = 'V'))
  5389.         BEGIN
  5390.             RAISERROR (14031, 16, -1)
  5391.             RETURN (1)
  5392.         END
  5393.     END
  5394.  
  5395.     /*
  5396.     ** If the publication is log-based,
  5397.     ** make sure there is a primary key on the source table.
  5398.     ** NOTE!  sprok in SPSUP.SQL
  5399.     */
  5400.     IF EXISTS (SELECT * FROM syspublications 
  5401.         WHERE pubid = @pubid AND
  5402.             (repl_freq = 0 OR allow_sync_tran = 1)
  5403.             )
  5404.     BEGIN
  5405.         EXEC @fHasPk = dbo.sp_MSreplsup_table_has_pk @tabid
  5406.  
  5407.         IF @fHasPk = 0
  5408.         BEGIN
  5409.             RAISERROR (14088, 16, -1, @source_table)
  5410.             RETURN (1)
  5411.         END
  5412.     END
  5413.  
  5414.     /*
  5415.     ** Parameter Check:  @creation_script and @schema_option
  5416.     ** @schema_option cannot be null
  5417.     ** If @schema_option is 0, there have to be @creation_script defined.
  5418.     */
  5419.     SELECT @repl_freq = repl_freq from syspublications where name = @publication
  5420.     IF @schema_option IS NULL
  5421.     BEGIN
  5422.         -- Snapshot publication, no cust. proc. generation
  5423.         IF @repl_freq = 1 
  5424.         BEGIN
  5425.             SELECT @schema_option  = 0x0000000000000071
  5426.         END
  5427.         ELSE
  5428.         BEGIN
  5429.             SELECT @schema_option  = 0x0000000000000073
  5430.         END
  5431.     END
  5432.  
  5433.     /*
  5434.     ** Parameter Check: @schema_option
  5435.     ** If bit 0x2 is set, this cannot be an article for a snapshot publication
  5436.     **
  5437.     */
  5438.     IF ((CONVERT(INT, @schema_option) & 0x2) <> 0) AND (@repl_freq = 1)
  5439.     BEGIN
  5440.         RAISERROR (21143, 16, -1)
  5441.         RETURN (1)
  5442.     END
  5443.  
  5444.     -- If pub sync_type is character mode bcp(1) 
  5445.     if @sync_method = 1
  5446.     begin
  5447.         select @status = 0
  5448.         if @ins_cmd is NULL  select @ins_cmd = 'SQL'
  5449.         if @upd_cmd is NULL  select @upd_cmd = 'SQL'
  5450.         if @del_cmd is NULL  select @del_cmd = 'SQL'
  5451.     end
  5452.  
  5453.     /*
  5454.     ** Parameter Check: @schema_option
  5455.     ** If Autogeneration of custom procedures is not enabled 
  5456.     ** then the default commands will be SQL
  5457.     */
  5458.     IF ((CONVERT(int, @schema_option) & 0x2) = 0)
  5459.     BEGIN
  5460.         if @ins_cmd is NULL  select @ins_cmd = 'SQL'
  5461.         if @upd_cmd is NULL  select @upd_cmd = 'SQL'
  5462.         if @del_cmd is NULL  select @del_cmd = 'SQL'
  5463.     END
  5464.           
  5465.     -- Autogenerate custom procedure names if not provided.
  5466.     -- If unable to construct a name because the article name is close to the maximum length, then create a
  5467.     -- name based on the database timestamp
  5468.     if ((@source_object is not NULL and len(@article) > 119) or
  5469.         (@source_object is NULL and len(@article) > 21)) or
  5470.         exists (select * from sysarticles where name = @article)
  5471.     begin
  5472.         set @guid = CONVERT(varbinary(16), LEFT(NEWID(),8))
  5473.         exec @retcode = master.dbo.xp_varbintohexstr @guid, @custom_proc_name OUTPUT
  5474.         if @@error <> 0 or @retcode <> 0
  5475.             RETURN(1)
  5476.     end
  5477.     else
  5478.         set @custom_proc_name = @article
  5479.  
  5480.     -- If no command then construct name 
  5481.     if @ins_cmd is NULL
  5482.     begin
  5483.         if (@status & 16) <> 0 -- parameterized
  5484.         begin
  5485.             if @source_object is not NULL  -- 7.0 format
  5486.                 set @ins_cmd = N'CALL ' + convert (sysname, 'sp_MSins_' + @custom_proc_name)
  5487.             else -- 6.x compatible
  5488.                 set @ins_cmd = N'CALL ' + convert(nvarchar(30), 'sp_MSins_' + @custom_proc_name)
  5489.         end
  5490.         else
  5491.             select @ins_cmd = 'SQL'
  5492.     end
  5493.  
  5494.     if @del_cmd is NULL
  5495.     begin
  5496.         if (@status & 16) <> 0 -- parameterized
  5497.         begin
  5498.             if @source_object is not NULL  -- 7.0 format
  5499.                 set @del_cmd = N'CALL ' + convert (sysname, 'sp_MSdel_' + @custom_proc_name)
  5500.             else -- 6.x compatible
  5501.                 set @del_cmd = N'CALL ' + convert(nvarchar(30), 'sp_MSdel_' + @custom_proc_name)
  5502.         end
  5503.         else
  5504.             select @del_cmd = 'SQL'
  5505.     end
  5506.  
  5507.     if @upd_cmd is NULL
  5508.     begin
  5509.         if (@status & 16) <> 0 -- parameterized
  5510.         begin
  5511.             if @source_object is not NULL  -- 7.0 format
  5512.                 set @upd_cmd = N'MCALL ' + convert (sysname, 'sp_MSupd_' + @custom_proc_name)
  5513.             else -- 6.x compatible
  5514.                 set @upd_cmd = N'CALL ' + convert(nvarchar(30), 'sp_MSupd_' + @custom_proc_name)
  5515.         end
  5516.         else
  5517.             select @upd_cmd = 'SQL'
  5518.     end
  5519.  
  5520.     -- SyncTran
  5521.     -- Add timestamp column if not exists
  5522.     if @allow_sync_tran = 1 and ObjectProperty(@tabid, 'TableHasTimestamp') = 0
  5523.     begin
  5524.         exec ('alter table ' + @source_table + ' add msrepl_synctran_ts timestamp not null' )
  5525.         IF @@ERROR <> 0 
  5526.             RETURN (1)
  5527.     end
  5528.  
  5529.     /*
  5530.     **  Add article to sysarticles and update sysobjects category bit.
  5531.     */
  5532.     begin tran
  5533.     save TRAN sp_addarticle
  5534.         INSERT sysarticles (columns, creation_script, del_cmd, description,
  5535.             dest_table, filter, filter_clause, ins_cmd, name,
  5536.             objid, pre_creation_cmd, pubid,
  5537.             status, sync_objid, type, upd_cmd, schema_option,
  5538.             dest_owner)
  5539.         VALUES (0, @creation_script, @del_cmd, @description, @destination_table,
  5540.             @filterid, @filter_clause, @ins_cmd, @article, @tabid,
  5541.             @precmdid, @pubid, @status, @syncid, @typeid, @upd_cmd, @schema_option, 
  5542.             @destination_owner)
  5543.  
  5544.         IF @@ERROR <> 0
  5545.         BEGIN
  5546.             if @@trancount > 0
  5547.             begin
  5548.                 ROLLBACK TRAN sp_addarticle
  5549.                 commit tran
  5550.             end
  5551.             RETURN (1)
  5552.         END
  5553.  
  5554.         SELECT @article_id = @@IDENTITY
  5555.  
  5556.         UPDATE sysobjects SET replinfo =  replinfo |  @publish_bit
  5557.             WHERE id = (SELECT objid FROM sysarticles WHERE name = @article 
  5558.                 and pubid =  @pubid)
  5559.  
  5560.         IF @@ERROR <> 0
  5561.         BEGIN
  5562.             if @@trancount > 0
  5563.             begin
  5564.                 ROLLBACK TRAN sp_addarticle
  5565.                 commit tran
  5566.             end
  5567.             RETURN (1)
  5568.         END
  5569.  
  5570.         IF @filter IS NOT NULL
  5571.         BEGIN
  5572.             EXEC dbo.sp_MSsetfilterparent @filter, @tabid
  5573.             IF @@ERROR <> 0
  5574.             BEGIN
  5575.                 if @@trancount > 0
  5576.                 begin
  5577.                     ROLLBACK TRAN sp_addarticle
  5578.                     commit tran
  5579.                 end
  5580.                 RETURN (1)
  5581.             END
  5582.         END
  5583.  
  5584.         EXEC dbo.sp_MSsetfilteredstatus @tabid
  5585.         IF @@ERROR <> 0
  5586.         BEGIN
  5587.             if @@trancount > 0
  5588.             begin
  5589.                 ROLLBACK TRAN sp_addarticle
  5590.                 commit tran
  5591.             end
  5592.             RETURN (1)
  5593.         END
  5594.  
  5595.         /*
  5596.         ** Set all bits to '1' in the columns column to include all columns.
  5597.         */
  5598.  
  5599.         IF @vertical_partition = 'false'
  5600.         BEGIN
  5601.             EXECUTE @retcode  = dbo.sp_articlecolumn @publication, @article
  5602.             -- synctran
  5603.             , @refresh_synctran_procs = 0
  5604.             
  5605.             IF @@ERROR <> 0 OR @retcode <> 0
  5606.             BEGIN
  5607.                 if @@trancount > 0
  5608.                 begin
  5609.                     ROLLBACK TRAN sp_addarticle
  5610.                     commit tran
  5611.                 end
  5612.                 RETURN (1)
  5613.             END
  5614.         END
  5615.         
  5616.         /*
  5617.         ** 1. Set all bits to '1' for all columns in the primary key.
  5618.         ** 2. Set timestamp column bit to 1 if the publication is synctran
  5619.         */
  5620.         ELSE
  5621.         BEGIN
  5622.             SELECT @indid = indid FROM sysindexes
  5623.             WHERE id = @tabid
  5624.             AND (status & 2048) <> 0    /* PK index */
  5625.         
  5626.             /*
  5627.             **  First we'll figure out what the keys are.
  5628.             */
  5629.             SELECT @i = 1
  5630.  
  5631.             WHILE (@i <= 16)
  5632.             BEGIN
  5633.                 SELECT @pkkey = INDEX_COL(@source_table, @indid, @i)
  5634.                 if @pkkey is NULL
  5635.                     break
  5636.  
  5637.                 EXECUTE @retcode  = dbo.sp_articlecolumn @publication,
  5638.                     @article, @pkkey, 'add'
  5639.                     -- synctran
  5640.                     , @refresh_synctran_procs = 0
  5641.                 IF @@ERROR <> 0 OR @retcode <> 0
  5642.                 BEGIN
  5643.                     if @@trancount > 0
  5644.                     begin
  5645.                         ROLLBACK TRAN sp_addarticle
  5646.                         commit tran
  5647.                     end
  5648.                     RETURN (1)
  5649.                 END
  5650.  
  5651.                 select @i = @i + 1
  5652.             END
  5653.  
  5654.             if @allow_sync_tran = 1 and ObjectProperty(@tabid, 'TableHasTimestamp') = 1
  5655.             begin
  5656.                 declare @ts_col sysname
  5657.                 -- Get synctran column
  5658.                 select @ts_col = name from syscolumns 
  5659.                     where id = @tabid and type_name(xtype) = 'timestamp' 
  5660.                 if @ts_col is not null
  5661.                 begin
  5662.                     EXECUTE @retcode  = dbo.sp_articlecolumn @publication,
  5663.                         @article, @ts_col, 'add'
  5664.                         -- synctran
  5665.                         , @refresh_synctran_procs = 0
  5666.                     IF @@ERROR <> 0 OR @retcode <> 0
  5667.                     BEGIN
  5668.                         if @@trancount > 0
  5669.                         begin
  5670.                             ROLLBACK TRAN sp_addarticle
  5671.                             commit tran
  5672.                         end
  5673.                         RETURN (1)
  5674.                     END
  5675.                 end
  5676.             end
  5677.         END
  5678.  
  5679.         ------------------------------------------------------------------------------
  5680.         -- if table based article does not use a view for sync, create one and use it
  5681.         ------------------------------------------------------------------------------
  5682.  
  5683.         if @tabid = @syncid 
  5684.         begin
  5685.             -- generate view name
  5686.  
  5687.             declare @viewname varchar(255)
  5688.  
  5689.             set @guid = CONVERT(varbinary(16), LEFT(NEWID(),8))
  5690.             exec @retcode = master.dbo.xp_varbintohexstr @guid, @viewname OUTPUT
  5691.             if @@ERROR <> 0 OR @retcode <> 0
  5692.             begin
  5693.                 if @@trancount > 0
  5694.                 begin
  5695.                     ROLLBACK TRAN sp_addarticle
  5696.                     commit tran
  5697.                 end
  5698.                 return 1
  5699.             end
  5700.             
  5701.             set @viewname = 'syncobj_' + @viewname
  5702.  
  5703.             -- create view for object synchronization
  5704.  
  5705.             exec @retcode = dbo.sp_articleview @publication, @article, @viewname, @filter_clause
  5706.             if @@ERROR <> 0 OR @retcode <> 0
  5707.             begin
  5708.                 if @@trancount > 0
  5709.                 begin
  5710.                     ROLLBACK TRAN sp_addarticle
  5711.                     commit tran
  5712.                 end
  5713.                 return 1
  5714.             end
  5715.         end
  5716.  
  5717.  DONE:
  5718.  
  5719.         /*
  5720.         ** Get distribution server information for remote RPC call.
  5721.         */
  5722.         EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  5723.            @distribdb   = @distribdb OUTPUT
  5724.         IF @@ERROR <> 0 or @retcode <> 0
  5725.             BEGIN
  5726.                 RAISERROR (14071, 16, -1)
  5727.                 RETURN (1)
  5728.             END
  5729.  
  5730.         SELECT @dbname =  DB_NAME()
  5731.         
  5732.         SELECT @distproc = RTRIM(@distributor) + '.' + @distribdb + 
  5733.             '.dbo.sp_MSadd_article'
  5734.         EXECUTE @retcode = @distproc
  5735.             @publisher = @@SERVERNAME,
  5736.             @publisher_db = @dbname,
  5737.             @publication = @publication,
  5738.             @article = @article,
  5739.             @article_id = @article_id,
  5740.             @destination_object = @destination_table,
  5741.             @source_owner = @source_owner,
  5742.             @source_object = @bak_source,
  5743.             @description = @description
  5744.  
  5745.  
  5746.         IF @@ERROR <> 0 OR @retcode <> 0
  5747.         BEGIN
  5748.             if @@trancount > 0
  5749.             begin
  5750.                 ROLLBACK TRAN sp_addarticle
  5751.                 commit tran
  5752.             end
  5753.             RETURN (1)
  5754.         END
  5755.         
  5756.         
  5757.         /* If the publication is immediate_sync type
  5758.         ** 1. Change the immediate_sync_ready status to false 
  5759.         ** 2. Add a virtual subscription on the article 
  5760.         ** 3. Add subscriptions for all the subscriber
  5761.         ** that have no_sync subscriptions on the publication
  5762.         **
  5763.         ** Note: Subscriptions for subscribers that have automatic sync subscriptions
  5764.         ** on the publication will be added by snasphot agent.
  5765.         */
  5766.         if EXISTS (SELECT *    FROM syspublications WHERE
  5767.             name = @publication    AND
  5768.             immediate_sync = 1 )
  5769.         BEGIN
  5770.             UPDATE syspublications SET immediate_sync_ready = 0
  5771.                 WHERE name = @publication 
  5772.             IF @@ERROR <> 0 
  5773.             BEGIN
  5774.                 if @@trancount > 0
  5775.                 begin
  5776.                     ROLLBACK TRAN sp_addarticle
  5777.                     commit tran
  5778.                 end
  5779.                 RETURN (1)
  5780.             END
  5781.  
  5782.  
  5783.             EXECUTE @retcode  = dbo.sp_addsubscription 
  5784.                 @publication = @publication, 
  5785.                 @article = @article, 
  5786.                 @subscriber = NULL, 
  5787.                 @destination_db = 'virtual', 
  5788.                 @sync_type = 'automatic', 
  5789.                 @status = NULL, 
  5790.                 @reserved = 'internal'
  5791.             IF @@ERROR <> 0 OR @retcode <> 0
  5792.             BEGIN
  5793.                 if @@trancount > 0
  5794.                 begin
  5795.                     ROLLBACK TRAN sp_addarticle
  5796.                     commit tran
  5797.                 end
  5798.                 RETURN (1)
  5799.             END
  5800.  
  5801.             -- Note: We have to add the subscriptions to the new article before 
  5802.             -- the virtual subscriptions being activated!!!! Otherwise, the snapshot 
  5803.             -- transactions may be skipped by dist agents.
  5804.             EXECUTE @retcode  = dbo.sp_refreshsubscriptions @publication
  5805.  
  5806.             IF @@ERROR <> 0 OR @retcode <> 0
  5807.             BEGIN
  5808.                 if @@trancount > 0
  5809.                 begin
  5810.                     ROLLBACK TRAN sp_addarticle
  5811.                     commit tran
  5812.                 end
  5813.                 RETURN (1)
  5814.             END 
  5815.         END
  5816.  
  5817.         /* 
  5818.         ** if @autogen_sync_procs_id is 1, autogen the sync tran procs, including name 
  5819.         */
  5820.         if @tabid > 0 and @autogen_sync_procs_id = 1
  5821.         begin
  5822.             declare @insproc sysname, @updproc sysname, @delproc sysname
  5823.  
  5824.             select @insproc = 'sp_MSsync_ins_' + SUBSTRING(RTRIM(@article), 1, 100) + '_' + rtrim(convert(varchar, @pubid))
  5825.             select @updproc = 'sp_MSsync_upd_' + SUBSTRING(RTRIM(@article), 1, 100) + '_' + rtrim(convert(varchar, @pubid))
  5826.             select @delproc = 'sp_MSsync_del_' + SUBSTRING(RTRIM(@article), 1, 100) + '_' + rtrim(convert(varchar, @pubid))
  5827.  
  5828.             -- check uniqueness of names and revert to ugly guid-based name if friendly name already exists
  5829.             if exists (select name from sysobjects where name in (@insproc, @updproc, @delproc))
  5830.             begin
  5831.                 declare @guid_name nvarchar(36)
  5832.                 select @guid_name =  convert (nvarchar(36), newid())
  5833.                 -- remove '-' from guid name because rpc can't handle '-'
  5834.                 select @guid_name = replace (@guid_name,'-','_')
  5835.                 select @insproc = 'sp_MSsync_ins_' + @guid_name
  5836.                 select @updproc = 'sp_MSsync_upd_' + @guid_name
  5837.                 select @delproc = 'sp_MSsync_del_' + @guid_name
  5838.             end
  5839.  
  5840.             if @insproc IS NULL
  5841.             begin
  5842.                 if @@trancount > 0
  5843.                 begin
  5844.                     ROLLBACK TRANSACTION sp_addarticle
  5845.                     commit tran
  5846.                 end
  5847.                 RAISERROR (14043, 11, -1, '@insproc')
  5848.                 RETURN (1)
  5849.             end
  5850.  
  5851.             if @updproc IS NULL
  5852.             begin
  5853.                 if @@trancount > 0
  5854.                 begin
  5855.                     ROLLBACK TRANSACTION sp_addarticle
  5856.                     commit tran
  5857.                 end
  5858.                 RAISERROR (14043, 11, -1, '@updproc')
  5859.                 RETURN (1)
  5860.             end
  5861.  
  5862.             if @delproc IS NULL
  5863.             begin
  5864.                 if @@trancount > 0
  5865.                 begin
  5866.                     ROLLBACK TRANSACTION sp_addarticle
  5867.                     commit tran
  5868.                 end
  5869.                 RAISERROR (14043, 11, -1, '@delproc')
  5870.                 RETURN (1)
  5871.             end
  5872.  
  5873.  
  5874.             exec @retcode = dbo.sp_articlesynctranprocs @publication, @article, @insproc, @updproc, @delproc, true
  5875.  
  5876.             IF @@ERROR <> 0 OR @retcode <> 0
  5877.             BEGIN
  5878.                 if @@trancount > 0
  5879.                 begin
  5880.                     ROLLBACK TRANSACTION sp_addarticle
  5881.                     commit tran
  5882.                 end
  5883.                 RETURN (1)
  5884.             END
  5885.         end
  5886.         -- end SyncTran
  5887.  
  5888.     COMMIT TRANSACTION
  5889. go
  5890.  
  5891. /*
  5892. ** Create replication stored procedures.
  5893. ** Part 1:  create codependent procedures.
  5894. */
  5895.  
  5896. EXEC dbo.sp_MS_marksystemobject sp_addarticle
  5897. GO
  5898.  
  5899. print ''
  5900. print 'Creating procedure sp_changesubstatus'
  5901. go
  5902. CREATE PROCEDURE sp_changesubstatus (
  5903.     @publication sysname = '%',    /* publication name */
  5904.     @article sysname = '%',        /* article name */
  5905.     @subscriber sysname = '%',      /* subscriber name */
  5906.     @status sysname,                /* subscription status */
  5907.     @previous_status sysname=NULL,  /* previous subscription status */
  5908.     @destination_db sysname = '%',   /* destination database name */
  5909.  
  5910.     @frequency_type int = NULL,
  5911.     @frequency_interval int = NULL,
  5912.     @frequency_relative_interval int = NULL,
  5913.     @frequency_recurrence_factor int = NULL,
  5914.     @frequency_subday int = NULL,
  5915.     @frequency_subday_interval int = NULL,
  5916.     @active_start_time_of_day int = NULL,
  5917.     @active_end_time_of_day int = NULL,
  5918.     @active_start_date int = NULL,
  5919.     @active_end_date int = NULL,
  5920.     @optional_command_line nvarchar(4000) = NULL,
  5921.     @distribution_jobid binary(16) = NULL OUTPUT,
  5922.     @from_auto_sync bit = 0,
  5923.     @ignore_distributor bit = 0
  5924. ) AS
  5925.  
  5926.     SET NOCOUNT ON
  5927.     DECLARE @inactive tinyint
  5928.     DECLARE @subscribed tinyint
  5929.     DECLARE @active tinyint
  5930.     DECLARE @public tinyint
  5931.     DECLARE @replicate_bit smallint
  5932.     DECLARE @msg nvarchar(255)
  5933.     DECLARE @prevstatid tinyint
  5934.     DECLARE @artid int
  5935.     DECLARE @tabid int
  5936.     DECLARE @srvid smallint
  5937.     DECLARE @statusid tinyint
  5938.     DECLARE @distributor sysname
  5939.     DECLARE @distribdb sysname
  5940.     DECLARE @distproc nvarchar (255)
  5941.     DECLARE @pub_db sysname
  5942.     DECLARE @dest_db sysname
  5943.     DECLARE @sub_name sysname
  5944.     DECLARE @sub_status tinyint
  5945.     DECLARE @sub_ts varbinary (16)
  5946.     DECLARE @non_sql_flag bit
  5947.     DECLARE @cmd0 nvarchar (255)
  5948.     DECLARE @cmd1 nvarchar (255)
  5949.     DECLARE @cmd2 nvarchar (255)
  5950.     DECLARE @cmd3 nvarchar (255)
  5951.     DECLARE @retcode int
  5952.     DECLARE @repl_freq tinyint
  5953.     DECLARE @art_type tinyint
  5954.     DECLARE @proccmd  nvarchar(255)
  5955.     DECLARE @procnum  smallint
  5956.     DECLARE @finished_real bit
  5957.     DECLARE @finished_virtual bit
  5958.     DECLARE @virtual_id smallint
  5959.     DECLARE @immediate_sync bit
  5960.     DECLARE @enabled_for_internet bit
  5961.     DECLARE @allow_anonymous bit
  5962.     DECLARE @subscription_type int
  5963.     DECLARE @xact_seqno binary(10)
  5964.     DECLARE @sync_type tinyint
  5965.     DECLARE @automatic tinyint
  5966.  
  5967.     DECLARE @art_change bit
  5968.     declare @login_name sysname
  5969.  
  5970.     -- synctran
  5971.     DECLARE @update_mode tinyint
  5972.     DECLARE @art_name sysname
  5973.     declare @synctran tinyint
  5974.     declare @no_distproc bit
  5975.     declare @loopback_detection bit
  5976.  
  5977.     /*
  5978.     ** Initializations.
  5979.     */
  5980.     select @synctran = 1
  5981.     SELECT @automatic = 1
  5982.     SELECT @inactive = 0        /* Const: subscription status 'inactive' */
  5983.     SELECT @subscribed = 1      /* Const: subscription status 'subscribed' */
  5984.     SELECT @active = 2          /* Const: subscription status 'active' */
  5985.     SELECT @public = 0          /* Const: publication status 'public' */
  5986.     SELECT @pub_db = DB_NAME()
  5987.     SELECT @virtual_id = -1
  5988.     SELECT @art_change = 0
  5989.  
  5990.  
  5991.  
  5992.     SELECT @replicate_bit = 2
  5993.  
  5994.     /* 
  5995.     ** Security Check.
  5996.     ** We use login_name stored in syssubscriptions to manage security 
  5997.     */
  5998.  
  5999.     /*
  6000.     ** Parameter Check:  @publication
  6001.     ** Check to make sure that the publication exists, that it's not NULL,
  6002.     ** and that it conforms to the rules for identifiers.
  6003.     */
  6004.  
  6005.     IF @publication IS NULL
  6006.         BEGIN
  6007.             RAISERROR (14043, 16, -1, '@publication')
  6008.             RETURN (1)
  6009.         END
  6010.  
  6011.     IF @publication <> '%'
  6012.         BEGIN
  6013.             EXECUTE @retcode = dbo.sp_validname @publication
  6014.             IF @@ERROR <> 0 OR @retcode <> 0
  6015.             RETURN (1)
  6016.         END
  6017.  
  6018.     IF NOT EXISTS (SELECT * FROM syspublications WHERE name LIKE @publication)
  6019.         BEGIN
  6020.         IF @publication = '%'
  6021.                 RAISERROR (14008, 11, -1)
  6022.         ELSE
  6023.                 RAISERROR (20026, 11, -1, @publication)
  6024.         RETURN (1)
  6025.         END
  6026.  
  6027.     /*
  6028.     ** Parameter Check:  @article
  6029.     ** Check to make sure that the article exists, that it's not null,
  6030.     ** and that it conforms to the rules for identifiers.
  6031.     */
  6032.  
  6033.     IF @article IS NULL
  6034.         BEGIN
  6035.             RAISERROR (14043, 16, -1, '@article')
  6036.             RETURN (1)
  6037.         END
  6038.  
  6039.     /*
  6040.     IF @article <> '%'
  6041.         BEGIN
  6042.             EXECUTE @retcode = dbo.sp_validname @article
  6043.             IF @@ERROR <> 0 OR @retcode <> 0
  6044.             RETURN (1)
  6045.         END
  6046.     */
  6047.  
  6048.     IF NOT EXISTS (SELECT *
  6049.                      FROM sysarticles a,
  6050.                           syspublications b
  6051.                 WHERE a.name LIKE @article
  6052.                       AND a.pubid = b.pubid
  6053.                       AND b.name LIKE @publication)
  6054.  
  6055.         BEGIN
  6056.         IF @article = '%'
  6057.                 RAISERROR (14009, 11, -1, @publication)
  6058.         ELSE
  6059.                 RAISERROR (20027, 11, -1, @article)
  6060.         RETURN (1)
  6061.         END
  6062.  
  6063.     /*
  6064.     ** Parameter Check:  @subscriber
  6065.     ** Check to make sure that the subscriber exists, that it is not NULL,
  6066.     ** and that it conforms to the rules for identifiers.
  6067.     ** Null subscriber represents virtual subscriptions
  6068.     */
  6069.  
  6070.     IF @subscriber IS NOT NULL AND @subscriber <> '%'
  6071.     BEGIN    
  6072.         EXECUTE @retcode = dbo.sp_validname @subscriber
  6073.         IF @@ERROR <> 0 OR @retcode <> 0
  6074.         RETURN (1)
  6075.  
  6076.         IF NOT EXISTS (SELECT *
  6077.                          FROM master..sysservers
  6078.                         WHERE UPPER(srvname) = UPPER(@subscriber)
  6079.                           AND (srvstatus & 4) <> 0)
  6080.  
  6081.             BEGIN
  6082.                 RAISERROR (14063, 11, -1)
  6083.                 RETURN (1)
  6084.             END
  6085.     END
  6086.  
  6087.     /*
  6088.     ** Parameter Check: @status.
  6089.     ** Set the @statusid according to the @status value.  Values can be
  6090.     ** any of the following:
  6091.     **
  6092.     **      status      statusid
  6093.     **      =========   ========
  6094.     **      inactive           0
  6095.     **      subscribed         1
  6096.     **      active             2
  6097.     */
  6098.  
  6099.     IF LOWER(@status) NOT IN ('active', 'subscribed', 'inactive')
  6100.         BEGIN
  6101.             RAISERROR (14065, 16, -1)
  6102.         RETURN (1)
  6103.         END
  6104.  
  6105.     IF LOWER(@status) IN ('active')
  6106.         SELECT @statusid = @active
  6107.     ELSE IF LOWER(@status) IN ('subscribed')
  6108.         SELECT @statusid = @subscribed
  6109.     ELSE
  6110.         SELECT @statusid = @inactive
  6111.  
  6112.     /*
  6113.     ** Parameter Check: @previous_status.
  6114.     ** Set the @prevstatid according to the @previous_status value.
  6115.     ** Values can be any of the following:
  6116.     **
  6117.     **      previous_status      prevstatid
  6118.     **      ===============      ==========
  6119.     **      inactive                      0
  6120.     **      subscribed                    1
  6121.     **      active                        2
  6122.     */
  6123.  
  6124.     IF @previous_status IS NOT NULL
  6125.     BEGIN
  6126.         IF LOWER(@previous_status) NOT IN ('active', 'subscribed', 'inactive')
  6127.         BEGIN
  6128.             RAISERROR (14066, 16, -1)
  6129.             RETURN (1)
  6130.         END
  6131.  
  6132.         IF LOWER(@status) = LOWER(@previous_status)
  6133.         BEGIN
  6134.             RAISERROR (14067, 16, -1)
  6135.             RETURN (1)
  6136.         END
  6137.  
  6138.         IF LOWER(@previous_status) IN ('active')
  6139.             SELECT @prevstatid = @active
  6140.         ELSE IF LOWER(@previous_status) IN ('subscribed')
  6141.             SELECT @prevstatid = @subscribed
  6142.         ELSE
  6143.            SELECT @prevstatid = @inactive
  6144.     END
  6145.  
  6146.     /*
  6147.     ** Parameter Check: @destination_db.
  6148.     ** Set @destination_db to current database if not specified.  Make
  6149.     ** sure that the @destination_db conforms to the rules for identifiers.
  6150.     */
  6151.  
  6152.     IF @destination_db <> '%' 
  6153.     BEGIN
  6154.         EXECUTE @retcode = dbo.sp_validname @destination_db
  6155.         IF @retcode <> 0
  6156.         RETURN (1)
  6157.     END
  6158.  
  6159.     /*
  6160.     ** Get distribution server information for remote RPC
  6161.     ** subscription calls.
  6162.     ** if @ignore_distributor = 1, we are in bruteforce cleanup mode, don't do RPC.
  6163.     */
  6164.     if @ignore_distributor = 1 
  6165.         select @no_distproc = 1
  6166.     else
  6167.         select @no_distproc = 0
  6168.  
  6169.     IF @no_distproc = 0 and @from_auto_sync = 0 
  6170.     BEGIN
  6171.         EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  6172.                                            @distribdb = @distribdb OUTPUT
  6173.  
  6174.         IF @@ERROR <> 0
  6175.         BEGIN
  6176.             RAISERROR (14071, 16, -1)
  6177.             RETURN (1)
  6178.         END
  6179.  
  6180.         IF @retcode <> 0 OR @distribdb IS NULL OR @distributor IS NULL
  6181.         BEGIN
  6182.             RAISERROR (14071, 16, -1)
  6183.             RETURN (1)
  6184.         END
  6185.     END
  6186.  
  6187.     begin tran
  6188.     save TRANSACTION changesubstatus
  6189.  
  6190.         SELECT @finished_virtual = 0
  6191.         SELECT @finished_real = 0
  6192.  
  6193.         /* 
  6194.         ** If @subscriber is null, don't process real subscriptions
  6195.         ** If @subscriber is not null and '%', don't process virtual subscriptions
  6196.         */
  6197.         IF @subscriber IS NULL SELECT @finished_real = 1
  6198.         ELSE IF @subscriber <> '%'  SELECT @finished_virtual = 1
  6199.  
  6200.         WHILE (@finished_real = 0 OR @finished_virtual = 0)
  6201.         BEGIN
  6202.             /*
  6203.             ** Declare cursor containing subscriptions to be updated.
  6204.             */
  6205.             IF @finished_real = 0
  6206.             BEGIN
  6207.                 IF @previous_status IS NOT NULL
  6208.                 BEGIN
  6209.                     DECLARE hCsubstatus CURSOR LOCAL SCROLL_LOCKS FOR
  6210.                         SELECT sub.artid,
  6211.                                art.objid,
  6212.                                sub.srvid,
  6213.                                ss.srvname,
  6214.                                sub.dest_db,
  6215.                                sub.status,
  6216.                            case when ss.srvproduct = 'MSREPL-NONSQL' then 1
  6217.                            else 0 end,
  6218.                            pub.repl_freq,
  6219.                                art.type,
  6220.                            pub.immediate_sync,
  6221.                            pub.enabled_for_internet,
  6222.                            pub.allow_anonymous,
  6223.                            sub.subscription_type,
  6224.                            sub.sync_type,
  6225.                            sub.update_mode,
  6226.                            art.name,
  6227.                            sub.login_name,
  6228.                            sub.loopback_detection
  6229.                           FROM syssubscriptions sub,
  6230.                                sysarticles art,
  6231.                                syspublications pub,
  6232.                                master..sysservers ss
  6233.                          WHERE pub.name LIKE @publication
  6234.                            AND art.name LIKE @article
  6235.                            AND ((@subscriber = N'%') OR (UPPER(ss.srvname) = UPPER(@subscriber)))
  6236.                            AND sub.srvid = ss.srvid
  6237.                            AND sub.artid = art.artid
  6238.                            AND art.pubid = pub.pubid
  6239.                             AND sub.status = @prevstatid
  6240.                            AND sub.dest_db LIKE @destination_db
  6241.                 END
  6242.                 ELSE
  6243.                 BEGIN
  6244.                     DECLARE hCsubstatus CURSOR LOCAL SCROLL_LOCKS FOR
  6245.                         SELECT sub.artid,
  6246.                                art.objid,
  6247.                                sub.srvid,
  6248.                                ss.srvname,
  6249.                                sub.dest_db,
  6250.                                sub.status,
  6251.                            case when ss.srvproduct = 'MSREPL-NONSQL' then 1
  6252.                            else 0 end,
  6253.                            pub.repl_freq,
  6254.                                art.type,
  6255.                            pub.immediate_sync,
  6256.                            pub.enabled_for_internet,
  6257.                            pub.allow_anonymous,
  6258.                            sub.subscription_type,
  6259.                            sub.sync_type,
  6260.                            sub.update_mode,
  6261.                            art.name,
  6262.                            sub.login_name,
  6263.                            sub.loopback_detection
  6264.                           FROM syssubscriptions sub,
  6265.                                sysarticles art,
  6266.                                syspublications pub,
  6267.                                master..sysservers ss
  6268.                          WHERE pub.name LIKE @publication
  6269.                            AND art.name LIKE @article
  6270.                            AND ((@subscriber = N'%') OR (UPPER(ss.srvname) = UPPER(@subscriber)))
  6271.                            AND sub.srvid = ss.srvid
  6272.                            AND sub.artid = art.artid
  6273.                            AND art.pubid = pub.pubid
  6274.                            AND sub.dest_db LIKE @destination_db
  6275.                 END
  6276.                 SELECT @finished_real = 1
  6277.             END
  6278.  
  6279.             ELSE IF @finished_virtual = 0  
  6280.             BEGIN
  6281.                 DECLARE @sub_bit smallint
  6282.                 DECLARE @null_name sysname
  6283.  
  6284.                 SELECT @sub_bit = 4
  6285.                 SELECT @null_name = NULL
  6286.  
  6287.                 /*
  6288.                 ** Treat anonymous virtual subscription as DSN subscriber.
  6289.                 ** This will cause sp_MSarticletextcol being called in sp_changesubstatus
  6290.                 */
  6291.                 DECLARE hCsubstatus CURSOR LOCAL SCROLL_LOCKS FOR
  6292.                     SELECT sub.artid,
  6293.                            art.objid,
  6294.                            sub.srvid,
  6295.                            @null_name,              /* subscriber name. NULL for virtual */
  6296.                            sub.dest_db,
  6297.                            sub.status,
  6298.                        case when pub.allow_anonymous = 1 then 1
  6299.                        else 0 end, /*indicate dsn or not */ 
  6300.                        pub.repl_freq,
  6301.                        art.type,
  6302.                        pub.immediate_sync,
  6303.                        pub.enabled_for_internet,
  6304.                        pub.allow_anonymous,
  6305.                        sub.subscription_type,
  6306.                        sub.sync_type,
  6307.                        sub.update_mode,
  6308.                        art.name,
  6309.                        login_name,
  6310.                        sub.loopback_detection
  6311.  
  6312.                       FROM syssubscriptions sub,
  6313.                            sysarticles art,
  6314.                            syspublications pub
  6315.                      WHERE pub.name LIKE @publication
  6316.                        AND art.name LIKE @article
  6317.                        AND sub.srvid = -1
  6318.                        AND sub.artid = art.artid
  6319.                        AND art.pubid = pub.pubid
  6320.                 SELECT @finished_virtual = 1
  6321.             END
  6322.  
  6323.             OPEN hCsubstatus
  6324.  
  6325.             FETCH hCsubstatus INTO @artid, @tabid, @srvid, @sub_name, @dest_db,
  6326.                 @sub_status, @non_sql_flag, @repl_freq, @art_type,
  6327.                 @immediate_sync, @enabled_for_internet,
  6328.                 @allow_anonymous, @subscription_type, @sync_type, @update_mode,
  6329.                 @art_name, @login_name, @loopback_detection
  6330.  
  6331.  
  6332.             WHILE (@@fetch_status <> -1)
  6333.             BEGIN
  6334.                 IF  suser_sname(suser_sid()) <> @login_name AND is_srvrolemember('sysadmin') <> 1  
  6335.                     AND is_member ('db_owner') <> 1
  6336.                 BEGIN
  6337.                         RAISERROR (14126, 11, -1)
  6338.                         RETURN (1)
  6339.                 END
  6340.  
  6341.                 /*
  6342.                 ** If current status is same as new status, do nothing.
  6343.                 ** @auto_sync_only is used by snapshot for immediate_sync
  6344.                 ** publications.
  6345.                 */
  6346.                 IF @sub_status = @statusid OR
  6347.                     (@from_auto_sync = 1 AND @sync_type <> @automatic)
  6348.                 BEGIN
  6349.                     FETCH hCsubstatus INTO @artid, @tabid, @srvid, @sub_name,
  6350.                        @dest_db, @sub_status, @non_sql_flag, @repl_freq, @art_type, 
  6351.                        @immediate_sync, @enabled_for_internet,
  6352.                        @allow_anonymous, @subscription_type, @sync_type, @update_mode,
  6353.                        @art_name, @login_name, @loopback_detection
  6354.  
  6355.                     CONTINUE
  6356.                 END
  6357.  
  6358.                 /*
  6359.                 ** Update syssubscription status
  6360.                 */
  6361.                 UPDATE syssubscriptions
  6362.                        SET status = @statusid
  6363.                        FROM syssubscriptions sub,
  6364.                            sysarticles art,
  6365.                            syspublications pub
  6366.                        WHERE pub.name LIKE @publication
  6367.                             AND art.artid = @artid
  6368.                             AND sub.srvid = @srvid
  6369.                             AND sub.artid = @artid
  6370.                             AND art.pubid = pub.pubid
  6371.                             AND sub.dest_db = @dest_db
  6372.                 if @@ERROR <> 0
  6373.                                BEGIN
  6374.                                CLOSE hCsubstatus
  6375.                                DEALLOCATE hCsubstatus
  6376.                                 if @@trancount > 0
  6377.                                 begin
  6378.                                     ROLLBACK TRANSACTION changesubstatus
  6379.                                     commit tran
  6380.                                 end
  6381.                                 RAISERROR (14053, 16, -1)
  6382.                                    RETURN (1)
  6383.                                END
  6384.  
  6385.                 /*
  6386.                 ** Get timestamp of subscription.
  6387.                 */
  6388.                 EXEC @retcode = dbo.sp_replincrementlsn @xact_seqno OUTPUT
  6389.                 IF @@ERROR <> 0 or @retcode <> 0
  6390.                             BEGIN
  6391.                                CLOSE hCsubstatus
  6392.                                DEALLOCATE hCsubstatus
  6393.                                if @@trancount > 0
  6394.                                 begin
  6395.                                     ROLLBACK TRANSACTION changesubstatus
  6396.                                     commit tran
  6397.                                 end
  6398.                                RETURN (1)
  6399.                             END
  6400.                 select @sub_ts = @xact_seqno
  6401.  
  6402.  
  6403.                 IF @sub_ts IS NULL
  6404.                             BEGIN
  6405.                                CLOSE hCsubstatus
  6406.                                DEALLOCATE hCsubstatus
  6407.                                if @@trancount > 0
  6408.                                 begin
  6409.                                     ROLLBACK TRANSACTION changesubstatus
  6410.                                     commit tran
  6411.                                 end
  6412.                                 RAISERROR (14053, 16, -1)
  6413.                                RETURN (1)
  6414.                             END
  6415.  
  6416.                 /*
  6417.                 ** If activating subscription, update sysarticles, sysobjects and
  6418.                 ** MSrepl_subscriptions.
  6419.                 */
  6420.                 IF @statusid = @active
  6421.                 BEGIN
  6422.                     
  6423.                     /*
  6424.                     ** Update status of article to show it has been activated.
  6425.                     */
  6426.                     IF @repl_freq = 0 and EXISTS (SELECT * FROM sysarticles WHERE artid = @artid
  6427.                         AND status & 1 <> 1)
  6428.                     BEGIN
  6429.                         UPDATE sysarticles SET status = status | 1 WHERE artid = @artid
  6430.                         IF @@ERROR <> 0
  6431.                             BEGIN
  6432.                                 CLOSE hCsubstatus
  6433.                                 DEALLOCATE hCsubstatus
  6434.                                 if @@trancount > 0
  6435.                                 begin
  6436.                                     ROLLBACK TRANSACTION changesubstatus
  6437.                                     commit tran
  6438.                                 end
  6439.                                 RAISERROR (14069, 16, -1)
  6440.                                 RETURN (1)
  6441.                             END
  6442.                         SELECT @art_change = 1
  6443.                     END
  6444.  
  6445.                         /*
  6446.                         ** Turn the replication flag on for this object in the
  6447.                         ** sysobjects table (make it logbased).
  6448.                         */
  6449.  
  6450.                     if @repl_freq = 0
  6451.                       BEGIN
  6452.                         UPDATE sysobjects SET replinfo = replinfo | @replicate_bit
  6453.                         WHERE id = ( SELECT objid FROM sysarticles WHERE artid = @artid )
  6454.                       END
  6455.  
  6456.                       IF @@ERROR <> 0
  6457.                       BEGIN
  6458.                           CLOSE hCsubstatus
  6459.                           DEALLOCATE hCsubstatus
  6460.                           if @@trancount > 0
  6461.                             begin
  6462.                                 ROLLBACK TRANSACTION changesubstatus
  6463.                                 commit tran
  6464.                             end
  6465.                           RAISERROR (14068, 16, -1)
  6466.                           RETURN (1)
  6467.                       END
  6468.  
  6469.                 END
  6470.  
  6471.                 /*
  6472.                 ** Update status of all Text\Image columns if
  6473.                 ** subscriber is non-SQL Server.
  6474.                 */
  6475.                 IF @non_sql_flag <> 0 AND ( @art_type & 1 ) = 1
  6476.                 BEGIN
  6477.                     IF @statusid = @subscribed OR @statusid = @active
  6478.                     BEGIN
  6479.  
  6480.                         EXEC @retcode = dbo.sp_MSarticletextcol @artid, NULL,
  6481.                                                           'nonsqlsub', 'add'
  6482.                         IF @@ERROR <> 0 OR @retcode <> 0
  6483.                         BEGIN
  6484.                             CLOSE hCsubstatus
  6485.                             DEALLOCATE hCsubstatus
  6486.                             if @@trancount > 0
  6487.                             begin
  6488.                                 ROLLBACK TRANSACTION changesubstatus
  6489.                                 commit tran
  6490.                             end
  6491.                             RAISERROR (14068, 16, -1)
  6492.                             RETURN (1)
  6493.                         END
  6494.  
  6495.  
  6496.                     END
  6497.                     ELSE IF @statusid = @inactive
  6498.                     BEGIN
  6499.  
  6500.                         EXEC @retcode = dbo.sp_MSarticletextcol @artid, NULL,
  6501.                                                           'nonsqlsub', 'drop'
  6502.                         IF @@ERROR <> 0 OR @retcode <> 0
  6503.                         BEGIN
  6504.                           CLOSE hCsubstatus
  6505.                           DEALLOCATE hCsubstatus
  6506.                           if @@trancount > 0
  6507.                             begin
  6508.                                 ROLLBACK TRANSACTION changesubstatus
  6509.                                 commit tran
  6510.                             end
  6511.                           RAISERROR (14068, 16, -1)
  6512.                           RETURN (1)
  6513.                         END
  6514.                     END
  6515.                 END
  6516.  
  6517.                 /*
  6518.                 ** If deactivating subscription, update sysarticles, sysobjects and
  6519.                 ** MSrepl_subscriptions.
  6520.                 */
  6521.  
  6522.                 IF @statusid <> @active AND @sub_status = @active
  6523.                 BEGIN
  6524.                     /*
  6525.                     ** Set the article status to 'inactive' if there are
  6526.                     ** no other active subscriptions on it.
  6527.                     */
  6528.                     IF NOT EXISTS (SELECT * FROM syssubscriptions WHERE
  6529.                        artid = @artid AND status = @active)
  6530.                     BEGIN
  6531.                         IF EXISTS (SELECT * FROM sysarticles WHERE artid = @artid
  6532.                             AND status & 1 = 1)
  6533.                         BEGIN
  6534.                             UPDATE sysarticles SET status = status & ~1 WHERE
  6535.                                 artid = @artid
  6536.                             IF @@ERROR <> 0
  6537.                             BEGIN
  6538.                                 CLOSE hCsubstatus
  6539.                                 DEALLOCATE hCsubstatus
  6540.                                 if @@trancount > 0
  6541.                                 begin
  6542.                                     ROLLBACK TRANSACTION changesubstatus
  6543.                                     commit tran
  6544.                                 end
  6545.                                 RAISERROR (14069, 16, -1)
  6546.                                 RETURN (1)
  6547.                             END
  6548.                             SELECT @art_change = 1
  6549.                         END
  6550.                     END
  6551.  
  6552.                     /*
  6553.                     ** Set the object replication bits  to 'inactive' if
  6554.                     ** there are no other active subscriptions on the
  6555.                     ** table.
  6556.                     */
  6557.                     IF NOT EXISTS (SELECT * FROM syssubscriptions WHERE
  6558.                         artid IN (SELECT sa.artid FROM sysarticles sa, syspublications sp WHERE
  6559.                         sa.objid = @tabid and sa.pubid = sp.pubid and sp.repl_freq = 0) AND status = @active)
  6560.                     BEGIN
  6561.                         UPDATE sysobjects SET replinfo =  replinfo & ~@replicate_bit
  6562.                         WHERE id = (SELECT objid FROM sysarticles WHERE artid = @artid )
  6563.  
  6564.                         IF @@ERROR <> 0
  6565.                         BEGIN
  6566.                            CLOSE hCsubstatus
  6567.                             DEALLOCATE hCsubstatus
  6568.                             RAISERROR (14068, 16, -1)
  6569.                             if @@trancount > 0
  6570.                             begin
  6571.                                 ROLLBACK TRANSACTION changesubstatus
  6572.                                 commit tran
  6573.                             end
  6574.                             RETURN (1)
  6575.                         END
  6576.                     END
  6577.                 END
  6578.  
  6579.  
  6580.                 if @no_distproc = 0
  6581.                 begin
  6582.                     /*
  6583.                     ** Add the active subscription to the distributor's
  6584.                     ** subscriptions table if changing status from @inactive
  6585.                     */
  6586.                     IF @sub_status = @inactive 
  6587.                     -- From inactive to subscribed or active
  6588.                     BEGIN
  6589.  
  6590.                         DECLARE @null_char sysname
  6591.                         SELECT @null_char = NULL
  6592.  
  6593.                         DECLARE @zero_bit bit
  6594.                         SELECT @zero_bit = 0
  6595.  
  6596.                         SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSadd_subscription'
  6597.                         EXEC @retcode = @distproc @@SERVERNAME, @pub_db, @sub_name, 
  6598.                             @artid, @dest_db, @statusid, @sub_ts,
  6599.                             @publication, 
  6600.                             @null_char, /* Pass null to @article, we already gave @artid */
  6601.                             @subscription_type,
  6602.                             --@immediate_sync, 
  6603.                             @sync_type, 
  6604.                             @zero_bit,
  6605.                             @frequency_type,
  6606.                             @frequency_interval,
  6607.                             @frequency_relative_interval,
  6608.                             @frequency_recurrence_factor,
  6609.                             @frequency_subday,
  6610.                             @frequency_subday_interval,
  6611.                             @active_start_time_of_day,
  6612.                             @active_end_time_of_day,
  6613.                             @active_start_date,
  6614.                             @active_end_date,
  6615.                             @optional_command_line = @optional_command_line,
  6616.                             -- synctran
  6617.                             @update_mode = @update_mode,
  6618.                             @loopback_detection = @loopback_detection,
  6619.                             @distribution_jobid = @distribution_jobid OUTPUT
  6620.  
  6621.                         IF @@ERROR <> 0 OR @retcode <> 0
  6622.                         BEGIN
  6623.                             CLOSE hCsubstatus
  6624.                             DEALLOCATE hCsubstatus
  6625.                             RAISERROR (14070, 16, -1)
  6626.                             if @@trancount > 0
  6627.                             begin
  6628.                                 ROLLBACK TRANSACTION changesubstatus
  6629.                                 commit tran
  6630.                             end
  6631.                             RETURN (1)
  6632.                         END
  6633.                     END
  6634.                     ELSE
  6635.                     -- From subscribed or active to others
  6636.                     BEGIN
  6637.                         /*
  6638.                         ** Drop the deactivated subscription from the distributor's
  6639.                         ** subscriptions table.
  6640.                         */
  6641.                         IF @statusid = @inactive
  6642.                         -- From subscribed to inactive or from active to inactive
  6643.                         BEGIN
  6644.                             SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSdrop_subscription'
  6645.                             EXEC @retcode = @distproc @@SERVERNAME, @pub_db, @sub_name,  @artid, @dest_db, @publication
  6646.                             IF @@ERROR <> 0 OR @retcode <> 0
  6647.                             BEGIN
  6648.                                 CLOSE hCsubstatus
  6649.                                 DEALLOCATE hCsubstatus
  6650.                                 RAISERROR (14070, 16, -1)
  6651.                                 if @@trancount > 0
  6652.                                 begin
  6653.                                     ROLLBACK TRANSACTION changesubstatus
  6654.                                     commit tran
  6655.                                 end
  6656.                                 RETURN (1)
  6657.                             END
  6658.                         END
  6659.                         ELSE 
  6660.                         -- From subscribed to active or from active to subscribed.
  6661.                         BEGIN
  6662.                             -- Don't do it if activating the subscription for snapshot agent.
  6663.                             IF NOT (@from_auto_sync = 1 AND @statusid = @active)
  6664.                             BEGIN
  6665.                                 SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSupdate_subscription'
  6666.                                 EXEC @retcode = @distproc @@SERVERNAME, @pub_db, @sub_name, @artid, @statusid, @sub_ts, @dest_db
  6667.                                 IF @@ERROR <> 0 OR @retcode <> 0
  6668.                                 BEGIN
  6669.                                     CLOSE hCsubstatus
  6670.                                     DEALLOCATE hCsubstatus
  6671.                                     RAISERROR (14070, 16, -1)
  6672.                                     if @@trancount > 0
  6673.                                     begin
  6674.                                         ROLLBACK TRANSACTION changesubstatus
  6675.                                         commit tran
  6676.                                     end
  6677.                                     RETURN (1)
  6678.                                 END
  6679.                             END
  6680.                         END
  6681.                     END
  6682.                 end
  6683.  
  6684.                 /*
  6685.                 ** Set internal object replication bit  to 'inactive' if
  6686.                 ** there are no other active subscriptions on the
  6687.                 ** table.
  6688.                 */
  6689.  
  6690.                 IF @statusid = @inactive AND @sub_status = @active AND
  6691.                     NOT EXISTS (SELECT * FROM syssubscriptions WHERE
  6692.                     artid IN (SELECT artid FROM sysarticles WHERE
  6693.                     objid = @tabid) AND status = @active)
  6694.                 BEGIN
  6695.                        /*
  6696.                        ** If it's a procedure execution article, clear proc status bits
  6697.                        */
  6698.                        IF (@art_type & 8 ) = 8
  6699.                        BEGIN
  6700.                            UPDATE sysobjects SET replinfo = replinfo & ~24 WHERE id = @tabid
  6701.                        END
  6702.                 END
  6703.  
  6704.  
  6705.                 /* Turn on object replication */
  6706.  
  6707.                 ELSE IF @statusid = @active
  6708.                 BEGIN
  6709.                        IF (@art_type & 24 ) = 24
  6710.                        BEGIN
  6711.  
  6712.                            UPDATE sysobjects SET replinfo = replinfo | 24 WHERE id = @tabid
  6713.                        END
  6714.                        ELSE IF( @art_type & 8 ) = 8
  6715.                        BEGIN
  6716.                            UPDATE sysobjects SET replinfo = replinfo | 8 WHERE id = @tabid
  6717.                        END
  6718.                 END
  6719.  
  6720.                 -- updates done flush in-memory object schema info
  6721.  
  6722.                 declare @qualified_name nvarchar(512)
  6723.  
  6724.                 exec dbo.sp_MSget_qualified_name @tabid, @qualified_name output
  6725.                 exec dbo.sp_replupdateschema @qualified_name
  6726.  
  6727.                /*
  6728.                ** Get next row.
  6729.                */
  6730.                FETCH hCsubstatus INTO @artid, @tabid, @srvid, @sub_name, @dest_db,
  6731.                @sub_status, @non_sql_flag, @repl_freq, @art_type ,  
  6732.                @immediate_sync, @enabled_for_internet,
  6733.                @allow_anonymous, @subscription_type, @sync_type, @update_mode,
  6734.                 @art_name, @login_name, @loopback_detection
  6735.  
  6736.           
  6737.                                     
  6738.            END  -- end while for cursor
  6739.  
  6740.            CLOSE hCsubstatus
  6741.            DEALLOCATE hCsubstatus
  6742.         
  6743.         END -- end while for virtual and real
  6744.  
  6745.         -- force refresh of article cache
  6746.         -- Bug 25265: Only do it if necessary
  6747.         -- Bug 47732: No need on brute force cleanup
  6748.         IF ( @art_change = 1 ) and ( @ignore_distributor = 0 )
  6749.             EXECUTE dbo.sp_replflush
  6750.  
  6751.     COMMIT TRANSACTION
  6752.     RETURN(0)
  6753. go
  6754.  
  6755. EXEC dbo.sp_MS_marksystemobject sp_changesubstatus
  6756. GO
  6757.  
  6758. print ''
  6759. print 'Creating procedure sp_addsubscription'
  6760. go
  6761. CREATE PROCEDURE sp_addsubscription (
  6762.     @publication sysname,                            /* publication name */
  6763.     @article sysname = 'all',                        /* article name */
  6764.     @subscriber sysname = NULL,                        /* subscriber name */
  6765.     @destination_db sysname = NULL,                /* destination database */
  6766.     @sync_type nvarchar (15) = 'automatic',                /* subscription sync type */
  6767.     @status sysname = NULL,                            /* subscription status */
  6768.     @subscription_type nvarchar(4) = 'push',                /* subscription type:
  6769.                                                         ** 'push' or 'pull' */
  6770.     -- SyncTran
  6771.     @update_mode           nvarchar(15)    = 'read only',    -- Can be 'read only', 'sync tran'
  6772.     @loopback_detection nvarchar(5) = NULL, -- 'true' or 'false'
  6773.     -- end SyncTran
  6774.  
  6775.     @frequency_type int = NULL,
  6776.     @frequency_interval int = NULL,
  6777.     @frequency_relative_interval int = NULL,
  6778.     @frequency_recurrence_factor int = NULL,
  6779.     @frequency_subday int = NULL,
  6780.     @frequency_subday_interval int = NULL,
  6781.     @active_start_time_of_day int = NULL,
  6782.     @active_end_time_of_day int = NULL,
  6783.     @active_start_date int = NULL,
  6784.     @active_end_date int = NULL,
  6785.     @optional_command_line nvarchar(4000) = NULL,
  6786.     
  6787.     @reserved nvarchar(10) = NULL,          /* reserved, used when calling from other system */
  6788.                                             /* stored procedures, it will be set to 'internal'.*/
  6789.                                             /* It should never be used directly */
  6790.     @enabled_for_syncmgr nvarchar(5) = 'false' /* Enabled for SYNCMGR: true or false */
  6791.                                         
  6792.     ) AS
  6793.  
  6794.     SET NOCOUNT ON
  6795.  
  6796.     /*
  6797.     ** Declarations.
  6798.     */
  6799.  
  6800.     DECLARE @artid int
  6801.     DECLARE @pre_creation_cmd tinyint
  6802.     DECLARE @none tinyint
  6803.     DECLARE @automatic tinyint
  6804.     DECLARE @cmd nvarchar(255)
  6805.     DECLARE @cmd2 nvarchar(255)
  6806.     DECLARE @inactive tinyint
  6807.     DECLARE @active tinyint
  6808.     DECLARE @subscribed tinyint
  6809.     DECLARE @manual tinyint
  6810.     DECLARE @pubid int
  6811.     DECLARE @retcode int
  6812.     DECLARE @srvid smallint
  6813.     DECLARE @subscriber_bit smallint
  6814.     DECLARE @sync_typeid tinyint
  6815.     DECLARE @non_sql_flag bit
  6816.     DECLARE @truncate tinyint
  6817.     DECLARE @sync_method tinyint
  6818.     DECLARE @char_bcp tinyint
  6819.     DECLARE @internal nvarchar(10)
  6820.     DECLARE @status_id tinyint
  6821.     DECLARE @virtual_id smallint
  6822.     DECLARE @subscription_type_id int /* 0 push, 1 pull */
  6823.     DECLARE @immediate_sync bit    /* publication type */
  6824.     DECLARE @count_subs int
  6825.     DECLARE @count_arts int
  6826.     DECLARE @distribution_jobid binary(16)
  6827.     DECLARE @pubstatus tinyint
  6828.     DECLARE @allow_anonymous bit
  6829.     DECLARE @immediate_sync_ready bit
  6830.     declare @loopback_detection_id bit
  6831.     declare @independent_agent_id bit
  6832.     DECLARE @platform_nt binary
  6833.  
  6834.     DECLARE @dsn_dbname sysname
  6835.  
  6836.     -- SyncTran
  6837.     DECLARE @allow_sync_tran_id bit
  6838.     DECLARE @update_mode_id     tinyint -- 0 = read only, 1 = sync tran
  6839.     -- end SyncTran
  6840.  
  6841.     /*
  6842.     ** Initializations.
  6843.     */
  6844.  
  6845.     SELECT @none = 2            /* Const: synchronization type 'none' */
  6846.     SELECT @automatic = 1       /* Const: synchronization type 'automatic' */
  6847.     SELECT @manual = 0          /* Const: synchronization type 'manual' */
  6848.     SELECT @inactive = 0        /* Const: subscription status 'inactive' */
  6849.     SELECT @subscribed = 1        /* Const: subscription status 'subscribed' */
  6850.     SELECT @active = 2        /* Const: subscription status 'arctive' */
  6851.     SELECT @subscriber_bit = 4  /* Const: subscription server status */
  6852.     SELECT @truncate = 3    /* Const: truncate pre-creation command */
  6853.     SELECT @char_bcp = 1    /* Const: character bcp sync method */
  6854.     SELECT @virtual_id = -1 /* Const: virtual subscriber id */
  6855.     SELECT @internal = 'internal' /* Const: Flag of calling internally from system */
  6856.                                   /* stored procedures     */
  6857.  
  6858.  
  6859.     -- Hardcoded in sqlrepl.h
  6860.     SELECT @dsn_dbname = 'DSN'
  6861.     SELECT @platform_nt = 0x1
  6862.  
  6863.     /*
  6864.     ** Parameter Check: @publication.
  6865.     ** Check to make sure that the publication exists and that it conforms
  6866.     ** to the rules for identifiers.
  6867.     ** set subscription_type for the publication
  6868.     */
  6869.  
  6870.     IF @publication IS NOT NULL
  6871.         BEGIN
  6872.             
  6873.             EXECUTE @retcode = dbo.sp_validname @publication
  6874.  
  6875.             IF @retcode <> 0
  6876.         RETURN (1)
  6877.  
  6878.             IF NOT EXISTS (SELECT * FROM syspublications WHERE name = @publication)
  6879.                 BEGIN
  6880.                     RAISERROR (20026, 11, -1, @publication)
  6881.                     RETURN (1)
  6882.                 END
  6883.  
  6884.         END
  6885.  
  6886.     /*
  6887.     ** Parameter Check: @subscription_type
  6888.     ** Valid values:
  6889.     ** push
  6890.     ** pull
  6891.     **
  6892.     */
  6893.  
  6894.     IF LOWER(@subscription_type) NOT IN ('push', 'pull')
  6895.         BEGIN
  6896.             RAISERROR (14128, 16, -1)    
  6897.             RETURN (1)
  6898.         END
  6899.  
  6900.     IF LOWER(@subscription_type) = 'push'
  6901.         SELECT @subscription_type_id = 0
  6902.     ELSE 
  6903.         SELECT @subscription_type_id = 1
  6904.  
  6905.     /*
  6906.     ** Security Check.
  6907.     */
  6908.  
  6909.     IF @subscription_type_id = 0 
  6910.     BEGIN
  6911.         exec @retcode = dbo.sp_MSreplcheck_publish
  6912.         if @@ERROR <> 0 or @retcode <> 0
  6913.             return(1)
  6914.     END
  6915.     ELSE
  6916.     BEGIN
  6917.         exec @retcode = dbo.sp_MSreplcheck_pull @publication
  6918.         if @@ERROR <> 0 or @retcode <> 0
  6919.             return(1)
  6920.     END
  6921.  
  6922.    SELECT @pubid = pubid, @sync_method = sync_method, 
  6923.         @immediate_sync = immediate_sync, @pubstatus = status, 
  6924.         @allow_anonymous = allow_anonymous, 
  6925.         @immediate_sync_ready = immediate_sync_ready,
  6926.         -- SyncTran
  6927.         @allow_sync_tran_id = allow_sync_tran,
  6928.         @independent_agent_id = independent_agent
  6929.     FROM syspublications WHERE name = @publication
  6930.  
  6931.     select @srvid = srvid from master..sysservers where UPPER(srvname)=UPPER(@subscriber)
  6932.  
  6933.     if exists (select name from sysobjects where name='sysmergesubscriptions')
  6934.         begin
  6935.             IF exists (select name from sysarticles where pubid=@pubid and 
  6936.                 objid in (select objid from sysmergearticles where 
  6937.                     pubid in (select pubid from sysmergesubscriptions where db_name=@destination_db and srvid=@srvid)))
  6938.             begin
  6939.                 RAISERROR(20084, 16, -1, @publication, @destination_db)
  6940.                 return (1)
  6941.             end
  6942.         end
  6943.  
  6944.  
  6945.     IF @pubid IS NULL
  6946.         BEGIN
  6947.             RAISERROR (14043, 16, -1, '@pubid')
  6948.             RETURN (1)
  6949.         END
  6950.  
  6951.  
  6952.     /* 
  6953.     ** Check to see if the desired subscription type is allowed
  6954.     */
  6955.     /* 
  6956.     ** push 
  6957.     ** Virtual subscriptions are always push type
  6958.     */
  6959.     IF @subscription_type_id = 0 AND @subscriber IS NOT NULL
  6960.     BEGIN
  6961.         IF NOT EXISTS (SELECT * from syspublications where
  6962.             allow_push = 1 AND
  6963.             pubid = @pubid)
  6964.         BEGIN
  6965.             RAISERROR (20012, 16, -1, @subscription_type, @publication)    
  6966.             RETURN (1)
  6967.         END
  6968.     END
  6969.         
  6970.     /* pull */
  6971.     IF @subscription_type_id = 1 AND @subscriber IS NOT NULL
  6972.     BEGIN
  6973.         IF NOT EXISTS (SELECT * from syspublications where
  6974.             allow_pull = 1 AND
  6975.             pubid = @pubid)
  6976.         BEGIN
  6977.             RAISERROR (20012, 16, -1, @subscription_type, @publication)    
  6978.             RETURN (1)
  6979.         END
  6980.     END
  6981.  
  6982.  
  6983.  /*
  6984.     ** Parameter Check: @subscriber.
  6985.     **
  6986.     ** Check if the server exists and that it is a subscription server.
  6987.     **
  6988.     ** @subscriber is NULL represent virtual subscription, which is not allowed
  6989.     ** in following case:
  6990.     ** 1. Non-immediate-sync publication
  6991.     ** 2. the stored procedure is not in the internal usage mode 
  6992.     **        (called by system stored procedures)
  6993.     ** 3. non push mode
  6994.     ** 
  6995.     */
  6996.  
  6997.     IF  @subscriber IS NULL AND (
  6998.         @immediate_sync = 0 OR
  6999.         @subscription_type_id <> 0 OR
  7000.         @reserved <> @internal)
  7001.         BEGIN
  7002.             RAISERROR (14043, 16, -1, '@subscriber')
  7003.             RETURN (1)
  7004.         END
  7005.  
  7006.  
  7007.     IF @subscriber IS NULL
  7008.         BEGIN
  7009.         /* set virtual subscriber ID */
  7010.             SELECT @srvid = @virtual_id 
  7011.             select @non_sql_flag = 0
  7012.         END
  7013.     ELSE
  7014.         BEGIN
  7015.             /* validate name and get subscriber ID  and server status  */
  7016.             EXECUTE @retcode = dbo.sp_validname @subscriber
  7017.  
  7018.             IF @retcode <> 0
  7019.             RETURN (1)
  7020.  
  7021.             select @srvid = null
  7022.             SELECT @srvid = srvid, @non_sql_flag = 
  7023.                 case when srvproduct = N'MSREPL-NONSQL' then 1
  7024.                 else 0 end
  7025.               FROM master..sysservers
  7026.              WHERE UPPER(srvname) = UPPER(@subscriber)
  7027.                AND (srvstatus & @subscriber_bit) <> 0
  7028.  
  7029.             IF @srvid IS NULL
  7030.                 BEGIN
  7031.                     RAISERROR (14010, 16, -1)
  7032.                    RETURN (1)
  7033.                 END
  7034.         END
  7035.  
  7036.     /*
  7037.     ** Parameter Check: @destination_db.
  7038.     ** @destination_db can not be all. 
  7039.     ** Set @destination_db to current database if not specified.  Make
  7040.     ** sure that the @destination_db conforms to the rules for identifiers.
  7041.     */
  7042.  
  7043.     if LOWER(@destination_db) = 'all'
  7044.     BEGIN
  7045.         RAISERROR (14032, 16, -1, '@destination_db')
  7046.         RETURN (1)
  7047.     END
  7048.  
  7049.     IF @destination_db IS NULL SELECT @destination_db = DB_NAME()
  7050.     
  7051.     EXECUTE @retcode = dbo.sp_validname @destination_db
  7052.  
  7053.     IF @retcode <> 0
  7054.     RETURN (1)
  7055.  
  7056.     /*
  7057.     ** Parameter Check:  @article
  7058.     */
  7059.  
  7060.     /* @article can not be null     */
  7061.     IF @article IS NULL
  7062.         BEGIN
  7063.             RAISERROR (14043, 16, -1, '@article')
  7064.             RETURN (1)
  7065.         END
  7066.  
  7067.     -- SyncTran
  7068.     /*
  7069.     ** Parameter check: @update_mode
  7070.     */
  7071.     IF @update_mode IS NULL OR LOWER(@update_mode) NOT IN ('read only', 'sync tran')
  7072.     BEGIN
  7073.         RAISERROR (20502, 16, -1, '@update_mode')
  7074.         RETURN (1)
  7075.     END
  7076.  
  7077.     IF LOWER(@update_mode) = 'sync tran' 
  7078.     BEGIN
  7079.         SELECT @update_mode_id = 1
  7080.        
  7081.         -- Check if publication allows this option
  7082.         IF @allow_sync_tran_id <> 1
  7083.         BEGIN
  7084.             RAISERROR (20503, 16, -1, '@update_mode', 'sp_addsubscription')
  7085.             RETURN (1)
  7086.         END
  7087.  
  7088.     END
  7089.     ELSE 
  7090.     BEGIN
  7091.         SELECT @update_mode_id = 0
  7092.     END
  7093.     -- end SyncTran
  7094.  
  7095.     /** For immediate_sync publication, @article has to be 'all'     */
  7096.     IF NOT @reserved = @internal AND @immediate_sync = 1
  7097.         AND NOT LOWER(@article) = 'all'
  7098.         BEGIN
  7099.             RAISERROR (14122, 16, -1)
  7100.             RETURN (1)
  7101.         END
  7102.  
  7103.     /* For immediate_sync publication,there has to be at least one
  7104.     ** article in the publication before the publication can be subscribed.
  7105.     */
  7106.     IF @immediate_sync = 1 AND not exists ( SELECT * from sysarticles sa, 
  7107.         syspublications sp WHERE sa.pubid = sp.pubid AND sp.name = @publication)
  7108.         BEGIN
  7109.             RAISERROR (14124, 16, -1)
  7110.             RETURN(1)
  7111.         END
  7112.  
  7113.     /* 
  7114.     ** For full subscription, check to see if  subscriptions
  7115.     ** to ALL the articles exist before expanding parameter @article.
  7116.     **
  7117.     */
  7118.     IF LOWER(@article) = 'all' AND @reserved <> @internal AND
  7119.         EXISTS (SELECT * FROM syspublications WHERE pubid = @pubid)
  7120.     BEGIN
  7121.         SELECT @count_arts = count(*) FROM sysarticles art
  7122.             WHERE art.pubid = @pubid 
  7123.  
  7124.         SELECT @count_subs = count(*) FROM syssubscriptions sub, 
  7125.                   sysarticles art
  7126.             WHERE sub.srvid = @srvid
  7127.               AND sub.srvid >= 0
  7128.               AND sub.dest_db = @destination_db
  7129.               AND sub.artid = art.artid
  7130.               AND art.pubid = @pubid
  7131.  
  7132.         IF (@count_arts = @count_subs)
  7133.         BEGIN
  7134.               RAISERROR (14058, 16, -1)
  7135.               RETURN (1)
  7136.         END
  7137.     END
  7138.  
  7139.     /* 
  7140.     ** Real subscription to inactive publicaton is not allowed
  7141.     ** Note, subscriptions to the new article will be added automatically
  7142.     ** for immediate_sync publications. At that time, the publication may not
  7143.     ** be active.
  7144.     */
  7145.  
  7146.     IF  @srvid <> @virtual_id AND @pubstatus = 0 AND @reserved <> @internal
  7147.         BEGIN
  7148.             RAISERROR (21000, 16, -1)
  7149.             RETURN (1)
  7150.         END
  7151.  
  7152.     /* 
  7153.     ** Do special things for DSN subscribers.
  7154.     */
  7155.     IF @subscriber IS NOT NULL AND @non_sql_flag <> 0
  7156.     BEGIN
  7157.         -- DSN subscriber cannot subscribe to native mode publication
  7158.         IF @sync_method <> @char_bcp
  7159.         BEGIN
  7160.             RAISERROR (14095, 16, -1, @publication, @subscriber)
  7161.             RETURN (1)
  7162.         END
  7163.  
  7164.         -- DSN subscriber cannot subscribe with 'Sync Update'
  7165.         IF @update_mode_id <> 0
  7166.         BEGIN
  7167.             RAISERROR (21032, 16, -1, @subscriber)
  7168.             RETURN (1)
  7169.         END
  7170.  
  7171.         -- DSN subscriber cannot subscribe to article using custom procs
  7172.         -- or articles using parameterized statements
  7173.         -- ( only run this test during execs when the article name is actually specified )
  7174.         IF( LOWER( @article ) <> 'all' )
  7175.         BEGIN
  7176.             --IF EXISTS ( select * from sysarticles sa, syspublications sp
  7177.                         --where sa.pubid = sp.pubid 
  7178.                         --and sp.name = @publication
  7179.                         --and sa.name = @article
  7180.                         --and ( ins_cmd like '%call%' or upd_cmd like '%call%' or del_cmd like '%call%' ) )
  7181.             --BEGIN
  7182.                 --RAISERROR(21051, 16, -1, @subscriber)
  7183.                 --RETURN (1)
  7184.             --END
  7185.  
  7186.             IF EXISTS ( select * from sysarticles sa, syspublications sp
  7187.                         where sa.pubid = sp.pubid 
  7188.                         and sp.name = @publication
  7189.                         and sa.name = @article
  7190.                         and sa.status & 16 = 16 ) 
  7191.             BEGIN
  7192.                 RAISERROR(21060, 16, -1, @subscriber)
  7193.                 RETURN (1)
  7194.             END
  7195.  
  7196.         END
  7197.  
  7198.         -- bug 24486 subscriber db of DSN subscriber is meaningless
  7199.         -- use internal values
  7200.         IF @non_sql_flag <> 0 
  7201.             SELECT @destination_db = @dsn_dbname
  7202.  
  7203.         
  7204.     END
  7205.  
  7206.  
  7207.     IF LOWER(@article) = 'all' 
  7208.     /*
  7209.     ** Get all articles in the publication that are not subscribed to
  7210.     ** by the @subscriber
  7211.     */
  7212.     BEGIN
  7213.             /*
  7214.             ** Make the operation atomic. This is to prevent multiple subscription_type
  7215.             ** from one subscriber on an immediate_sync publication
  7216.             */
  7217.             BEGIN TRAN 
  7218.  
  7219.             DECLARE hCx CURSOR LOCAL FAST_FORWARD FOR  SELECT DISTINCT a.name
  7220.                 FROM sysarticles a, syspublications b  
  7221.                 WHERE a.pubid = b.pubid 
  7222.                 AND b.name = @publication
  7223.                 AND NOT EXISTS (SELECT * from syssubscriptions s 
  7224.                     WHERE s.artid = a.artid AND s.status <> 0 AND s.srvid = @srvid
  7225.                     AND s.dest_db = @destination_db)
  7226.             FOR READ ONLY
  7227.  
  7228.             EXECUTE (@cmd + @cmd2)
  7229.             OPEN hCx
  7230.             FETCH hCx INTO @article
  7231.  
  7232.             WHILE (@@fetch_status <> -1)
  7233.                 BEGIN
  7234.                     EXECUTE @retcode = dbo.sp_addsubscription 
  7235.                                 @publication       = @publication,
  7236.                                 @article        = @article,
  7237.                                 @subscriber     = @subscriber,
  7238.                                 @destination_db = @destination_db,
  7239.                                 @sync_type      = @sync_type,
  7240.                                 @status            = @status,
  7241.                                 @subscription_type = @subscription_type,
  7242.                                 @reserved       = @internal,
  7243.                                 -- SyncTran
  7244.                                 @update_mode    = @update_mode,      
  7245.                                 -- end SyncTran
  7246.                                 @loopback_detection = @loopback_detection,
  7247.                                 @frequency_type  = @frequency_type,
  7248.                                 @frequency_interval  = @frequency_interval,
  7249.                                 @frequency_relative_interval  = @frequency_relative_interval,
  7250.                                 @frequency_recurrence_factor  = @frequency_recurrence_factor,
  7251.                                 @frequency_subday  = @frequency_subday,
  7252.                                 @frequency_subday_interval  = @frequency_subday_interval,
  7253.                                 @active_start_time_of_day  = @active_start_time_of_day,
  7254.                                 @active_end_time_of_day  = @active_end_time_of_day,
  7255.                                 @active_start_date  = @active_start_date,
  7256.                                 @active_end_date  = @active_end_date,
  7257.                                 @optional_command_line = @optional_command_line
  7258.     
  7259.  
  7260.                     IF @@error <> 0 OR @retcode <> 0
  7261.                     BEGIN
  7262.                        CLOSE hCx
  7263.                        DEALLOCATE hCx
  7264.                        if @@trancount > 0
  7265.                             ROLLBACK TRAN 
  7266.                        RETURN (1)
  7267.                     END
  7268.                     FETCH hCx INTO @article
  7269.                 END
  7270.             CLOSE hCx
  7271.             DEALLOCATE hCx
  7272.  
  7273.             COMMIT TRAN
  7274.  
  7275.             RETURN (0)
  7276.         END
  7277.  
  7278.    
  7279.     /* After 'all' being expanded, check to make sure that the article exists, 
  7280.     ** is not NULL, and conforms to the rules for identifiers.
  7281.     */
  7282.     /*
  7283.     EXECUTE @retcode = dbo.sp_validname @article
  7284.     IF @retcode <> 0
  7285.     RETURN (1)
  7286.     */
  7287.  
  7288.     SELECT @artid = artid, @pre_creation_cmd = pre_creation_cmd
  7289.     FROM sysarticles
  7290.     WHERE name = @article
  7291.     AND pubid = @pubid
  7292.  
  7293.     IF NOT EXISTS (SELECT *
  7294.                              FROM sysarticles
  7295.                             WHERE artid = @artid
  7296.                               AND pubid = @pubid)
  7297.         BEGIN
  7298.             RAISERROR (20027, 11, -1, @article)
  7299.             RETURN (1)
  7300.         END
  7301.  
  7302.  
  7303.     /*
  7304.     ** If the subscriber is an ODBC DSN, do not allow subscriptions to
  7305.     ** articles with a "truncate" pre_creation_cmd.
  7306.     */
  7307.     IF @non_sql_flag <> 0 AND @pre_creation_cmd = @truncate
  7308.         BEGIN
  7309.             RAISERROR (14094, 16, -1, @article, @subscriber)
  7310.             RETURN (1)
  7311.         END
  7312.  
  7313.    /*
  7314.    ** Parameter Check: @sync_type.
  7315.    ** Set sync_typeid based on the @sync_type specified.
  7316.    **
  7317.    **   sync_typeid     sync_type
  7318.    **   ===========     =========
  7319.    **             0     manual
  7320.    **             1     automatic
  7321.    **             2     none
  7322.    */
  7323.  
  7324.  
  7325.    IF LOWER(@sync_type) NOT IN ('automatic', 'manual', 'none')
  7326.        BEGIN
  7327.            RAISERROR (14052, 16, -1)
  7328.            RETURN (1)
  7329.        END
  7330.  
  7331.    IF LOWER(@sync_type) = 'manual'
  7332.        BEGIN
  7333.            RAISERROR (14123, 16, -1)
  7334.            RETURN (1)
  7335.        END
  7336.  
  7337.  
  7338.    IF LOWER(@sync_type) = 'automatic'
  7339.    BEGIN
  7340.         SELECT @sync_typeid = @automatic
  7341.    END
  7342.    ELSE
  7343.    BEGIN
  7344.         SELECT @sync_typeid = @none
  7345.    END
  7346.  
  7347.  
  7348.  
  7349.     /*
  7350.     ** Bug 12850:
  7351.     ** Make sure that the creation_script is specified if pre_creation_cmd is "drop"
  7352.     ** Note that at this point, @article cannot be 'all'.
  7353.     */
  7354.     /*  NO LONGER REQUIRED IN 7.0
  7355.         if exists (select * from sysarticles where
  7356.                 name = @article AND
  7357.                 pre_creation_cmd = 1 AND
  7358.                 creation_script is null)
  7359.             BEGIN
  7360.                 RAISERROR (14096, 16, -1)    
  7361.                 RETURN (1)
  7362.             END
  7363.     */
  7364.  
  7365.     /*
  7366.     ** Parameter Check: @status
  7367.     ** If the publication is immediate_sync type and sync_type is automatic
  7368.     ** the status has to be NULL.
  7369.     ** Note for 6x backward compatibility, don't do the check for non immediate_sync
  7370.     ** publication
  7371.     */
  7372.     IF @immediate_sync = 1 and @sync_typeid = @automatic AND 
  7373.         @status IS NOT NULL
  7374.     BEGIN
  7375.           RAISERROR (14129, 16, -1)
  7376.           RETURN (1)
  7377.     END
  7378.  
  7379.  
  7380.     /*
  7381.     ** Parameter Check:  @loopback_detection
  7382.     */
  7383.     IF @loopback_detection is not null and LOWER(@loopback_detection) 
  7384.         NOT IN ('true', 'false')
  7385.     BEGIN
  7386.         RAISERROR (14148, 16, -1, '@loopback_detection')
  7387.         RETURN (1)
  7388.     END
  7389.  
  7390.     IF  LOWER(@loopback_detection) = 'true'  
  7391.         SELECT @loopback_detection_id = 1
  7392.     ELSE IF LOWER(@loopback_detection) = 'false' 
  7393.         SELECT @loopback_detection_id = 0
  7394.     ELSE 
  7395.     -- if @loopback_detection is null, we will chose the value
  7396.     begin
  7397.         if @update_mode_id = 1 
  7398.         begin
  7399.             declare @tabid int
  7400.             select @tabid = objid from sysarticles 
  7401.                 where artid = @artid
  7402.             -- Determine if table has timestamp property
  7403.             if ObjectProperty(@tabid, 'TableHasTimestamp') = 1 
  7404.             begin
  7405.                 exec @retcode = dbo.sp_MSis_col_replicated @publication, @article, 'timestamp'
  7406.                 if @@error <> 0
  7407.                     return (1)
  7408.  
  7409.                 if @retcode = 1
  7410.                     select @loopback_detection_id = 1
  7411.                 else
  7412.                     select @loopback_detection_id = 0
  7413.             end
  7414.             else
  7415.                 select @loopback_detection_id = 0
  7416.         end
  7417.         else
  7418.             select @loopback_detection_id = 0
  7419.     end
  7420.  
  7421.     /*
  7422.     ** Add subscription to syssubscriptions
  7423.     */
  7424.     begin tran
  7425.     save TRAN addsubscription
  7426.  
  7427.     /*
  7428.     ** If no subscription exists, add it to syssubscriptions.
  7429.     */
  7430.     /* (leih) SID: getting around bug( 17371 ) */
  7431.     IF NOT EXISTS (SELECT *
  7432.                      FROM syssubscriptions
  7433.                     WHERE srvid = @srvid
  7434.                       AND artid = @artid
  7435.                       AND dest_db = @destination_db)
  7436.         BEGIN
  7437.        INSERT syssubscriptions (artid,
  7438.                                     srvid,
  7439.                                     dest_db,
  7440.                                     login_name,
  7441.                                     status,
  7442.                                     sync_type,
  7443.                                     subscription_type,
  7444.                                     distribution_jobid,
  7445.                                     -- SyncTran
  7446.                                     update_mode,
  7447.                                     loopback_detection)
  7448.                                  /*  timestamp) */
  7449.        VALUES (@artid,
  7450.                    @srvid,
  7451.                    @destination_db,    
  7452.                    suser_sname(suser_sid()),
  7453.                    @inactive,
  7454.                    @sync_typeid,
  7455.                    @subscription_type_id,
  7456.                    0,
  7457.                    -- SyncTran
  7458.                    @update_mode_id,
  7459.                    @loopback_detection_id)
  7460.  
  7461.            /*  NULL) */
  7462.  
  7463.        IF @@ERROR <> 0
  7464.            BEGIN
  7465.                 if @@trancount > 0
  7466.                 begin
  7467.                     ROLLBACK TRAN  addsubscription
  7468.                     commit tran
  7469.                 end
  7470.                 RAISERROR (14057, 16, -1)
  7471.                 RETURN (1)
  7472.            END
  7473.         END
  7474.     ELSE
  7475.        BEGIN
  7476.           RAISERROR (14058, 16, -1)
  7477.           if @@trancount > 0
  7478.             begin
  7479.                 ROLLBACK TRAN  addsubscription
  7480.                 commit tran
  7481.             end
  7482.           RETURN (1)
  7483.        END
  7484.  
  7485.     /*
  7486.     ** If the @status was not provided determine the default value.
  7487.     ** If the @sync_type = 'none' then the subscription defaults to 'active'.
  7488.     ** Else the subscription defaults to 'subscribed'.
  7489.     */
  7490.     IF @status IS NULL
  7491.     BEGIN
  7492.         IF @sync_typeid = @none    
  7493.             SELECT @status = 'active'
  7494.         ELSE
  7495.             SELECT @status = 'subscribed'
  7496.     END
  7497.  
  7498.     /*
  7499.     ** Set publication subscription status.
  7500.     */
  7501.     EXEC @retcode = dbo.sp_changesubstatus
  7502.     @publication = @publication,
  7503.     @article     = @article,
  7504.     @subscriber  = @subscriber,
  7505.     @status      = @status,
  7506.     @destination_db = @destination_db,
  7507.     
  7508.     @frequency_type  = @frequency_type,
  7509.     @frequency_interval  = @frequency_interval,
  7510.     @frequency_relative_interval  = @frequency_relative_interval,
  7511.     @frequency_recurrence_factor  = @frequency_recurrence_factor,
  7512.     @frequency_subday  = @frequency_subday,
  7513.     @frequency_subday_interval  = @frequency_subday_interval,
  7514.     @active_start_time_of_day  = @active_start_time_of_day,
  7515.     @active_end_time_of_day  = @active_end_time_of_day,
  7516.     @active_start_date  = @active_start_date,
  7517.     @active_end_date  = @active_end_date,
  7518.     @optional_command_line = @optional_command_line,
  7519.     @distribution_jobid = @distribution_jobid OUTPUT
  7520.     IF @@error <> 0 OR @retcode <> 0
  7521.     BEGIN
  7522.         if @@trancount > 0
  7523.         begin
  7524.             ROLLBACK TRAN  addsubscription
  7525.             commit tran
  7526.         end
  7527.        RAISERROR (14057, 16, -1)
  7528.        RETURN (1)
  7529.     END
  7530.  
  7531.     UPDATE syssubscriptions SET 
  7532.         distribution_jobid = @distribution_jobid where
  7533.         artid = @artid AND
  7534.         srvid = @srvid AND
  7535.         dest_db = @destination_db            
  7536.  
  7537.     IF @@error <> 0
  7538.     BEGIN
  7539.         if @@trancount > 0
  7540.         begin
  7541.             ROLLBACK TRAN  addsubscription
  7542.             commit tran
  7543.         end
  7544.        RETURN (1)
  7545.     END
  7546.  
  7547.  
  7548.     /*
  7549.     ** If possible, activate the real subscriptions on immediate_sync publication
  7550.     ** immediately. Also, activate the virtual subscriptions on 
  7551.     ** anonymous publications immediately.
  7552.     ** We change the subscription status from 'subscribed' to 'active' so that 
  7553.     ** sp_MSupdate_subscription will be called, which will set the subscription's
  7554.     ** xactid_ts to the snapshot xactid_ts of virtual subscriptions. This means that
  7555.     ** we have to call sp_changesubstatus again here. We can not combine two calls 
  7556.     ** into ONE !!!
  7557.     **
  7558.     ** Activate the subscription immediately if 
  7559.     ** 1. The publication is immediate_sync type
  7560.     ** 2. sync_type is 'automatic'
  7561.     ** AND
  7562.     ** 1. The subscription is real
  7563.     ** 2. The snapshot has completed once
  7564.     ** 3. The subscription is the last subscription added to the publication (subscription for
  7565.     ** the last article). This is to guarantee the subscription status of all the articles
  7566.     ** in the publication be activate in one transaction at the distributor. This is
  7567.     ** to prevent the distribution agent from picking up partial subscriptions. 
  7568.     ** Note that this SP will be called with @article = 'all'
  7569.     ** OR
  7570.     ** 1. The publication is active
  7571.     ** 2. The publication is allow_anonymous
  7572.     ** 3. The subscription is virtual
  7573.     ** 
  7574.     */
  7575.     
  7576.     IF  @sync_typeid = @automatic AND @immediate_sync = 1 AND
  7577.         
  7578.         ((@srvid <> @virtual_id AND 
  7579.         @immediate_sync_ready = 1 AND
  7580.         NOT EXISTS (select * from sysarticles art where
  7581.                     art.pubid = @pubid and
  7582.                     not exists (select * from syssubscriptions sub
  7583.                         where sub.artid = art.artid and
  7584.                               sub.srvid = @srvid and
  7585.                               sub.dest_db = @destination_db))) OR
  7586.  
  7587.         (@pubstatus = 1 and @srvid = @virtual_id and @allow_anonymous = 1))
  7588.     BEGIN
  7589.         DECLARE @article_ex sysname
  7590.         IF @srvid <> @virtual_id
  7591.             SELECT @article_ex = '%'
  7592.         ELSE
  7593.             SELECT @article_ex = @article
  7594.  
  7595.         /*
  7596.         ** Set publication subscription status.
  7597.         */
  7598.         EXEC @retcode = dbo.sp_changesubstatus
  7599.         @publication = @publication,
  7600.         @article     = @article_ex,
  7601.         @subscriber  = @subscriber,
  7602.         @status      = 'active',
  7603.         @destination_db = @destination_db
  7604.  
  7605.         IF @@error <> 0 OR @retcode <> 0
  7606.         BEGIN
  7607.             if @@trancount > 0
  7608.             begin
  7609.                 ROLLBACK TRAN  addsubscription
  7610.                 commit tran
  7611.             end
  7612.            RAISERROR (14057, 16, -1)
  7613.            RETURN (1)
  7614.         END
  7615.     END
  7616.  
  7617.     /* Conditional support for MobileSync */
  7618.     if LOWER(@enabled_for_syncmgr) = 'true'
  7619.     BEGIN
  7620.         /* MobileSync Support */
  7621.         declare @distributor_server                 sysname
  7622.         declare @distributor_security_mode          int
  7623.         declare @distributor_login                  sysname
  7624.         declare @distributor_password               sysname
  7625.         declare @publisher_db sysname
  7626.         
  7627.         set @publisher_db = DB_NAME()
  7628.         /* 
  7629.         ** The registry entry needs to be created only for push subscriptions -  
  7630.         ** i.e - need not be called when a pull subscription is created at the 
  7631.         ** subscriber and sp_addmergesubscription is being called then.
  7632.         */
  7633.         IF LOWER(@subscription_type) = 'push'
  7634.         BEGIN
  7635.             EXECUTE @retcode = dbo.sp_helpdistributor
  7636.                 @distributor = @distributor_server OUTPUT               /* Distributor RPC server name */
  7637.  
  7638.             IF @@ERROR <> 0 or @retcode <> 0
  7639.                 BEGIN
  7640.                     if @@trancount > 0
  7641.                         ROLLBACK TRAN  addsubscription
  7642.                     RAISERROR (14057, 16, -1)
  7643.                     RETURN (1)
  7644.                 END
  7645.  
  7646.             -- Always use integrated security on winNT
  7647.             if (@platform_nt = platform() & @platform_nt )
  7648.                 begin
  7649.                     set @distributor_security_mode = 1
  7650.                 end
  7651.             -- For Win9x the dist publisher and distributor are the same machine                
  7652.             else
  7653.                 begin
  7654.                     select  @distributor_security_mode = 0,
  7655.                         @distributor_login  = login,
  7656.                         @distributor_password = password
  7657.                     from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername)
  7658.                 end
  7659.  
  7660.  
  7661.             /* Call sp_MSregistersubscription so that the subscription can be synchronized via Onestop etc. */
  7662.             declare @subscription_id uniqueidentifier
  7663.             set @subscription_id = convert(uniqueidentifier, @distribution_jobid)
  7664.             exec @retcode = dbo.sp_MSregistersubscription @replication_type = 1,
  7665.                                     @publisher = @@SERVERNAME,
  7666.                                     @publisher_db = @publisher_db,
  7667.                                     @publication = @publication,
  7668.                                     @subscriber = @subscriber,
  7669.                                     @subscriber_db = @destination_db,
  7670.                                     @distributor = @distributor_server,
  7671.                                     @distributor_security_mode = @distributor_security_mode,
  7672.                                     @distributor_login = @distributor_login,
  7673.                                     @distributor_password = @distributor_password,
  7674.                                     @subscription_id = @subscription_id,
  7675.                                     @independent_agent = @independent_agent_id,
  7676.                                     @subscription_type = @subscription_type_id
  7677.  
  7678.  
  7679.             IF @@ERROR <> 0 or @retcode <> 0
  7680.                 BEGIN
  7681.                     if @@trancount > 0
  7682.                         ROLLBACK TRAN  addsubscription
  7683.                     RAISERROR (14057, 16, -1)
  7684.                     RETURN (1)
  7685.                 END
  7686.         END
  7687.     END
  7688.     COMMIT TRAN
  7689. go
  7690.  
  7691. EXEC dbo.sp_MS_marksystemobject sp_addsubscription
  7692. GO
  7693.  
  7694. print ''
  7695. print 'Creating procedure sp_changearticle'
  7696. GO
  7697. CREATE PROCEDURE sp_changearticle (
  7698.     @publication sysname = NULL,        /* Publication name */
  7699.     @article sysname = NULL,            /* Article name */
  7700.     @property nvarchar(20) = NULL,           /* The property to change */
  7701.     @value nvarchar(255) = NULL              /* The new property value */
  7702.     ) AS
  7703.  
  7704.     SET NOCOUNT ON
  7705.  
  7706.     /*
  7707.     ** Declarations.
  7708.     */
  7709.  
  7710.     DECLARE @artid int
  7711.     DECLARE @cmd1 nvarchar(512)
  7712.     DECLARE @cmd2 nvarchar(512)
  7713.     DECLARE @db sysname
  7714.     DECLARE @filter int
  7715.     DECLARE @object sysname
  7716.     DECLARE @owner sysname
  7717.     DECLARE @pubid int
  7718.     DECLARE @retcode int
  7719.     DECLARE @site sysname
  7720.     DECLARE @sync_objid int
  7721.     DECLARE @typeid tinyint
  7722.     DECLARE @precmdid tinyint
  7723.     DECLARE @active tinyint
  7724.     DECLARE @virtual_id smallint
  7725.  
  7726.     DECLARE @objid    int
  7727.     DECLARE @objtype  nchar(2)
  7728.     DECLARE @old_filter_name sysname
  7729.  
  7730.     DECLARE @distributor sysname
  7731.     DECLARE @distribdb sysname
  7732.     DECLARE @dbname sysname
  7733.     DECLARE @distproc nvarchar (255)
  7734.     DECLARE @article_id int
  7735.  
  7736.     select @active = 2
  7737.     select @virtual_id = -1
  7738.  
  7739.     /*
  7740.     ** Security Check
  7741.     */
  7742.     exec @retcode = dbo.sp_MSreplcheck_publish
  7743.     if @@ERROR <> 0 or @retcode <> 0
  7744.         return(1)
  7745.  
  7746.     /*
  7747.     ** Check to see if the database has been activated for publication.
  7748.     */
  7749.  
  7750.     IF (SELECT category & 1
  7751.           FROM master..sysdatabases
  7752.          WHERE name = DB_NAME()) = 0
  7753.  
  7754.     BEGIN
  7755.             RAISERROR (14013, 16, -1)
  7756.             RETURN (1)
  7757.         END
  7758.  
  7759.  
  7760.     /*
  7761.     ** Parameter Check:  @publication.
  7762.     ** Make sure that the publication exists.
  7763.     */
  7764.  
  7765.     IF @publication IS NULL
  7766.         BEGIN
  7767.             RAISERROR (14043, 16, -1, '@publication')
  7768.             RETURN (1)
  7769.         END
  7770.  
  7771.     EXECUTE @retcode = dbo.sp_validname @publication
  7772.  
  7773.     IF @@ERROR <> 0 OR @retcode <> 0
  7774.     RETURN (1)
  7775.  
  7776.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  7777.  
  7778.     IF @pubid IS NULL
  7779.         BEGIN
  7780.             RAISERROR (20026, 11, -1, @publication)
  7781.             RETURN (1)
  7782.         END
  7783.     ELSE
  7784.  
  7785.     /*
  7786.     ** Check to see that the article exists in sysarticles.
  7787.     ** Fetch the article identification number.
  7788.     */
  7789.  
  7790.     IF @article IS NULL
  7791.         BEGIN
  7792.             RAISERROR (14043, 16, -1, '@article')
  7793.             RETURN (1)
  7794.         END
  7795.  
  7796.     /*
  7797.     EXECUTE @retcode = dbo.sp_validname @article
  7798.  
  7799.     IF @retcode <> 0
  7800.     RETURN (1)
  7801.     */
  7802.  
  7803.     SELECT @artid = artid
  7804.       FROM sysarticles
  7805.      WHERE name = @article
  7806.        AND pubid = @pubid
  7807.     IF @artid IS NULL
  7808.         BEGIN
  7809.             RAISERROR (20027, 11, -1, @article)
  7810.             RETURN (1)
  7811.         END
  7812.  
  7813.  
  7814.     /*
  7815.     ** Some options on cannot be modified if articles have active subscriptions
  7816.     ** (excluding virtual subscriptions).
  7817.     */
  7818.     IF EXISTS (SELECT * FROM syssubscriptions WHERE artid = @artid
  7819.        AND status = @active 
  7820.        AND srvid >=0
  7821.        AND @property in (N'type', N'filter')  )
  7822.         BEGIN
  7823.             RAISERROR (14092, 11, -1, @property, @article )
  7824.             RETURN (1)
  7825.         END
  7826.  
  7827.     /*
  7828.     ** Get the object id and type from sysobjects
  7829.     */
  7830.  
  7831.     SELECT @objtype = type
  7832.        FROM sysobjects
  7833.        WHERE id = ( SELECT  objid
  7834.                       FROM  sysarticles
  7835.                       WHERE artid = @artid
  7836.                       AND   pubid = @pubid )
  7837.  
  7838.     IF @objtype IS NULL
  7839.     BEGIN
  7840.         RAISERROR( 20027, 11, -1, @article )
  7841.         RETURN( 1 )
  7842.     END
  7843.  
  7844.     /*
  7845.     ** Parameter Check:  @property.
  7846.     ** If the @property parameter is NULL, print the options.
  7847.     */
  7848.  
  7849.     IF @property IS NULL
  7850.         BEGIN
  7851.             CREATE TABLE #tab1 (properties sysname NOT NULL)
  7852.             INSERT INTO #tab1 VALUES ('description')
  7853.             INSERT INTO #tab1 VALUES ('sync_object')
  7854.             INSERT INTO #tab1 VALUES ('type')
  7855.             INSERT INTO #tab1 VALUES ('ins_cmd')
  7856.             INSERT INTO #tab1 VALUES ('del_cmd')
  7857.             INSERT INTO #tab1 VALUES ('upd_cmd')
  7858.             INSERT INTO #tab1 VALUES ('filter')
  7859.             INSERT INTO #tab1 VALUES ('dest_table')
  7860.             INSERT INTO #tab1 VALUES ('dest_object')
  7861.             INSERT INTO #tab1 VALUES ('creation_script')
  7862.             INSERT INTO #tab1 VALUES ('pre_creation_cmd')
  7863.             INSERT INTO #tab1 VALUES ('status')
  7864.             INSERT INTO #tab1 VALUES ('schema_option')
  7865.             INSERT INTO #tab1 VALUES ('destination_owner')
  7866.             PRINT ''
  7867.             SELECT * FROM #tab1
  7868.             RETURN (0)
  7869.         END
  7870.  
  7871.     IF @objtype = 'U' AND LOWER(@property) NOT IN ('description',
  7872.                                                    'sync_object',
  7873.                                                    'type',
  7874.                                                    'ins_cmd',
  7875.                                                    'del_cmd',
  7876.                                                    'upd_cmd',
  7877.                                                    'filter',
  7878.                                                    'dest_table',
  7879.                                                    'dest_object',
  7880.                                                    'creation_script',
  7881.                                                    'pre_creation_cmd',
  7882.                                                    'status',
  7883.                                                    'schema_option',
  7884.                                                    'destination_owner')
  7885.         BEGIN
  7886.             RAISERROR (14022, 16, -1)
  7887.             RETURN (1)
  7888.         END
  7889.  
  7890.     IF @objtype = 'P' AND LOWER(@property) NOT IN ('description',
  7891.                                                    'dest_object',
  7892.                                                    'dest_table',
  7893.                                                    'creation_script',
  7894.                                                    'pre_creation_cmd',
  7895.                                                    'schema_option',
  7896.                                                    'destination_owner')
  7897.         BEGIN
  7898.             RAISERROR ( 14110, 16, -1 )
  7899.             RETURN (1)
  7900.         END
  7901.  
  7902.     /* dest_object and 'dest_table' are same */
  7903.     IF LOWER(@property) = 'dest_object'
  7904.         SELECT @property = 'dest_table' 
  7905.  
  7906.     /*
  7907.     ** Change the property.
  7908.     */
  7909.  
  7910.     begin tran
  7911.     save TRAN sp_changearticle
  7912.  
  7913.         IF LOWER(@property) IN ( 'description', 'ins_cmd', 'del_cmd', 'upd_cmd', 'dest_table', 'creation_script', 'dest_object')
  7914.             BEGIN
  7915.  
  7916.  
  7917.             /*
  7918.             ** Check the validity of the destination object.  NULL should
  7919.             ** get converted to the source object name.  Destination object
  7920.             ** names can be owner qualified, but not database qualified.
  7921.             */
  7922.  
  7923.             IF LOWER(@property) = 'dest_table' OR LOWER(@property) = 'dest_object'
  7924.                 BEGIN
  7925.                     IF @value IS NULL
  7926.                         SELECT @value = object_name(objid)
  7927.                           FROM sysarticles
  7928.                          WHERE artid = @artid
  7929.                            AND pubid = @pubid
  7930.                 END
  7931.  
  7932.             SELECT @cmd1 = 'UPDATE sysarticles '
  7933.  
  7934.             IF @value IS NULL
  7935.             BEGIN
  7936.                     SELECT @cmd1 = @cmd1 + '   SET ' + LOWER(@property) + ' = NULL'
  7937.                 SELECT @cmd2 = ' WHERE artid = ' + STR(@artid)
  7938.                 SELECT @cmd2 = @cmd2 + '   AND pubid = ' + STR(@pubid)
  7939.                 EXECUTE (@cmd1 + @cmd2)
  7940.             END
  7941.             ELSE
  7942.             BEGIN
  7943.                 
  7944.                 SELECT @cmd1 = @cmd1 + '   SET ' + LOWER(@property) + ' = ''' + @value + ''''
  7945.                 SELECT @cmd2 = ' WHERE artid = ' + STR(@artid)
  7946.                 SELECT @cmd2 = @cmd2 + '   AND pubid = ' + STR(@pubid)
  7947.                 EXECUTE (@cmd1 + @cmd2)
  7948.             END
  7949.  
  7950.             IF LOWER(@property) = 'upd_cmd'
  7951.             BEGIN
  7952.                 IF ( 0 <> ( SELECT PATINDEX( '%[789].[0-9]%', @@version ) ) ) OR
  7953.                    ( 0 <> ( SELECT PATINDEX( '%[1-9][0-9].[0-9]%', @@version ) ) )
  7954.                 BEGIN
  7955.                     SELECT @objid = objid FROM sysarticles
  7956.                         WHERE artid = @artid
  7957.                         AND pubid = @pubid
  7958.  
  7959.                     exec dbo.sp_MSsetfilteredstatus @objid
  7960.                 END
  7961.  
  7962.             END
  7963.  
  7964.             IF @@ERROR <> 0 
  7965.                 BEGIN
  7966.                     if @@trancount > 0
  7967.                     begin
  7968.                         ROLLBACK TRAN sp_changearticle
  7969.                         commit tran
  7970.                     end
  7971.                     RETURN (1)
  7972.                 END
  7973.             END
  7974.  
  7975.         IF LOWER(@property) = 'sync_object'
  7976.             BEGIN
  7977.  
  7978.                 /*
  7979.                 ** Check for a valid synchronization object.
  7980.                 */
  7981.  
  7982.                 IF @value IS NULL
  7983.                     BEGIN
  7984.                         RAISERROR (14043, 16, -1, '@value')
  7985.                         if @@trancount > 0
  7986.                         begin
  7987.                             ROLLBACK TRAN sp_changearticle
  7988.                             commit tran
  7989.                         end
  7990.                         RETURN (1)
  7991.                     END
  7992.  
  7993.                 IF @value LIKE '%.%.%' OR @value LIKE '%.%'
  7994.                 BEGIN
  7995.                   select @object = PARSENAME( @value, 1 )
  7996.                   select @owner = PARSENAME(  @value, 2 )
  7997.                   select @db = PARSENAME(  @value, 3 )
  7998.                   select @site = PARSENAME(  @value, 4 )
  7999.  
  8000.                   if @object IS NULL
  8001.                         return 1
  8002.                 END
  8003.  
  8004.  
  8005.                 SELECT @sync_objid = OBJECT_ID(@value)
  8006.                 IF @sync_objid IS NULL
  8007.                     BEGIN
  8008.                         RAISERROR (15001, 11, -1, @value)
  8009.                         if @@trancount > 0
  8010.                         begin
  8011.                             ROLLBACK TRAN sp_changearticle
  8012.                             commit tran
  8013.                         end
  8014.                         RETURN (1)
  8015.                     END
  8016.  
  8017.                 IF NOT EXISTS (SELECT *
  8018.                                  FROM sysobjects
  8019.                                 WHERE type IN ('U', 'V')
  8020.                                   AND id = @sync_objid)
  8021.  
  8022.                     BEGIN
  8023.                         RAISERROR (14031, 16, -1)
  8024.                         if @@trancount > 0
  8025.                         begin
  8026.                             ROLLBACK TRAN sp_changearticle
  8027.                             commit tran
  8028.                         end
  8029.                         RETURN (1)
  8030.                     END
  8031.  
  8032.                 /*
  8033.                 ** Update the article with the new synchronization object.
  8034.                 */
  8035.  
  8036.                 UPDATE sysarticles
  8037.                    SET sync_objid = @sync_objid
  8038.                  WHERE artid = @artid
  8039.                    AND pubid = @pubid
  8040.  
  8041.                 IF @@ERROR <> 0 
  8042.                 BEGIN
  8043.                     if @@trancount > 0
  8044.                     begin
  8045.                         ROLLBACK TRAN sp_changearticle
  8046.                         commit tran
  8047.                     end
  8048.                     RETURN (1)
  8049.                 END
  8050.  
  8051.             END
  8052.  
  8053.         IF LOWER(@property) = 'type'
  8054.             BEGIN
  8055.  
  8056.                 /*
  8057.                 ** Check to make sure that we have a valid type.
  8058.                 */
  8059.  
  8060.             IF LOWER(@value) NOT IN ('logbased', 'logbased manualfilter', 'logbased manualview', 'logbased manualboth')
  8061.                     BEGIN
  8062.                         RAISERROR (14023, 16, -1)
  8063.                         if @@trancount > 0
  8064.                         begin
  8065.                             ROLLBACK TRAN sp_changearticle
  8066.                             commit tran
  8067.                         end
  8068.                         RETURN (1)
  8069.                     END
  8070.  
  8071.                 /*
  8072.                 ** Determine the integer value for the type.
  8073.                 */
  8074.             IF LOWER(@value) = 'logbased'
  8075.             SELECT @typeid = 1
  8076.             ELSE IF LOWER(@value) = 'logbased manualfilter'
  8077.             SELECT @typeid = 3
  8078.             ELSE IF LOWER(@value) = 'logbased manualview'
  8079.             SELECT @typeid = 5
  8080.             ELSE IF LOWER(@value) = 'logbased manualboth'
  8081.             SELECT @typeid = 7
  8082.  
  8083.                 /*
  8084.                 ** Update the article with the new type.
  8085.                 */
  8086.  
  8087.                 UPDATE sysarticles
  8088.                    SET type = @typeid
  8089.                  WHERE artid = @artid
  8090.                    AND pubid = @pubid
  8091.  
  8092.                 IF @@ERROR <> 0 
  8093.                 BEGIN
  8094.                     if @@trancount > 0
  8095.                     begin   
  8096.                         ROLLBACK TRAN sp_changearticle
  8097.                         commit tran
  8098.                     end
  8099.                     RETURN (1)
  8100.                 END
  8101.  
  8102.  
  8103.             END
  8104.  
  8105.         IF LOWER(@property) = 'filter'
  8106.             BEGIN
  8107.  
  8108.                 /*
  8109.                 ** Check for a valid filter value.
  8110.                 */
  8111.  
  8112.                 IF @value IS NOT NULL
  8113.                     BEGIN
  8114.  
  8115.                         IF @value LIKE '%.%.%' OR @value LIKE '%.%'
  8116.                         BEGIN
  8117.                            select @object = PARSENAME( @value, 1 )
  8118.                            select @owner = PARSENAME(  @value, 2 )
  8119.                            select @db = PARSENAME(  @value, 3 )
  8120.                            select @site = PARSENAME(  @value, 4 )
  8121.  
  8122.                            if @object IS NULL
  8123.                                  return 1
  8124.                         END
  8125.  
  8126.                     END
  8127.  
  8128.                 SELECT @filter = OBJECT_ID(@value)
  8129.  
  8130.                 IF @value IS NOT NULL
  8131.                     BEGIN
  8132.  
  8133.                         IF @filter IS NULL
  8134.                             BEGIN
  8135.                                 RAISERROR (15001, 11, -1, @value)
  8136.                                 if @@trancount > 0
  8137.                                 begin
  8138.                                     ROLLBACK TRAN sp_changearticle
  8139.                                     commit tran
  8140.                                 end
  8141.                                 RETURN (1)
  8142.                             END
  8143.  
  8144.                         IF NOT EXISTS (SELECT *
  8145.                                          FROM sysobjects
  8146.                                         WHERE type = 'RF'
  8147.                                           AND id = @filter)
  8148.  
  8149.                             BEGIN
  8150.                                 RAISERROR (14049, 16, -1)
  8151.                                 if @@trancount > 0
  8152.                                 begin
  8153.                                     ROLLBACK TRAN sp_changearticle
  8154.                                     commit tran
  8155.                                 end
  8156.                                 RETURN (1)
  8157.                             END
  8158.  
  8159.                     END
  8160.  
  8161.                 IF @value IS NULL SELECT @filter = 0
  8162.  
  8163.                 -----------------------------
  8164.                 -- save off the old filter
  8165.                 -----------------------------
  8166.  
  8167.                 SELECT @old_filter_name = object_name( filter )
  8168.                 FROM sysarticles WHERE artid = @artid
  8169.                 AND pubid = @pubid
  8170.  
  8171.                 IF @@ERROR <> 0 
  8172.                 BEGIN
  8173.                     if @@trancount > 0
  8174.                     begin
  8175.                         ROLLBACK TRAN sp_changearticle
  8176.                         commit tran
  8177.                     end
  8178.                     RETURN (1)
  8179.                 END
  8180.  
  8181.                 --------------------------------------------
  8182.                 -- Update the article with the new filter.
  8183.                 --------------------------------------------
  8184.  
  8185.                 UPDATE sysarticles
  8186.                    SET filter = @filter
  8187.                  WHERE artid = @artid
  8188.                    AND pubid = @pubid
  8189.  
  8190.                 IF @@ERROR <> 0 
  8191.                 BEGIN
  8192.                     if @@trancount > 0
  8193.                     begin
  8194.                         ROLLBACK TRAN sp_changearticle
  8195.                         commit tran
  8196.                     end
  8197.                     RETURN (1)
  8198.                 END
  8199.  
  8200.                 -- SQL SERVER > 7.x ONLY  disassociate old filter with table
  8201.                 -- and associate new one
  8202.  
  8203.                 IF ( 0 <> ( SELECT PATINDEX( '%[789].[0-9]%', @@version ) ) ) OR
  8204.                    ( 0 <> ( SELECT PATINDEX( '%[1-9][0-9].[0-9]%', @@version ) ) )   
  8205.                 BEGIN
  8206.  
  8207.                     ------------------------------------------
  8208.                     -- disassociate table from old filter proc
  8209.                     ------------------------------------------
  8210.  
  8211.                     EXEC dbo.sp_MSsetfilterparent @old_filter_name, 0
  8212.  
  8213.                     IF @@ERROR <> 0
  8214.                     BEGIN
  8215.                         if @@trancount > 0
  8216.                         begin
  8217.                             ROLLBACK TRAN sp_changearticle
  8218.                             commit tran
  8219.                         end
  8220.                         RETURN (1)
  8221.                     END
  8222.  
  8223.                     ------------------------------------
  8224.                     -- get the table id from sysarticles
  8225.                     ------------------------------------
  8226.  
  8227.                     SELECT @objid = objid
  8228.                     FROM sysarticles
  8229.                     WHERE artid = @artid
  8230.                     AND pubid = @pubid
  8231.  
  8232.                     IF @@ERROR <> 0
  8233.                     BEGIN
  8234.                         if @@trancount > 0
  8235.                         begin
  8236.                             ROLLBACK TRAN sp_changearticle
  8237.                             commit tran
  8238.                         end
  8239.                         RETURN (1)
  8240.                     END
  8241.  
  8242.                     ------------------------------------------------------
  8243.                     -- set the parent of the filter proc to this object_id
  8244.                     ------------------------------------------------------
  8245.  
  8246.                     EXEC dbo.sp_MSsetfilterparent @value, @objid
  8247.  
  8248.                     IF @@ERROR <> 0
  8249.                     BEGIN
  8250.                         if @@trancount > 0
  8251.                         begin
  8252.                             ROLLBACK TRAN sp_changearticle
  8253.                             commit tran
  8254.                         end
  8255.                         RETURN (1)
  8256.                     END
  8257.                 END
  8258.  
  8259.             END
  8260.  
  8261.         IF LOWER(@property) = 'pre_creation_cmd'
  8262.             BEGIN
  8263.  
  8264.                 /*
  8265.                 ** Check to make sure that we have a valid pre_creation_cmd.
  8266.                 */
  8267.             IF @objtype = 'P' and LOWER(@value) NOT IN ('none', 'drop')
  8268.                 BEGIN
  8269.                     RAISERROR ( 14111, 16, -1 )
  8270.                     if @@trancount > 0
  8271.                     begin   
  8272.                         ROLLBACK TRAN sp_changearticle
  8273.                         commit tran
  8274.                     end
  8275.                     RETURN (1)
  8276.                 END
  8277.  
  8278.                 IF LOWER(@value) NOT IN ('none', 'drop', 'delete', 'truncate')
  8279.                     BEGIN
  8280.                         RAISERROR (14061, 16, -1)
  8281.                         if @@trancount > 0
  8282.                         begin
  8283.                             ROLLBACK TRAN sp_changearticle
  8284.                             commit tran
  8285.                         end
  8286.                         RETURN (1)
  8287.                     END
  8288.  
  8289.                 /*
  8290.                 ** Determine the integer value for the type.
  8291.                 */
  8292.  
  8293.                 IF LOWER(@value) = 'none'
  8294.                     SELECT @precmdid = 0
  8295.                 ELSE IF LOWER(@value) = 'drop'
  8296.                     SELECT @precmdid = 1
  8297.                 ELSE IF LOWER(@value) = 'delete'
  8298.                     SELECT @precmdid = 2
  8299.                 ELSE IF LOWER(@value) = 'truncate'
  8300.                     SELECT @precmdid = 3
  8301.  
  8302.                 /*
  8303.                 ** Update the article with the new pre_creation_cmd.
  8304.                 */
  8305.                 UPDATE sysarticles
  8306.                    SET pre_creation_cmd = @precmdid
  8307.                  WHERE artid = @artid
  8308.                    AND pubid = @pubid
  8309.  
  8310.                 IF @@ERROR <> 0 
  8311.                     BEGIN
  8312.                         if @@trancount > 0
  8313.                         begin
  8314.                             ROLLBACK TRAN sp_changearticle
  8315.                             commit tran
  8316.                         end
  8317.                         RETURN (1)
  8318.                     END
  8319.  
  8320.             END
  8321.  
  8322.         IF LOWER(@property) = 'status'
  8323.             BEGIN
  8324.                 /*
  8325.                 ** Check to make sure that we have a valid type.
  8326.                 */
  8327.  
  8328.                 IF LOWER(@value) IN ('not owner qualified', 'owner qualified')
  8329.                     BEGIN
  8330.                         RAISERROR (21023, 16, -1,@value)
  8331.                         if @@trancount > 0
  8332.                         begin
  8333.                             ROLLBACK TRAN sp_changearticle
  8334.                             commit tran
  8335.                         end
  8336.                         RETURN (1)
  8337.                     END
  8338.  
  8339.                 IF LOWER(@value) NOT IN ('no column names', 'include column names', 'string literals', 'parameters' )
  8340.                     BEGIN
  8341.                         RAISERROR (14097, 16, -1)
  8342.                         if @@trancount > 0
  8343.                         begin
  8344.                             ROLLBACK TRAN sp_changearticle
  8345.                             commit tran
  8346.                         end                        
  8347.                         RETURN (1)
  8348.                     END
  8349.  
  8350.                 /*
  8351.                 ** Determine the integer value for the type.
  8352.                 */
  8353.                 IF LOWER(@value) = 'not owner qualified'
  8354.                     UPDATE sysarticles 
  8355.                     SET status = status & ~4
  8356.                     WHERE artid = @artid
  8357.                                   AND pubid = @pubid
  8358.  
  8359.                 ELSE IF LOWER(@value) = 'owner qualified'
  8360.                     UPDATE sysarticles 
  8361.                     SET status = status | 4
  8362.                     WHERE artid = @artid
  8363.                                   AND pubid = @pubid
  8364.                      
  8365.                 ELSE IF LOWER(@value) = 'no column names'
  8366.                     UPDATE sysarticles 
  8367.                     SET status = status & ~8
  8368.                     WHERE artid = @artid
  8369.                                   AND pubid = @pubid
  8370.                      
  8371.                 ELSE IF LOWER(@value) = 'include column names'
  8372.                     UPDATE sysarticles 
  8373.                     SET status = status | 8
  8374.                     WHERE artid = @artid
  8375.                                   AND pubid = @pubid
  8376.  
  8377.                 ELSE IF LOWER(@value) = 'string literals'
  8378.                     UPDATE sysarticles 
  8379.                     SET status = status & ~16
  8380.                     WHERE artid = @artid
  8381.                                   AND pubid = @pubid
  8382.                      
  8383.                 ELSE IF LOWER(@value) = 'parameters'
  8384.                     UPDATE sysarticles 
  8385.                     SET status = status | 16
  8386.                     WHERE artid = @artid
  8387.                                   AND pubid = @pubid
  8388.                 
  8389.                 IF @@ERROR <> 0 
  8390.                     BEGIN
  8391.                         if @@trancount > 0
  8392.                         begin
  8393.                             ROLLBACK TRAN sp_changearticle
  8394.                             commit tran
  8395.                         end
  8396.                         RETURN (1)
  8397.                     END
  8398.             END
  8399.  
  8400.         IF LOWER(@property) = 'schema_option'
  8401.             BEGIN
  8402.                 IF @value IS NULL
  8403.                     BEGIN
  8404.                         RAISERROR(14146, 16,1)
  8405.                         if @@trancount > 0
  8406.                         begin
  8407.                             ROLLBACK TRAN sp_changearticle
  8408.                             commit tran
  8409.                         end
  8410.                         RETURN (1)
  8411.                     END
  8412.  
  8413.                 CREATE TABLE #tab_changearticle (value binary(8) NULL)
  8414.                                      
  8415.                 IF @@ERROR <> 0 
  8416.                     BEGIN
  8417.                         if @@trancount > 0
  8418.                         begin
  8419.                             ROLLBACK TRAN sp_changearticle
  8420.                             commit tran
  8421.                         end
  8422.                         RETURN (1)
  8423.                     END
  8424.  
  8425.                 EXEC ('insert #tab_changearticle values (' + 
  8426.                         @value +')' )
  8427.                                      
  8428.                 IF @@ERROR <> 0 
  8429.                     BEGIN
  8430.                         if @@trancount > 0
  8431.                         begin
  8432.                             ROLLBACK TRAN sp_changearticle
  8433.                             commit tran
  8434.                         end
  8435.                         RETURN (1)
  8436.                     END
  8437.                 
  8438.                 IF @objtype = 'P' AND EXISTS (SELECT * from #tab_changearticle 
  8439.                     WHERE value <> 0x0000000000000000 AND
  8440.                           value <> 0x0000000000000001 )
  8441.                     BEGIN
  8442.                         RAISERROR ( 20014, 16, -1 )
  8443.                         if @@trancount > 0
  8444.                         begin
  8445.                             ROLLBACK TRAN sp_changearticle
  8446.                             commit tran
  8447.                         end
  8448.                         RETURN (1)
  8449.                     END
  8450.                
  8451.  
  8452.                 UPDATE sysarticles SET schema_option = tab.value from 
  8453.                     #tab_changearticle tab WHERE artid = @artid
  8454.                                   AND pubid = @pubid
  8455.                 DROP TABLE #tab_changearticle 
  8456.                                      
  8457.                 IF @@ERROR <> 0 
  8458.                     BEGIN
  8459.                         if @@trancount > 0
  8460.                         begin
  8461.                             ROLLBACK TRAN sp_changearticle
  8462.                             commit tran
  8463.                         end
  8464.                         RETURN (1)
  8465.                     END
  8466.  
  8467.             END
  8468.  
  8469.         IF LOWER(@property) = 'destination_owner'
  8470.             BEGIN
  8471.                 IF @value IS NOT NULL
  8472.                 BEGIN
  8473.                     /*
  8474.                     ** The destination_owner must conform to the rules
  8475.                     ** for identifiers.
  8476.                     */
  8477.  
  8478.                     EXECUTE @retcode = dbo.sp_validname @value
  8479.  
  8480.                     IF @retcode <> 0
  8481.                     RETURN (1)
  8482.                 END
  8483.  
  8484.                 UPDATE sysarticles SET dest_owner = @value from 
  8485.                     sysarticles WHERE artid = @artid
  8486.                                   AND pubid = @pubid
  8487.                                      
  8488.                 IF @@ERROR <> 0 
  8489.                     BEGIN
  8490.                         if @@trancount > 0
  8491.                         begin
  8492.                             ROLLBACK TRAN sp_changearticle
  8493.                             commit tran
  8494.                         end
  8495.                         RETURN (1)
  8496.                     END
  8497.  
  8498.             END
  8499.  
  8500.  
  8501.         -------------------------------------------------------------------------
  8502.         -- some info on articles is also stored at the distributor.
  8503.         -- update info at distributor if these properties change
  8504.         -------------------------------------------------------------------------
  8505.  
  8506.         if @property in ( N'description', N'dest_table', N'dest_object' )
  8507.         BEGIN
  8508.             /*
  8509.             ** Get distribution server information for remote RPC call.
  8510.             */
  8511.             EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  8512.                @distribdb   = @distribdb OUTPUT
  8513.             IF @@ERROR <> 0 or @retcode <> 0
  8514.             BEGIN
  8515.                 RAISERROR (14071, 16, -1)
  8516.                 if @@trancount > 0
  8517.                 begin
  8518.                     ROLLBACK TRAN sp_changearticle
  8519.                     commit tran
  8520.                 end
  8521.                 RETURN (1)
  8522.             END
  8523.  
  8524.             SELECT @dbname =  DB_NAME()
  8525.             SELECT @article_id = artid from sysarticles where name = @article
  8526.  
  8527.             SELECT @distproc = RTRIM(@distributor) + '.' + @distribdb + 
  8528.                 '.dbo.sp_MSchange_article'
  8529.             EXECUTE @retcode = @distproc
  8530.                 @publisher = @@SERVERNAME,
  8531.                 @publisher_db = @dbname,
  8532.                 @publication = @publication,
  8533.                 @article = @article,
  8534.                 @article_id = @article_id,
  8535.                 @property = @property,
  8536.                 @value = @value
  8537.  
  8538.  
  8539.             IF @@ERROR <> 0 OR @retcode <> 0
  8540.             BEGIN
  8541.                 if @@trancount > 0
  8542.                 begin
  8543.                     ROLLBACK TRAN sp_changearticle
  8544.                     commit tran
  8545.                 end
  8546.                 RETURN (1)
  8547.             END
  8548.         END
  8549.  
  8550.     COMMIT TRAN
  8551.  
  8552.     /*
  8553.     ** Force the article cache to be refreshed with the new definition.
  8554.     */
  8555.     EXECUTE dbo.sp_replflush
  8556.  
  8557.     /*
  8558.     ** Return succeed.
  8559.     */
  8560.  
  8561.     RAISERROR (14025, 10, -1)
  8562.     RETURN (0)
  8563. go
  8564.  
  8565. dump tran master with no_log
  8566. go
  8567.  
  8568. EXEC dbo.sp_MS_marksystemobject sp_changearticle
  8569. GO
  8570.  
  8571. print ''
  8572. print 'Creating procedure sp_droparticle'
  8573. go
  8574.  
  8575. CREATE PROCEDURE sp_droparticle(
  8576.         @publication sysname,     /* The publication name */
  8577.         @article sysname,          /* The article name */
  8578.         @ignore_distributor bit = 0
  8579.         ) AS
  8580.  
  8581.     /*
  8582.     ** Declarations.
  8583.     */
  8584.  
  8585.     DECLARE @cmd nvarchar(255)
  8586.     DECLARE @objid int
  8587.     DECLARE @pubid int
  8588.     DECLARE @publish_bit smallint
  8589.     DECLARE @retcode int
  8590.     DECLARE @filter_name sysname
  8591.     DECLARE @view_name sysname
  8592.     DECLARE @type tinyint
  8593.     DECLARE @procnum smallint
  8594.     DECLARE @virtual_id smallint
  8595.     DECLARE @push tinyint
  8596.     DECLARE @distributor sysname
  8597.     DECLARE @distribdb sysname
  8598.     DECLARE @distproc nvarchar (255)
  8599.     DECLARE @dbname sysname
  8600.     -- SyncTran
  8601.     DECLARE @allow_sync_tran_id bit
  8602.     declare @artid int, @insproc_id int, @updproc_id int, @delproc_id int
  8603.     declare @insproc sysname, @updproc sysname, @delproc sysname
  8604.     declare @filter_id int
  8605.     declare @view_id int
  8606.  
  8607.  
  8608.     SET NOCOUNT ON
  8609.  
  8610.     /*
  8611.     ** Initializations.
  8612.     */
  8613.  
  8614.     SELECT @virtual_id = -1     /* Const: virtual subscriber id */
  8615.  
  8616.     SELECT @publish_bit = 1
  8617.  
  8618.     /*
  8619.     ** Security Check.
  8620.     */
  8621.     exec @retcode = dbo.sp_MSreplcheck_publish
  8622.     if @@ERROR <> 0 or @retcode <> 0
  8623.         return(1)
  8624.  
  8625.     /*
  8626.     ** Parameter Check: @publication.
  8627.     ** The @publication name must conform to the rules for identifiers.
  8628.     */
  8629.  
  8630.     IF @publication IS NULL
  8631.         BEGIN
  8632.             RAISERROR (14043, 16, -1, '@publication')
  8633.             RETURN (1)
  8634.         END
  8635.  
  8636.     EXECUTE @retcode = dbo.sp_validname @publication
  8637.  
  8638.     IF @retcode <> 0
  8639.     RETURN (1)
  8640.  
  8641.     IF NOT EXISTS (SELECT * FROM syspublications WHERE name = @publication)
  8642.         BEGIN
  8643.             RAISERROR (20026, 11, -1, @publication)
  8644.             RETURN (1)
  8645.         END
  8646.  
  8647.  
  8648.     /*
  8649.     ** Get the @pubid.
  8650.     */
  8651.  
  8652.     -- SyncTran
  8653.     --SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  8654.     SELECT @pubid = pubid, @allow_sync_tran_id = allow_sync_tran 
  8655.     FROM syspublications WHERE name = @publication
  8656.  
  8657.     /*
  8658.     ** Parameter Check:  @article.
  8659.     ** If the @article is 'all', drop all articles for the specified
  8660.     ** publication (@publication).
  8661.     */
  8662.  
  8663.     IF LOWER(@article) = 'all'
  8664.         BEGIN
  8665.             DECLARE hC  CURSOR LOCAL FAST_FORWARD FOR 
  8666.                 SELECT DISTINCT  name FROM sysarticles 
  8667.                     WHERE pubid = @pubid
  8668.             OPEN hC
  8669.             FETCH hC INTO @article
  8670.             WHILE (@@fetch_status <> -1)
  8671.                 BEGIN
  8672.                     EXECUTE dbo.sp_droparticle 
  8673.                         @publication = @publication, 
  8674.                         @article = @article,
  8675.                         @ignore_distributor = @ignore_distributor
  8676.                     FETCH hC INTO @article
  8677.                 END
  8678.             CLOSE hC
  8679.             DEALLOCATE hC
  8680.             RETURN (0)
  8681.         END
  8682.  
  8683.     /*
  8684.     ** Parameter Check: @article.
  8685.     ** The @article name must conform to the rules for identifiers.
  8686.     */
  8687.  
  8688.     IF @article IS NULL
  8689.         BEGIN
  8690.             RAISERROR (14043, 16, -1, '@article')
  8691.             RETURN (1)
  8692.         END
  8693.  
  8694.     /*
  8695.     EXECUTE @retcode = dbo.sp_validname @article
  8696.  
  8697.     IF @retcode <> 0
  8698.     RETURN (1)
  8699.     */
  8700.  
  8701.     /*
  8702.     ** Ascertain the existence of the article.
  8703.     */
  8704.  
  8705.     IF NOT EXISTS (SELECT *
  8706.                      FROM sysarticles
  8707.                     WHERE name = @article
  8708.                       AND pubid = @pubid)
  8709.         BEGIN
  8710.             RAISERROR (20027, 11, -1, @article)
  8711.         RETURN (1)
  8712.         END
  8713.  
  8714.     /*
  8715.     ** Check to make sure that there are no 'real' subscriptions on the article.
  8716.     */
  8717.  
  8718.     IF EXISTS (SELECT *
  8719.                  FROM syssubscriptions, sysarticles
  8720.                 WHERE sysarticles.name = @article
  8721.                   AND sysarticles.pubid = @pubid
  8722.                   AND sysarticles.artid = syssubscriptions.artid
  8723.                   AND syssubscriptions.srvid <> @virtual_id)
  8724.         BEGIN
  8725.             RAISERROR (14046, 16, -1)
  8726.             RETURN (1)
  8727.         END
  8728.  
  8729.     -- SyncTran
  8730.     /*
  8731.     ** If allow_sync_procs option turned on for the publication, retrieve info from sysarticle updates
  8732.     */
  8733.     if @allow_sync_tran_id = 1 
  8734.     begin
  8735.         select @artid = artid from sysarticles where name = @article and pubid = @pubid
  8736.  
  8737.         select @insproc_id = sync_ins_proc, @updproc_id = sync_upd_proc, @delproc_id = sync_del_proc
  8738.         from sysarticleupdates
  8739.         where artid = @artid and pubid = @pubid 
  8740.     end
  8741.     -- end SyncTran
  8742.  
  8743.         /*
  8744.         ** Retrieve the object id of the underlying table.
  8745.         */
  8746.  
  8747.         SELECT @objid = objid, @type = type
  8748.           FROM sysarticles
  8749.          WHERE name = @article
  8750.            AND pubid = @pubid
  8751.  
  8752.     begin tran
  8753.     save TRAN droparticle
  8754.  
  8755.         /* Drop virtual subscription first for @immediate_sync publications
  8756.            */
  8757.         if EXISTS (SELECT * FROM syspublications WHERE
  8758.             name = @publication    AND
  8759.             immediate_sync = 1)
  8760.         BEGIN
  8761.             EXECUTE @retcode  = dbo.sp_dropsubscription 
  8762.                 @publication = @publication, 
  8763.                 @article = @article,
  8764.                 @subscriber = NULL,
  8765.                 @ignore_distributor = @ignore_distributor,
  8766.                 @reserved = 'internal'
  8767.             IF @@ERROR <> 0 OR @retcode <> 0
  8768.             BEGIN
  8769.                 if @@trancount > 0
  8770.                 begin
  8771.                     ROLLBACK TRAN droparticle
  8772.                     commit tran
  8773.                 end
  8774.                 RETURN (1)
  8775.             END
  8776.         END
  8777.  
  8778.         /* Drop article at the distributor side */
  8779.         /*
  8780.         ** if @ignore_distributor = 1, we are in bruteforce cleanup mode, don't do RPC.
  8781.         */
  8782.         if @ignore_distributor = 0
  8783.         begin
  8784.  
  8785.             /*
  8786.             ** Get distribution server information for remote RPC call.
  8787.             */
  8788.             EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  8789.                @distribdb   = @distribdb OUTPUT
  8790.             IF @@ERROR <> 0 or @retcode <> 0
  8791.                 BEGIN
  8792.                     RETURN (1)
  8793.                 END
  8794.  
  8795.             SELECT @dbname =  DB_NAME()
  8796.         
  8797.             SELECT @distproc = RTRIM(@distributor) + '.' + @distribdb + 
  8798.                 '.dbo.sp_MSdrop_article'
  8799.             EXECUTE @retcode = @distproc
  8800.                 @publisher = @@SERVERNAME,
  8801.                 @publisher_db = @dbname,
  8802.                 @publication = @publication,
  8803.                 @article = @article
  8804.  
  8805.             IF @@ERROR <> 0 OR @retcode <> 0
  8806.             BEGIN
  8807.                 if @@trancount > 0
  8808.                     ROLLBACK TRAN 
  8809.                 RETURN (1)
  8810.             END
  8811.         end
  8812.         
  8813.         /*
  8814.         **  Delete article from sysarticles and clear publish bit in
  8815.         **  sysobjects.
  8816.         */
  8817.  
  8818.  
  8819.         /*
  8820.         ** If this article is the only one that references this object,
  8821.         ** then we can safely turn off the publish bit in sysobjects.
  8822.         */
  8823.  
  8824.         IF NOT EXISTS (SELECT *
  8825.                          FROM sysarticles
  8826.                         WHERE objid = @objid
  8827.                           AND NOT (name = @article AND pubid = @pubid))
  8828.             BEGIN
  8829.  
  8830.             UPDATE sysobjects SET replinfo = replinfo & ~ @publish_bit 
  8831.                 WHERE id = (SELECT objid FROM sysarticles WHERE name = @article 
  8832.                     AND pubid =  @pubid) 
  8833.  
  8834.             /*
  8835.             EXEC (@cmd)
  8836.  
  8837.             IF @@ERROR <> 0
  8838.                 BEGIN
  8839.                     if @@trancount > 0
  8840.                         ROLLBACK TRAN
  8841.                     RAISERROR (14047, 16, -1, @article)
  8842.                     RETURN (1)
  8843.                 END
  8844.             */
  8845.  
  8846.             END
  8847.  
  8848.         /*
  8849.         ** Drop article view if not logbased manualview (type = 5)
  8850.         */
  8851.     IF (@type & 5) = 1
  8852.        BEGIN    
  8853.         SELECT @view_id = sysobjects.id
  8854.             FROM sysarticles, sysobjects
  8855.          WHERE sysarticles.name = @article
  8856.            AND pubid = @pubid
  8857.            AND sync_objid = sysobjects.id
  8858.            AND sysobjects.type = 'V'
  8859.         exec sp_MSget_qualified_name @view_id, @view_name OUTPUT
  8860.  
  8861.        END
  8862.  
  8863.         /*
  8864.         ** Drop article filter if not logbased manualfilter (type = 3)
  8865.         */
  8866.     IF (@type & 3) = 1
  8867.        BEGIN    
  8868.         SELECT @filter_id = sysobjects.id
  8869.             FROM sysarticles, sysobjects
  8870.          WHERE sysarticles.name = @article
  8871.            AND pubid = @pubid
  8872.            AND filter = sysobjects.id
  8873.            AND sysobjects.type = 'RF'
  8874.  
  8875.         exec sp_MSget_qualified_name @filter_id, @filter_name OUTPUT
  8876.        
  8877.        END
  8878.  
  8879.  
  8880.         IF( @type & 3 ) = 3
  8881.         BEGIN
  8882.             select @filter_id =  filter from sysarticles
  8883.             where name = @article and pubid = @pubid
  8884.  
  8885.             exec sp_MSget_qualified_name @filter_id, @filter_name OUTPUT
  8886.  
  8887.             if @filter_name is not null
  8888.                 EXEC dbo.sp_MSsetfilterparent @filter_name, 0
  8889.             
  8890.             -- Clear base table dependency on the filter
  8891.             EXEC dbo.sp_MSsetfilteredstatus @objid
  8892.  
  8893.             -- This is a manual filter, we should not drop it automatically
  8894.             -- since it is not created by us.
  8895.             -- Set @filter_id to null so the object will not be dropped later.
  8896.             select @filter_name = null
  8897.  
  8898.         END
  8899.  
  8900.  
  8901.     /*
  8902.     ** If this is a table based article, Drop all article columns.
  8903.         ** This is done to force all Text\Image column status to be updated.
  8904.     */
  8905.  
  8906.         IF (@type & 8) != 8
  8907.         BEGIN
  8908.  
  8909.     -- propagate @ignore_distributor to sp_articlecolumn to allow forced cleanup
  8910.     EXECUTE @retcode  = dbo.sp_articlecolumn @publication, @article,
  8911.        @operation = 'drop', @ignore_distributor = @ignore_distributor
  8912.        -- synctran
  8913.         , @refresh_synctran_procs = 0
  8914.         IF @@ERROR <> 0 OR @retcode <> 0
  8915.        BEGIN
  8916.             if @@trancount > 0
  8917.             begin
  8918.                 ROLLBACK TRAN droparticle
  8919.                 commit tran
  8920.             end
  8921.             RETURN (1)
  8922.        END
  8923.         END
  8924.  
  8925.  
  8926.         /*
  8927.         ** Remove the row from sysarticles.
  8928.         */
  8929.         DELETE
  8930.           FROM sysarticles
  8931.          WHERE name = @article
  8932.            AND pubid = @pubid
  8933.  
  8934.         IF @@ERROR <> 0
  8935.         BEGIN
  8936.             if @@trancount > 0
  8937.                 ROLLBACK TRAN 
  8938.             RAISERROR (14047, 16, -1, @article)
  8939.             RETURN (1)
  8940.         END
  8941.  
  8942.         -- SyncTran
  8943.         /*
  8944.         ** Drop associated sync tran procs and entries in sysarticle updates
  8945.         */
  8946.         if @allow_sync_tran_id = 1
  8947.         begin
  8948.             exec @retcode = dbo.sp_MSdrop_object 
  8949.                 @object_id = @insproc_id
  8950.             if @retcode <> 0 or @@error <> 0
  8951.                 goto UNDO
  8952.  
  8953.             exec @retcode = dbo.sp_MSdrop_object 
  8954.                 @object_id = @updproc_id
  8955.             if @retcode <> 0 or @@error <> 0
  8956.                 goto UNDO
  8957.  
  8958.             exec @retcode = dbo.sp_MSdrop_object 
  8959.                 @object_id = @delproc_id
  8960.             if @retcode <> 0 or @@error <> 0
  8961.                 goto UNDO
  8962.             
  8963.             delete from sysarticleupdates where artid = @artid and pubid = @pubid
  8964.             if @@ERROR <> 0 begin
  8965.                 if @@trancount > 0
  8966.                     ROLLBACK TRAN
  8967.                 RETURN (1)
  8968.             end
  8969.         end
  8970.         -- end SyncTran
  8971.  
  8972.  
  8973.     COMMIT TRAN
  8974.  
  8975.     IF @view_name IS NOT NULL
  8976.     BEGIN
  8977.         -- @view_name is already quoted.
  8978.         SELECT @cmd = 'drop view ' + @view_name
  8979.         exec (@cmd)
  8980.     END
  8981.  
  8982.     IF @filter_name IS NOT NULL
  8983.     BEGIN
  8984.         -- @filter_name is already quoted.
  8985.         SELECT @cmd = 'drop proc ' + @filter_name
  8986.         exec (@cmd)
  8987.     END
  8988.     /*
  8989.     ** Force the article cache to be refreshed; only if needed
  8990.     */
  8991.     if ( @ignore_distributor = 0 )
  8992.         EXECUTE dbo.sp_replflush
  8993.  
  8994.     return (0)
  8995.  
  8996. UNDO:
  8997.     if @@trancount <> 0
  8998.         rollback tran
  8999.  
  9000. go
  9001.  
  9002. EXEC dbo.sp_MS_marksystemobject sp_droparticle
  9003. GO
  9004.  
  9005. print ''
  9006. print 'Creating procedure sp_droppublication'
  9007. go
  9008.  
  9009. CREATE PROCEDURE sp_droppublication(
  9010.         @publication sysname,       /* The publication name */
  9011.         @ignore_distributor bit = 0
  9012.         ) AS
  9013.  
  9014.     /*
  9015.     ** Declarations.
  9016.     */
  9017.  
  9018.     DECLARE @article sysname
  9019.     DECLARE @cmd nvarchar(255)
  9020.     DECLARE @retcode int
  9021.     DECLARE @distributor sysname
  9022.     DECLARE @distribdb sysname
  9023.     DECLARE @distproc nvarchar (255)
  9024.     DECLARE @agentname nvarchar (40)
  9025.     DECLARE @dbname sysname
  9026.     DECLARE @virtual_id smallint
  9027.  
  9028.     SELECT @virtual_id = -1
  9029.     select @dbname = db_name()
  9030.  
  9031.     /*
  9032.     ** Security check
  9033.     */
  9034.     exec @retcode = dbo.sp_MSreplcheck_publish
  9035.     if @@ERROR <> 0 or @retcode <> 0
  9036.         return(1)
  9037.  
  9038.     /*
  9039.     ** Parameter Check:  @publication.
  9040.     ** If the @publication is 'all', drop all publications.  Otherwise,
  9041.     ** make sure the @publication is a valid non-null identifier.
  9042.     ** Delete the logreader agent after all the publications have been 
  9043.     ** removed.
  9044.     */
  9045.  
  9046.     IF LOWER(@publication) = 'all'
  9047.         BEGIN
  9048.             DECLARE hC1  CURSOR LOCAL FAST_FORWARD FOR 
  9049.                 SELECT DISTINCT name FROM syspublications 
  9050.                     WHERE pubid NOT IN 
  9051.                         (SELECT pubid FROM sysarticles WHERE artid IN 
  9052.                             (SELECT artid FROM syssubscriptions WHERE srvid <> @virtual_id))
  9053.             OPEN hC1
  9054.             FETCH hC1 INTO @publication
  9055.             WHILE (@@fetch_status <> -1)
  9056.                 BEGIN
  9057.                     EXECUTE dbo.sp_droppublication @publication,
  9058.                         @ignore_distributor = @ignore_distributor
  9059.                     FETCH hC1 INTO @publication
  9060.                 END
  9061.             CLOSE hC1
  9062.             DEALLOCATE hC1
  9063.             RETURN (0)
  9064.         END
  9065.  
  9066.     IF @publication IS NULL
  9067.         BEGIN
  9068.             RAISERROR (14003, 16, -1)
  9069.             RETURN (1)
  9070.         END
  9071.  
  9072.     EXECUTE @retcode = dbo.sp_validname @publication
  9073.  
  9074.     IF @retcode <> 0
  9075.     RETURN (1)
  9076.  
  9077.     /*
  9078.     ** Ascertain the existence of the publication and get the taskid.
  9079.     */
  9080.     IF NOT EXISTS (SELECT *
  9081.                      FROM syspublications
  9082.                     WHERE name = @publication)
  9083.     BEGIN
  9084.         RAISERROR (20026, 11, -1, @publication)
  9085.         RETURN (1)
  9086.     END
  9087.  
  9088.     /*
  9089.     ** Check to make sure that there are no subscriptions on the publication.
  9090.     */
  9091.  
  9092.     IF EXISTS (SELECT *
  9093.                  FROM syssubscriptions a, sysarticles b, syspublications c
  9094.                 WHERE c.name = @publication
  9095.                   AND c.pubid = b.pubid
  9096.                   AND b.artid = a.artid
  9097.                   AND a.srvid <>@virtual_id)
  9098.         BEGIN
  9099.             RAISERROR (14005, 16, -1)
  9100.             RETURN (1)
  9101.         END
  9102.  
  9103.     /*
  9104.     ** Delete all articles from the publication.
  9105.     */
  9106.  
  9107.     DECLARE hC2  CURSOR LOCAL FAST_FORWARD FOR 
  9108.         SELECT DISTINCT name FROM sysarticles 
  9109.             WHERE pubid = (SELECT pubid FROM syspublications 
  9110.                 WHERE name = @publication)
  9111.     OPEN hC2
  9112.     FETCH hC2 INTO @article
  9113.     WHILE (@@fetch_status <> -1)
  9114.         BEGIN
  9115.             EXECUTE dbo.sp_droparticle @publication = @publication, 
  9116.                 @article = @article,
  9117.                 @ignore_distributor = @ignore_distributor
  9118.             FETCH hC2 INTO @article
  9119.         END
  9120.     CLOSE hC2
  9121.     DEALLOCATE hC2
  9122.  
  9123.     
  9124.     BEGIN TRAN
  9125.  
  9126.     /*
  9127.     ** Delete publication from syspublications.
  9128.     */
  9129.  
  9130.     DELETE FROM syspublications WHERE name = @publication
  9131.  
  9132.     IF @@ERROR <> 0
  9133.         GOTO UNDO
  9134.  
  9135.     /*
  9136.     ** if @ignore_distributor = 1, we are in bruteforce cleanup mode, don't do RPC.
  9137.     */
  9138.     if @ignore_distributor = 0
  9139.     begin
  9140.  
  9141.         /*
  9142.         ** Get distribution server information for remote RPC call.
  9143.         */
  9144.  
  9145.         EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  9146.                                            @distribdb = @distribdb OUTPUT
  9147.  
  9148.         IF @@ERROR <> 0 OR  @retcode <> 0
  9149.             BEGIN
  9150.                 RAISERROR (14071, 16, -1)
  9151.                 RETURN (1)
  9152.             END
  9153.  
  9154.         /*
  9155.         ** Delete sync agent of Publication if it exists.
  9156.         */
  9157.         SELECT @distproc = RTRIM(@distributor) + '.' + @distribdb + '.dbo.sp_MSdrop_snapshot_agent'
  9158.         EXECUTE @retcode = @distproc 
  9159.             @publisher = @@SERVERNAME,
  9160.             @publisher_db = @dbname,
  9161.             @publication = @publication
  9162.  
  9163.         IF @@ERROR <> 0 or @retcode <> 0
  9164.             GOTO UNDO
  9165.  
  9166.         IF NOT EXISTS (SELECT * FROM syspublications  where repl_freq = 0)
  9167.             BEGIN
  9168.                 /*
  9169.                 ** Delete logreader agent, continue if drop is not successful
  9170.                 */
  9171.                 SELECT @distproc = RTRIM(@distributor) + '.' + @distribdb + '.dbo.sp_MSdrop_logreader_agent'
  9172.                 EXECUTE @retcode = @distproc @publisher = @@SERVERNAME,
  9173.                     @publisher_db = @dbname,
  9174.                     -- 'ALL' is used in sp_addpublication.
  9175.                     @publication = 'ALL'
  9176.                 IF @@ERROR <> 0 or @retcode <> 0
  9177.                     GOTO UNDO
  9178.             END
  9179.  
  9180.         /*
  9181.         ** Delete the publication at the distribution server
  9182.         */
  9183.         SELECT @distproc = RTRIM(@distributor) + '.' + @distribdb + 
  9184.             '.dbo.sp_MSdrop_publication'
  9185.         EXECUTE @retcode = @distproc
  9186.             @publisher = @@SERVERNAME,
  9187.             @publisher_db = @dbname,
  9188.             @publication = @publication
  9189.         IF @@ERROR <> 0 or @retcode <> 0
  9190.             GOTO UNDO
  9191.     end
  9192.  
  9193.     COMMIT TRAN
  9194.  
  9195.     return (0)  
  9196.     
  9197. UNDO:
  9198.     if @@TRANCOUNT = 1
  9199.         ROLLBACK TRAN
  9200.     else
  9201.         COMMIT TRAN
  9202.     return(1)
  9203. GO
  9204.  
  9205. EXEC dbo.sp_MS_marksystemobject sp_droppublication
  9206. GO
  9207.  
  9208. print ''
  9209. print 'Creating procedure sp_dropsubscription'
  9210. go
  9211. CREATE PROCEDURE sp_dropsubscription (
  9212.     @publication sysname = NULL,   /* The publication name */
  9213.     @article sysname = NULL,       /* The article name */
  9214.     @subscriber sysname,           /* The subscriber name */
  9215.     @destination_db sysname =NULL,                /* Name of the destination database */
  9216.                                         /* If null, all the subscriptions from that
  9217.                                             subscriber will be dropped */
  9218.     @ignore_distributor bit = 0,
  9219.  
  9220.     @reserved nvarchar(10) = NULL            /* reserved, used when calling from other system */
  9221.                                             /* stored procedures, it will be set to 'internal'.*/
  9222.                                             /* It should never be used directly */
  9223.     ) AS
  9224.  
  9225.     /*
  9226.     ** Declarations.
  9227.     */
  9228.  
  9229.     DECLARE @subscriber_bit smallint
  9230.     DECLARE @cmd nvarchar(255)
  9231.     DECLARE @srvid smallint
  9232.     DECLARE @artid int
  9233.     DECLARE @retcode int
  9234.     DECLARE @active tinyint
  9235.     DECLARE @internal nvarchar(10)
  9236.     DECLARE @expand_article nvarchar(10)
  9237.     DECLARE @push tinyint
  9238.     DECLARE @virtual_id smallint
  9239.     DECLARE @login_name sysname
  9240.     DECLARE @immediate_sync bit
  9241.     DECLARE @subscription_type int
  9242.     DECLARE @qualified_subscription_name nvarchar(512)
  9243.  
  9244.     /*
  9245.     ** Initializations.
  9246.     */
  9247.     SET NOCOUNT ON
  9248.     SELECT @subscriber_bit = 4  /* Const: subscription server status */
  9249.     SELECT @active = 2          /* Const: subscription status 'active' */
  9250.     SELECT @push = 0        /* Const: push publication type */
  9251.     SELECT @virtual_id = -1 /* Const: virtual subscriber id */
  9252.     SELECT @internal = 'internal' /* Const: Flag of calling internally from system */
  9253.                                   /* stored procedures     */
  9254.     SELECT @expand_article = 'expand_art' 
  9255.         /* Const: Flag of calling after expand 'all' for @artcle  */
  9256.     
  9257.     /* 
  9258.     ** Security Check.
  9259.     ** We use login_name stored in syssubscriptions to manage security 
  9260.     */
  9261.  
  9262.     -- Bug 25691. Test distributor RPC connection before open the cursor
  9263.     /*
  9264.     ** if @ignore_distributor = 1, we are in bruteforce cleanup mode, don't do RPC.
  9265.     */
  9266.     if @ignore_distributor = 0
  9267.     begin
  9268.         declare @distributor sysname
  9269.         EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT
  9270.         if @@ERROR <> 0 or @retcode <> 0
  9271.             return(1)
  9272.     end
  9273.  
  9274.     /*
  9275.     ** If the @subscriber is 'all', the user wants to cancel all subscriptions
  9276.     ** to the specified article(s).
  9277.     */
  9278.  
  9279.     IF LOWER(@subscriber) = 'all'
  9280.         BEGIN
  9281.             DECLARE hCdrop_subscription1  CURSOR LOCAL FAST_FORWARD FOR 
  9282.                 SELECT DISTINCT srvname 
  9283.                     FROM master..sysservers a, syssubscriptions b 
  9284.                     WHERE srvstatus & @subscriber_bit <> 0 
  9285.                     AND a.srvid = b.srvid
  9286.  
  9287.     -- With ANSI Defaults ON, the cursor will automatically
  9288.     -- be closed on commit.   Since this proc gets called recursively, 
  9289.     -- this can happen.  So check before opening. 
  9290.     IF CURSOR_STATUS('local','hCdrop_subscription1') = -1
  9291.             OPEN hCdrop_subscription1
  9292.  
  9293.             -- Bug : 47836 : must owner qual proc invoke to exec inside server on restore/attach cleanup
  9294.             FETCH hCdrop_subscription1 INTO @subscriber
  9295.             WHILE (@@fetch_status <> -1)
  9296.                 BEGIN
  9297.                     EXECUTE dbo.sp_dropsubscription 
  9298.                         @publication = @publication,
  9299.                         @article = @article,
  9300.                         @subscriber  = @subscriber,
  9301.                         @destination_db = 'all',
  9302.                         @ignore_distributor = @ignore_distributor,
  9303.                         @reserved = @reserved
  9304.  
  9305.         IF CURSOR_STATUS('local','hCdrop_subscription1') = -1
  9306.                 OPEN hCdrop_subscription1
  9307.                 FETCH hCdrop_subscription1 INTO @subscriber
  9308.                 END
  9309.             CLOSE hCdrop_subscription1
  9310.             DEALLOCATE hCdrop_subscription1
  9311.             RETURN (0)
  9312.         END
  9313.  
  9314.     
  9315.     
  9316.     /*
  9317.     ** Parameter Check: @subscriber.
  9318.     **
  9319.     ** Check if the server exists and that it is a subscription server.
  9320.     **
  9321.     */
  9322.     IF @subscriber IS NULL
  9323.         BEGIN
  9324.             SELECT @srvid = @virtual_id 
  9325.         END
  9326.     ELSE
  9327.         BEGIN
  9328.             /* validate name and get subscriber ID  and server status  */
  9329.             EXECUTE @retcode = dbo.sp_validname @subscriber
  9330.             IF @retcode <> 0
  9331.             RETURN (1)
  9332.  
  9333.             SELECT @srvid = srvid
  9334.               FROM master..sysservers
  9335.              WHERE UPPER(srvname) = UPPER(@subscriber)
  9336.                AND (srvstatus & @subscriber_bit) <> 0
  9337.  
  9338.             IF @srvid IS NULL
  9339.                 BEGIN
  9340.                     RAISERROR (14010, 16, -1)
  9341.                     RETURN (1)
  9342.                 END
  9343.         END
  9344.     /*
  9345.     ** If the @publication is 'all', the user wants to cancel all subscriptions
  9346.     ** for all publications associated with the specified @subscriber.
  9347.     */
  9348.  
  9349.     IF LOWER(@publication) = 'all'
  9350.         BEGIN
  9351.             DECLARE hCdrop_subscription2  CURSOR LOCAL FAST_FORWARD FOR 
  9352.                 SELECT DISTINCT a.name 
  9353.                     FROM syspublications a, sysarticles b,  syssubscriptions c 
  9354.                     WHERE c.srvid = @srvid
  9355.                     AND a.pubid = b.pubid 
  9356.                     AND b.artid = c.artid 
  9357.                     
  9358.             OPEN hCdrop_subscription2
  9359.             FETCH hCdrop_subscription2 INTO @publication
  9360.             WHILE (@@fetch_status <> -1)
  9361.                 BEGIN
  9362.                     EXECUTE dbo.sp_dropsubscription @publication = @publication,
  9363.                                                 @article     = 'all',
  9364.                                                 @subscriber  = @subscriber,
  9365.                                                 @destination_db = @destination_db,
  9366.                                                 @ignore_distributor = @ignore_distributor,
  9367.                                                 @reserved = @reserved
  9368.  
  9369.                     FETCH hCdrop_subscription2 INTO @publication
  9370.                 END
  9371.             CLOSE hCdrop_subscription2
  9372.             DEALLOCATE hCdrop_subscription2
  9373.             RETURN (0)
  9374.         END
  9375.  
  9376.     /*
  9377.     ** Parameter Check: @publication.
  9378.     ** Check to make sure that the publication exists and that it conforms
  9379.     ** to the rules for identifiers.
  9380.     */
  9381.  
  9382.     IF @publication IS NULL
  9383.         BEGIN
  9384.             RAISERROR (14043, 16, -1, '@publication')
  9385.             RETURN (1)
  9386.         END
  9387.  
  9388.     EXECUTE @retcode = dbo.sp_validname @publication
  9389.  
  9390.     IF @retcode <> 0
  9391.     RETURN (1)
  9392.  
  9393.     IF NOT EXISTS (SELECT * FROM syspublications WHERE name = @publication)
  9394.         BEGIN
  9395.             RAISERROR (20026, 11, -1, @publication)
  9396.             RETURN (1)
  9397.         END
  9398.  
  9399.     /* Get subscription type of the publication */
  9400.     SELECT @immediate_sync = immediate_sync
  9401.         FROM syspublications WHERE name = @publication
  9402.  
  9403.     /*
  9404.     ** Parameter Check:  @article
  9405.     */
  9406.  
  9407.     /* @article can not be null     */
  9408.     IF @article IS NULL
  9409.         BEGIN
  9410.             RAISERROR (14043, 16, -1, '@article')
  9411.             RETURN (1)
  9412.         END
  9413.  
  9414.     /** For immediate_sync publication, @article has to be 'all'     */
  9415.     -- Relax this constraint since users will need to do this before dropping
  9416.     -- an article
  9417.     /*
  9418.     IF @reserved <> @internal AND @reserved <> @expand_article
  9419.         AND @immediate_sync = 1
  9420.         AND NOT LOWER(@article) = 'all'
  9421.         BEGIN
  9422.             RAISERROR (14122, 16, -1)
  9423.             RETURN (1)
  9424.         END
  9425.     */
  9426.  
  9427.     /*
  9428.     ** If the @article is 'all', the user wants to cancel all
  9429.     ** subscriptions on this publisher associated with the given @subscriber
  9430.     ** and @publication.
  9431.     */
  9432.  
  9433.     IF LOWER(@article) = 'all'
  9434.         BEGIN
  9435.  
  9436.             /* Make the operation automic for immediate_sync publications */
  9437.             BEGIN TRAN
  9438.  
  9439.             IF @reserved IS NULL
  9440.                 SELECT @reserved = @expand_article
  9441.  
  9442.             DECLARE hCdrop_subscription3  CURSOR LOCAL FAST_FORWARD FOR
  9443.                 SELECT DISTINCT art.name 
  9444.                     FROM sysarticles art, syssubscriptions sub, syspublications pub 
  9445.                     WHERE sub.srvid = @srvid
  9446.                     AND sub.artid = art.artid
  9447.                     AND art.pubid = pub.pubid
  9448.                     AND pub.name = @publication 
  9449.                     
  9450.             OPEN hCdrop_subscription3
  9451.             FETCH hCdrop_subscription3 INTO @article
  9452.             WHILE (@@fetch_status <> -1)
  9453.                 BEGIN
  9454.                     EXECUTE @retcode = dbo.sp_dropsubscription 
  9455.                         @publication = @publication,
  9456.                         @article = @article,
  9457.                         @subscriber = @subscriber,
  9458.                         @destination_db = @destination_db,
  9459.                         @ignore_distributor = @ignore_distributor,
  9460.                         @reserved = @reserved
  9461.                     IF @@error<>0 OR @retcode <> 0
  9462.                     BEGIN
  9463.                         CLOSE hCdrop_subscription3
  9464.                         DEALLOCATE hCdrop_subscription3
  9465.                         GOTO UNDO                        
  9466.                     END
  9467.                     FETCH hCdrop_subscription3 INTO @article
  9468.                 END
  9469.             CLOSE hCdrop_subscription3
  9470.             DEALLOCATE hCdrop_subscription3
  9471.  
  9472.             COMMIT TRAN
  9473.             RETURN (0)
  9474.         END
  9475.  
  9476.     /*
  9477.     ** Parameter Check: @article
  9478.     ** Check if the article exists.
  9479.     */
  9480.  
  9481.     /*
  9482.     EXECUTE @retcode = dbo.sp_validname @article
  9483.  
  9484.     IF @retcode <> 0
  9485.     RETURN (1)
  9486.     */
  9487.  
  9488.     SELECT @artid = artid
  9489.       FROM sysarticles art, syspublications pub
  9490.      WHERE pub.name = @publication
  9491.        AND art.name = @article
  9492.        AND art.pubid = pub.pubid
  9493.  
  9494.     IF @artid IS NULL
  9495.         BEGIN
  9496.             RAISERROR (20027, 11, -1, @article)
  9497.         RETURN (1)
  9498.         END
  9499.  
  9500.  
  9501.     /*
  9502.     ** Parameter Check: @destination_db.
  9503.     ** Set @destination_db to current database if not specified.  Make
  9504.     ** sure that the @destination_db conforms to the rules for identifiers.
  9505.     */
  9506.  
  9507.     IF @destination_db IS NULL
  9508.     BEGIN
  9509.         /*
  9510.         ** Check if the subscription exists.
  9511.         */
  9512.  
  9513.         IF NOT EXISTS (SELECT *
  9514.                          FROM syssubscriptions
  9515.                         WHERE srvid = @srvid
  9516.                           AND artid = @artid)
  9517.         BEGIN    
  9518.                 RAISERROR (14055, 11, -1)
  9519.                 RETURN (1)
  9520.         END
  9521.         ELSE
  9522.  
  9523.         SELECT @destination_db = 'all' 
  9524.     END
  9525.     ELSE
  9526.     BEGIN
  9527.         EXECUTE @retcode = dbo.sp_validname @destination_db
  9528.         IF @retcode <> 0
  9529.         RETURN (1)
  9530.     END
  9531.  
  9532.     IF LOWER(@destination_db) = 'all' 
  9533.         BEGIN
  9534.             DECLARE hCdropsub4  CURSOR LOCAL FAST_FORWARD FOR 
  9535.                 SELECT DISTINCT dest_db
  9536.                     FROM syssubscriptions 
  9537.                     WHERE srvid = @srvid
  9538.                     AND artid = @artid
  9539.             OPEN hCdropsub4
  9540.             FETCH hCdropsub4 INTO @destination_db
  9541.             WHILE (@@fetch_status <> -1)
  9542.                 BEGIN
  9543.                     EXECUTE dbo.sp_dropsubscription 
  9544.                         @publication = @publication,
  9545.                         @article = @article,
  9546.                         @subscriber = @subscriber,
  9547.                         @destination_db = @destination_db,
  9548.                         @ignore_distributor = @ignore_distributor,
  9549.                         @reserved = @reserved
  9550.                     FETCH hCdropsub4 INTO @destination_db
  9551.                 END
  9552.             CLOSE hCdropsub4
  9553.             DEALLOCATE hCdropsub4
  9554.             RETURN (0)
  9555.         END
  9556.  
  9557.     /*
  9558.     ** Dropping virtual subscriptions is not allowed
  9559.     ** in following case:
  9560.     ** 1. non sa or dbo user
  9561.     ** 2. the stored procedure is not in internal usage mode 
  9562.     **        (called by system stored procedures)
  9563.     **
  9564.     ** Note: Only immediate_sync publications have virtual subscriptions
  9565.     ** 
  9566.     */
  9567.  
  9568.     IF  @srvid = @virtual_id  AND  (
  9569.         @reserved <> @internal)
  9570.         BEGIN
  9571.             RAISERROR (14056, 16, -1)
  9572.             RETURN (1)
  9573.         END
  9574.  
  9575.     /*
  9576.     ** Check if the subscription exists.
  9577.     */
  9578.  
  9579.     IF NOT EXISTS (SELECT *
  9580.                      FROM syssubscriptions
  9581.                     WHERE srvid = @srvid
  9582.                       AND artid = @artid
  9583.                       AND dest_db = @destination_db)
  9584.     BEGIN
  9585.             RAISERROR (14055, 11, -1)
  9586.             RETURN (1)
  9587.     END
  9588.  
  9589.  
  9590.     /* Check the current login id. It is valid only when
  9591.     ** 1. sa or dbo
  9592.     ** 2. same as the one who add the subscription.
  9593.     */
  9594.     SELECT @login_name = login_name 
  9595.          FROM syssubscriptions
  9596.         WHERE srvid = @srvid
  9597.           AND artid = @artid
  9598.           AND dest_db = @destination_db
  9599.  
  9600.     IF  suser_sname(suser_sid()) <> @login_name AND is_srvrolemember('sysadmin') <> 1  
  9601.         AND is_member ('db_owner') <> 1
  9602.     BEGIN
  9603.             SELECT @qualified_subscription_name = @subscriber + N':' + @destination_db
  9604.             RAISERROR(21120, 11, -1, @qualified_subscription_name, @publication)
  9605.             RETURN (1)
  9606.     END
  9607.  
  9608.  
  9609.     begin tran
  9610.     save TRANSACTION dropsubscription
  9611.  
  9612.         /* If dropping virtual subscriptions, reset immediate_sync_ready bit */
  9613.         IF @srvid = @virtual_id
  9614.         BEGIN
  9615.             UPDATE syspublications SET immediate_sync_ready = 0
  9616.                 WHERE
  9617.                     name = @publication and
  9618.                     immediate_sync = 1 and
  9619.                     immediate_sync_ready = 1
  9620.             IF @@ERROR <> 0
  9621.                 goto UNDO
  9622.         END
  9623.  
  9624.         /*
  9625.         ** Change the status of the subscription to 'inactive'.
  9626.         */
  9627.  
  9628.         EXECUTE @retcode = dbo.sp_changesubstatus @publication = @publication,
  9629.                                               @article = @article,
  9630.                                               @subscriber = @subscriber,
  9631.                                               @status = 'inactive',
  9632.                                               @destination_db = @destination_db,
  9633.                                               @ignore_distributor = @ignore_distributor
  9634.         IF @@ERROR <> 0 OR @retcode <> 0
  9635.         BEGIN
  9636.             if @@trancount > 0
  9637.             begin
  9638.                 ROLLBACK TRANSACTION dropsubscription
  9639.                 commit tran
  9640.             end
  9641.             RETURN (1)
  9642.         END
  9643.  
  9644.     /* Read the subscription_type befor removing the syssubscriptions row */
  9645.     select @subscription_type = subscription_type from syssubscriptions
  9646.         WHERE artid = @artid
  9647.         AND srvid = @srvid
  9648.         AND dest_db = @destination_db
  9649.     /*
  9650.     ** Remove subscription from syssubscriptions.
  9651.     */
  9652.     DELETE syssubscriptions
  9653.      WHERE artid = @artid
  9654.        AND srvid = @srvid
  9655.        AND dest_db = @destination_db
  9656.  
  9657.     IF @@ERROR <> 0
  9658.     BEGIN
  9659.         if @@trancount > 0
  9660.         begin
  9661.             ROLLBACK TRANSACTION dropsubscription
  9662.             commit tran
  9663.         end
  9664.         RETURN (1)
  9665.     END
  9666.  
  9667.     /* Call sp_MSunregistersubscription so that the reg entries get deleted (for push subscriptions) */
  9668.     if @subscription_type = @push
  9669.         begin
  9670.             declare @publisher_db sysname
  9671.             set @publisher_db = DB_NAME()
  9672.             exec @retcode = dbo.sp_MSunregistersubscription @publisher = @@SERVERNAME,
  9673.                                 @publisher_db = @publisher_db,
  9674.                                 @publication = @publication,
  9675.                                 @subscriber = @subscriber,
  9676.                                 @subscriber_db = @destination_db
  9677.  
  9678.             IF @retcode<>0 or @@ERROR<>0
  9679.                 GOTO UNDO
  9680.         end             
  9681.  
  9682.     COMMIT TRANSACTION
  9683.     RETURN (0)
  9684.  
  9685. UNDO:
  9686.     IF @@TRANCOUNT = 1
  9687.         ROLLBACK TRAN
  9688.     ELSE
  9689.         COMMIT TRAN
  9690.     RETURN(1)
  9691. go
  9692.  
  9693. EXEC dbo.sp_MS_marksystemobject sp_dropsubscription
  9694. GO
  9695.  
  9696. print ''
  9697. print 'Creating procedure sp_subscribe'
  9698. go
  9699. CREATE PROCEDURE sp_subscribe (
  9700.     @publication sysname,          /* publication name */
  9701.     @article sysname = 'all',          /* article name */
  9702.     @destination_db sysname = NULL,  /* subscriber database */
  9703.     @sync_type nvarchar (15) = 'automatic' /* subscription sync type */
  9704.     ) AS
  9705.  
  9706.     -- New 7.0 sp_addsubscription parameters
  9707.     DECLARE @subscriber                  sysname
  9708.     DECLARE @status                      sysname
  9709.     DECLARE @subscription_type           nvarchar(4)
  9710.     DECLARE @update_mode                 nvarchar(15)
  9711.     DECLARE @loopback_detection          nvarchar(5)
  9712.     DECLARE @enabled_for_syncmgr         nvarchar(5)
  9713.     DECLARE @retcode                     int
  9714.  
  9715.     SET NOCOUNT ON
  9716.  
  9717.     -- sp_subscribe has to be called from a remote subscriber 
  9718.     -- If not, we state that it is unsupported
  9719.     SELECT @subscriber = @@REMSERVER
  9720.     IF @subscriber IS NULL
  9721.     BEGIN
  9722.       RAISERROR (21023, 16, -1,'sp_subscribe')
  9723.       RETURN(1)
  9724.     END
  9725.     
  9726.     SELECT @status = NULL
  9727.     SELECT @subscription_type = 'push'
  9728.     SELECT @update_mode = 'read only'
  9729.     SELECT @loopback_detection = 'false'
  9730.     SELECT @enabled_for_syncmgr = 'false'
  9731.  
  9732.     -- Call sp_addsubscription to do the actual work
  9733.     EXEC @retcode = dbo.sp_addsubscription @publication = @publication,
  9734.                                            @article = @article,
  9735.                                            @destination_db = @destination_db,
  9736.                                            @sync_type = @sync_type,
  9737.                                            @subscriber = @subscriber,
  9738.                                            @status = @status,
  9739.                                            @subscription_type = @subscription_type,
  9740.                                            @update_mode = @update_mode,
  9741.                                            @loopback_detection = @loopback_detection,
  9742.                                            @enabled_for_syncmgr = @enabled_for_syncmgr
  9743.                                         
  9744.     RETURN @retcode   
  9745. go
  9746.  
  9747. EXEC dbo.sp_MS_marksystemobject sp_subscribe
  9748. GO
  9749.  
  9750. print ''
  9751. print 'Creating procedure sp_unsubscribe'
  9752. go
  9753. CREATE PROCEDURE sp_unsubscribe (
  9754.     @publication sysname = NULL,       /* publication name */
  9755.     @article sysname = NULL            /* article name */
  9756.     ) AS
  9757.  
  9758.     -- New 7.0 sp_dropsubscription parameters
  9759.     DECLARE @subscriber     sysname
  9760.     DECLARE @destination_db sysname    
  9761.     DECLARE @retcode        int 
  9762.  
  9763.     SET NOCOUNT ON
  9764.     
  9765.     -- sp_unsubscribe has to be callled from a remote subscriber
  9766.     -- If not, we state that it is unsupported
  9767.     SELECT @subscriber = @@REMSERVER
  9768.     IF @subscriber IS NULL
  9769.     BEGIN
  9770.         RAISERROR (21023, 16, -1,'sp_unsubscribe')
  9771.         RETURN(1)
  9772.     END
  9773.  
  9774.     -- 6.5 didn't support having multiple databases on the same subscriber
  9775.     -- subscribing to the same publication so here, all subscriptions to the
  9776.     -- same publication will be dropped 
  9777.     SELECT @destination_db = NULL
  9778.     
  9779.     -- Call sp_dropsubscription to do the real work
  9780.     EXEC @retcode = sp_dropsubscription @publication = @publication,
  9781.                                         @article = @article,
  9782.                                         @subscriber = @subscriber,
  9783.                                         @destination_db = @destination_db
  9784.     RETURN @retcode
  9785.     
  9786. go
  9787.  
  9788. EXEC dbo.sp_MS_marksystemobject sp_unsubscribe
  9789. GO
  9790.  
  9791. print ''
  9792. print 'Creating procedure sp_refreshsubscriptions'
  9793. go
  9794.  
  9795. CREATE PROCEDURE sp_refreshsubscriptions (
  9796.     @publication sysname       /* Publication name */
  9797.     ) AS
  9798.  
  9799.     SET NOCOUNT ON
  9800.  
  9801.     /*
  9802.     ** Declarations.
  9803.     */
  9804.  
  9805.     DECLARE @article  sysname 
  9806.     DECLARE @subscriber sysname
  9807.     DECLARE @dest_db sysname
  9808.     DECLARE @retcode int
  9809.     DECLARE @pubid int
  9810.     DECLARE @immediate_sync bit 
  9811.     DECLARE @no_sync tinyint
  9812.     DECLARE @subscription_type_id int
  9813.     DECLARE @subscription_type nvarchar(4)
  9814.     DECLARE @virtual smallint
  9815.     DECLARE @srvid smallint
  9816.     DECLARE @sync_typeid int
  9817.     DECLARE @automatic tinyint
  9818.     DECLARE @sync_type nvarchar(9)
  9819.  
  9820.     SELECT @no_sync = 2
  9821.     SELECT @virtual = -1
  9822.     SELECT @automatic = 1
  9823.     /*
  9824.     ** Security Check
  9825.     */
  9826.     exec @retcode = dbo.sp_MSreplcheck_publish
  9827.     if @@ERROR <> 0 or @retcode <> 0
  9828.         return(1)
  9829.  
  9830.     /*
  9831.     ** Check to see if the database has been activated for publication.
  9832.     */
  9833.  
  9834.     IF (SELECT category & 1
  9835.           FROM master..sysdatabases
  9836.          WHERE name = DB_NAME()) = 0
  9837.  
  9838.     BEGIN
  9839.             RAISERROR (14013, 16, -1)
  9840.         RETURN (1)
  9841.     END
  9842.  
  9843.  
  9844.     /*
  9845.     ** Parameter Check:  @publication.
  9846.     ** Make sure that the publication exists
  9847.     */
  9848.  
  9849.     IF @publication IS NULL
  9850.         BEGIN
  9851.             RAISERROR (14043, 16, -1, '@publication')
  9852.             RETURN (1)
  9853.         END
  9854.  
  9855.     EXECUTE @retcode = dbo.sp_validname @publication
  9856.  
  9857.     IF @@ERROR <> 0 OR @retcode <> 0
  9858.     RETURN (1)
  9859.  
  9860.     SELECT @pubid = pubid
  9861.         FROM syspublications WHERE name = @publication
  9862.  
  9863.     IF @pubid IS NULL
  9864.         BEGIN
  9865.             RAISERROR (20026, 11, -1, @publication)
  9866.             RETURN (1)
  9867.         END
  9868.     
  9869.     
  9870.     /* Add real subscription to the new articles  */
  9871.     /* Open a cursor on all the pending subscriptions, that is */
  9872.     /* All the subscriptions on the publication that */
  9873.     /* are not on an article in the publication. */
  9874.     /* not including virtual subscriptions */
  9875.  
  9876.     DECLARE hCrefreshsubscriptions CURSOR LOCAL FAST_FORWARD FOR
  9877.         SELECT DISTINCT art1.name, subs1.dest_db, subs1.srvid
  9878.             FROM syssubscriptions subs1, sysarticles art1
  9879.             WHERE art1.pubid = @pubid AND
  9880.                   subs1.srvid <> @virtual AND
  9881.                   EXISTS (SELECT * FROM syssubscriptions subs2, sysarticles art2
  9882.                     WHERE subs2.srvid = subs1.srvid AND
  9883.                           subs2.dest_db = subs1.dest_db AND
  9884.                           subs2.artid = art2.artid AND
  9885.                           art2.pubid = @pubid) AND
  9886.                   NOT EXISTS ( SELECT * FROM syssubscriptions subs3 
  9887.                     WHERE  subs3.artid = art1.artid AND
  9888.                            subs3.srvid = subs1.srvid AND
  9889.                            subs3.dest_db = subs1.dest_db)
  9890.     FOR READ ONLY
  9891.     OPEN hCrefreshsubscriptions
  9892.     FETCH hCrefreshsubscriptions INTO @article,  @dest_db, @srvid
  9893.             
  9894.     
  9895.     WHILE (@@fetch_status <> -1)
  9896.     BEGIN
  9897.  
  9898.         /* 
  9899.         ** Get subscription type on the publication
  9900.         */ 
  9901.         SELECT @subscription_type_id = subs.subscription_type,
  9902.             @sync_typeid = subs.sync_type
  9903.          from 
  9904.             sysarticles art, syssubscriptions subs where 
  9905.             art.pubid = @pubid AND
  9906.             subs.srvid = @srvid AND
  9907.             subs.dest_db = @dest_db AND
  9908.             subs.artid = art.artid
  9909.  
  9910.         /* 
  9911.         ** only do it if the subscription all have the same subscription type
  9912.         ** and sync_type
  9913.         */
  9914.         IF NOT EXISTS (SELECT * from 
  9915.             sysarticles art, syssubscriptions subs where 
  9916.             art.pubid = @pubid AND
  9917.             subs.srvid = @srvid AND
  9918.             subs.dest_db = @dest_db AND
  9919.             subs.artid = art.artid AND
  9920.             (subscription_type <> @subscription_type_id OR
  9921.             sync_type <> @sync_typeid))
  9922.         BEGIN
  9923.             IF @subscription_type_id = 0
  9924.                 SELECT @subscription_type = 'push'
  9925.             ELSE
  9926.                 SELECT @subscription_type = 'pull'
  9927.  
  9928.             if @sync_typeid = @automatic
  9929.                 SELECT @sync_type = 'automatic'
  9930.             else
  9931.                 SELECT @sync_type = 'none'
  9932.  
  9933.             /* 
  9934.             ** Get the server name
  9935.             */
  9936.             SELECT @subscriber = srvname FROM master.dbo.sysservers 
  9937.                 WHERE srvid = @srvid
  9938.  
  9939.             EXECUTE @retcode  = dbo.sp_addsubscription 
  9940.                         @publication = @publication, 
  9941.                         @article = @article, 
  9942.                         @subscriber = @subscriber, 
  9943.                         @destination_db = @dest_db, 
  9944.                         @sync_type = @sync_type, 
  9945.                         @status = NULL, 
  9946.                         @subscription_type = @subscription_type,
  9947.                         @reserved = 'internal'
  9948.             IF @@ERROR <> 0 OR @retcode <> 0
  9949.             BEGIN
  9950.                 CLOSE hCrefreshsubscriptions
  9951.                 DEALLOCATE hCrefreshsubscriptions
  9952.                 RETURN (1)
  9953.             END
  9954.         END
  9955.         FETCH hCrefreshsubscriptions INTO @article, @dest_db, @srvid
  9956.     END
  9957.     
  9958.     CLOSE hCrefreshsubscriptions
  9959.     DEALLOCATE hCrefreshsubscriptions
  9960.  
  9961. GO
  9962.  
  9963. EXEC dbo.sp_MS_marksystemobject sp_refreshsubscriptions
  9964. GO
  9965.  
  9966. print ''
  9967. print 'Creating procedure sp_MSpublishdb'
  9968. go
  9969.  
  9970. CREATE PROCEDURE sp_MSpublishdb(
  9971.       @value     sysname,
  9972.       @ignore_distributor bit = 0
  9973.     ) AS
  9974.  
  9975.     SET NOCOUNT ON
  9976.  
  9977.     /*
  9978.     ** Declarations.
  9979.     */
  9980.     declare @quoted_db      sysname
  9981.     declare @db_name        sysname
  9982.     declare @command        nvarchar(255)
  9983.     declare @description    nvarchar(500)
  9984.     declare @category_name  nvarchar(100)
  9985.     DECLARE @agentname      nvarchar(300)
  9986.     DECLARE @dbname         sysname 
  9987.     DECLARE @retcode        int
  9988.     DECLARE @distributor    sysname
  9989.     DECLARE @distribdb      sysname
  9990.     DECLARE @distproc       nvarchar (255)
  9991.     DECLARE @replicate_bit    smallint
  9992.  
  9993.     SELECT @replicate_bit = 2
  9994.  
  9995.     /*
  9996.     ** Initialization
  9997.     */
  9998.  
  9999.     SELECT @dbname = DB_NAME()
  10000.  
  10001.     /*
  10002.     ** Parameter check
  10003.     ** @value
  10004.     */
  10005.     IF LOWER(@value) NOT IN ('true','false')
  10006.     BEGIN
  10007.       RAISERROR(14137,16,-1)
  10008.       RETURN(1)
  10009.     END
  10010.  
  10011.     /*
  10012.     ** if @ignore_distributor = 1, we are in bruteforce cleanup mode, don't do RPC.
  10013.     */
  10014.     if @ignore_distributor = 0
  10015.     begin
  10016.         /*
  10017.         ** Test to see if the distributor is installed and online.
  10018.         */
  10019.         EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  10020.            @distribdb   = @distribdb OUTPUT
  10021.  
  10022.         IF @@ERROR <> 0 or @retcode <> 0 or @distributor IS NULL or @distribdb IS NULL
  10023.         BEGIN
  10024.             IF LOWER(@value) = 'true'
  10025.                 RAISERROR (20028, 16, -1)
  10026.             ELSE
  10027.                 RAISERROR (20029, 16, -1)
  10028.             RETURN (1)
  10029.         END
  10030.     end
  10031.  
  10032.     /*
  10033.     ** Enable the database for publishing.
  10034.     */
  10035.     IF LOWER(@value) = 'true'
  10036.     BEGIN
  10037.  
  10038.         /*
  10039.         ** Drop and then create central publish tables
  10040.         */
  10041.  
  10042.         /* 
  10043.         ** Drop first if exists
  10044.         */
  10045.  
  10046.         EXEC @retcode = dbo.sp_MSdrop_pub_tables
  10047.         IF @@ERROR <> 0 or @retcode <> 0
  10048.         BEGIN
  10049.             return (1)
  10050.         END
  10051.  
  10052.         /*
  10053.         ** Create central publish tables
  10054.         */
  10055.  
  10056.         EXEC @retcode = dbo.sp_MScreate_pub_tables
  10057.         IF @@ERROR <> 0 or @retcode <> 0
  10058.         BEGIN
  10059.             return (1)
  10060.         END
  10061.     END
  10062.  
  10063.     ELSE    /* Disable the database for publishing. */
  10064.     BEGIN
  10065.         /*
  10066.         ** Remove all subscriptions in the database.
  10067.         ** WARNING : must owner qualify proc calls for these to run inside server on restore/attach
  10068.         */
  10069.         EXEC @retcode = dbo.sp_dropsubscription @publication = 'all',
  10070.             @article = 'all', @subscriber = 'all', 
  10071.             @ignore_distributor = @ignore_distributor
  10072.         IF @@ERROR <> 0 or @retcode <> 0
  10073.         BEGIN
  10074.             return (1)
  10075.         END
  10076.  
  10077.         -- Used for attach and restored db.
  10078.         -- sysservers table in master db might be changed so that
  10079.         -- sp_dropsubscription won't work. Delete the table directly.
  10080.         -- Before dropping the table, we need to unmark repl bits in sysobjects
  10081.         -- see below
  10082.  
  10083.         delete syssubscriptions where srvid >= 0
  10084.         IF @@ERROR <> 0 
  10085.         BEGIN
  10086.             return (1)
  10087.         END
  10088.  
  10089.         /*
  10090.         ** Remove all publications and articles in the database.
  10091.         */
  10092.         EXEC @retcode = dbo.sp_droppublication @publication = 'all', 
  10093.             @ignore_distributor = @ignore_distributor
  10094.         IF @@ERROR <> 0 or @retcode <> 0
  10095.         BEGIN
  10096.             return (1)
  10097.         END
  10098.   
  10099.         /*
  10100.         ** Remove all published database transactions from the distribution
  10101.         ** database.
  10102.         */
  10103.         if @ignore_distributor = 0
  10104.         begin
  10105.             SELECT  @distproc = RTRIM(@distributor) + '.' +
  10106.                     RTRIM(@distribdb) + '.dbo.sp_MSremove_published_jobs '
  10107.             EXEC @retcode = @distproc @@SERVERNAME, @dbname
  10108.             IF @@ERROR <> 0 or @retcode <> 0
  10109.             BEGIN
  10110.                 return (1)
  10111.             END
  10112.         end
  10113.  
  10114.         /*
  10115.         ** Publishing shutdown, remove all xacts pending distribution
  10116.         */
  10117.  
  10118.         /* ensure we can get in as logreader */
  10119.  
  10120.         EXEC @retcode = dbo.sp_replflush
  10121.         IF @@ERROR <> 0 or @retcode <> 0
  10122.         BEGIN
  10123.             return (1)
  10124.         END
  10125.  
  10126.         /* unmark all xacts marked for replication */
  10127.  
  10128.         select @quoted_db = QUOTENAME(@dbname)
  10129.         EXEC ( 'USE ' + @quoted_db + ' exec dbo.sp_repldone NULL, NULL, 0, 0, 1' )
  10130.         IF @@ERROR <> 0 
  10131.         BEGIN
  10132.             return (1)
  10133.         END
  10134.     
  10135.         /* release our hold on the db as logreader */
  10136.         EXEC dbo.sp_replflush
  10137.         IF @@ERROR <> 0 
  10138.         BEGIN
  10139.             RETURN(1)
  10140.         END
  10141.  
  10142.         /* 
  10143.         ** Drop central publish tables
  10144.         */ 
  10145.         EXEC @retcode = dbo.sp_MSdrop_pub_tables
  10146.         IF @@ERROR <> 0 or @retcode <> 0
  10147.         BEGIN
  10148.             return (1)
  10149.         END
  10150.             
  10151.         -- Used for attached and restored db.
  10152.         -- sysservers table in master db might be changed so that
  10153.         -- sp_dropsubscription won't work. Unmark repl bits in sysobjects
  10154.         -- directly.
  10155.         UPDATE sysobjects SET replinfo =  replinfo & ~@replicate_bit
  10156.     END
  10157.     return (0)
  10158. GO
  10159.  
  10160. EXEC dbo.sp_MS_marksystemobject sp_MSpublishdb
  10161. GO
  10162.  
  10163. print ''
  10164. print 'Creating procedure sp_MSactivate_auto_sub'
  10165. go
  10166.  
  10167. CREATE PROCEDURE sp_MSactivate_auto_sub (
  10168.     @publication sysname,        /* Publication name */
  10169.     @article sysname
  10170.     ) AS
  10171.  
  10172.     SET NOCOUNT ON
  10173.  
  10174.     DECLARE @retcode int
  10175.  
  10176.     /*
  10177.     ** Security Check.
  10178.     */
  10179.     exec @retcode = dbo.sp_MSreplcheck_publish
  10180.     if @@ERROR <> 0 or @retcode <> 0
  10181.         return(1)
  10182.  
  10183.     /*
  10184.     ** Check to see if the database has been activated for publication.
  10185.     */
  10186.  
  10187.     IF (SELECT category & 1
  10188.           FROM master..sysdatabases
  10189.          WHERE name = DB_NAME()) = 0
  10190.  
  10191.     BEGIN
  10192.         RAISERROR (14013, 16, -1)
  10193.         RETURN (1)
  10194.     END
  10195.  
  10196.  
  10197.     /*
  10198.     ** Parameter Check:  @publication.
  10199.     ** Make sure that the publication exists and the publication is not push type
  10200.     */
  10201.  
  10202.     IF @publication IS NULL
  10203.         BEGIN
  10204.             RAISERROR (14043, 16, -1, '@publication')
  10205.             RETURN (1)
  10206.         END
  10207.  
  10208.     EXECUTE @retcode = dbo.sp_validname @publication
  10209.     IF @@ERROR <> 0 OR @retcode <> 0
  10210.         RETURN (1)
  10211.     
  10212.     BEGIN TRAN
  10213.  
  10214.     UPDATE syspublications SET immediate_sync_ready = 1 
  10215.         WHERE
  10216.             name = @publication AND
  10217.             immediate_sync = 1 AND
  10218.             immediate_sync_ready <> 1
  10219.     IF @@ERROR <> 0
  10220.     BEGIN
  10221.         GOTO UNDO
  10222.         RETURN (1)
  10223.     END
  10224.  
  10225.     EXECUTE @retcode = dbo.sp_changesubstatus 
  10226.         @publication = @publication,
  10227.         @article = @article,
  10228.         @status = 'active',
  10229.         @from_auto_sync = 1
  10230.  
  10231.     IF @@ERROR <> 0 OR @retcode <> 0
  10232.     BEGIN
  10233.         GOTO UNDO
  10234.         RETURN (1)
  10235.     END
  10236.     
  10237.     COMMIT TRAN
  10238.     RETURN(0)
  10239.  
  10240. UNDO:
  10241.     IF @@TRANCOUNT = 1
  10242.         ROLLBACK TRAN
  10243.     ELSE
  10244.         COMMIT TRAN
  10245.  
  10246. GO
  10247.  
  10248. EXEC dbo.sp_MS_marksystemobject sp_MSactivate_auto_sub
  10249. GO
  10250.  
  10251. raiserror('Creating procedure sp_MSget_synctran_commands', 0,1)
  10252. GO
  10253. CREATE PROCEDURE sp_MSget_synctran_commands(
  10254.     @publication sysname    /* publication name */,
  10255.     @article sysname = 'all',
  10256.     @command_only bit = 0   /* 0 if called by snapshot agent, 1 if called by sp_script_..., */
  10257. ) AS
  10258.  
  10259.     SET NOCOUNT ON
  10260.     DECLARE @artid int
  10261.     DECLARE @tabid int
  10262.     DECLARE @retcode int
  10263.     declare @art_type tinyint        
  10264.     declare @filter_id int
  10265.     declare @filter_clause nvarchar(4000)
  10266.     declare @columns binary(32)
  10267.  
  10268.     DECLARE @pubid int,
  10269.         @art_name sysname, 
  10270.         @posted_synctran_artid int,
  10271.         @dest_table sysname, 
  10272.         @dest_owner sysname,
  10273.         @proc_owner sysname
  10274.  
  10275.     /*
  10276.     ** Initializations.
  10277.     */
  10278.     select @posted_synctran_artid = 0 
  10279.  
  10280.     /* 
  10281.     ** Security Check.
  10282.     ** We use login_name stored in syssubscriptions to manage security 
  10283.     ** Do a relaxed security check here.
  10284.     */
  10285.     exec @retcode = dbo.sp_MSreplcheck_publish
  10286.     if @@ERROR <> 0 or @retcode <> 0
  10287.         return(1)
  10288.  
  10289.     /*
  10290.     ** Parameter Check:  @publication
  10291.     ** Check to make sure that the publication exists, that it's not NULL,
  10292.     ** and that it conforms to the rules for identifiers.
  10293.     */
  10294.  
  10295.     IF @publication IS NULL
  10296.         BEGIN
  10297.             RAISERROR (14043, 16, -1, '@publication')
  10298.             RETURN (1)
  10299.         END
  10300.  
  10301.     EXECUTE @retcode = dbo.sp_validname @publication
  10302.     IF @@ERROR <> 0 OR @retcode <> 0
  10303.     RETURN (1)
  10304.  
  10305.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  10306.  
  10307.     IF @pubid IS NULL
  10308.     BEGIN
  10309.         RAISERROR (20026, 11, -1, @publication)
  10310.         RETURN (1)
  10311.     END
  10312.  
  10313.     -- If the publication does not allow sync tran return nothing
  10314.     IF NOT EXISTS (SELECT * FROM syspublications WHERE pubid = @pubid and
  10315.         allow_sync_tran = 1)
  10316.         RETURN(0)
  10317.  
  10318.     CREATE TABLE #art_commands (artid int NOT NULL, commands nvarchar(4000) NULL, id int identity NOT NULL)
  10319.     
  10320.     declare @all_article bit 
  10321.  
  10322.     if lower(@article) = 'all'
  10323.         select @all_article = 1
  10324.     else
  10325.         select @all_article = 0
  10326.  
  10327.     DECLARE hCsynctran_arts CURSOR LOCAL FAST_FORWARD FOR
  10328.         SELECT art.artid,
  10329.                art.objid,
  10330.                
  10331.                art.dest_table,
  10332.                art.dest_owner,
  10333.                art.name,
  10334.                art.type,
  10335.                art.filter,
  10336.                art.columns
  10337.           FROM sysarticles art,
  10338.                syspublications pub
  10339.          WHERE pub.pubid = @pubid and
  10340.                pub.pubid = art.pubid and
  10341.                (art.type & 0x1) = 1 and
  10342.                (art.name = @article or
  10343.                @all_article = 1)
  10344.     FOR READ ONLY
  10345.  
  10346.     OPEN hCsynctran_arts
  10347.  
  10348.     FETCH hCsynctran_arts INTO @artid, @tabid, @dest_table, @dest_owner, @art_name, 
  10349.         @art_type, @filter_id, @columns
  10350.     
  10351.     WHILE (@@fetch_status <> -1)
  10352.     BEGIN
  10353.  
  10354.     /*
  10355.     ** Determine conflict detection method 
  10356.     */
  10357.         declare @ts_col sysname
  10358.         -- Determine if table has timestamp property
  10359.         select @ts_col = NULL
  10360.         if ObjectProperty(@tabid, 'TableHasTimestamp') = 1 
  10361.         begin
  10362.             exec dbo.sp_MSis_col_replicated @publication, @art_name, 
  10363.                 'timestamp', @ts_col OUTPUT
  10364.         end
  10365.  
  10366.         declare @replcmd nvarchar(4000)
  10367.         declare @insproc sysname, @updproc sysname, @delproc sysname
  10368.         declare @identity_col sysname
  10369.         declare @identity_prop tinyint
  10370.  
  10371.         select @posted_synctran_artid = @artid
  10372.  
  10373.         select @insproc = null, @updproc = null, @delproc = null
  10374.  
  10375.         -- Get sproc names and owner name of the sprocs
  10376.         -- Note artid is unique
  10377.         select @insproc = o.name, @proc_owner = u.name from sysobjects o, sysarticleupdates a, sysusers u
  10378.         where a.artid = @artid and a.sync_ins_proc = o.id and
  10379.             u.uid = o.uid
  10380.  
  10381.         select @updproc = o.name from sysobjects o, sysarticleupdates a
  10382.         where a.artid = @artid and a.sync_upd_proc = o.id
  10383.         
  10384.         select @delproc = o.name from sysobjects o, sysarticleupdates a
  10385.         where a.artid = @artid and a.sync_del_proc = o.id 
  10386.  
  10387.         if @insproc IS NULL
  10388.         begin
  10389.             CLOSE hCsynctran_arts
  10390.             DEALLOCATE hCsynctran_arts
  10391.             RAISERROR (14043, 11, -1, '@insproc')
  10392.             RETURN (1)
  10393.         end
  10394.  
  10395.         if @updproc IS NULL 
  10396.         begin
  10397.             CLOSE hCsynctran_arts
  10398.             DEALLOCATE hCsynctran_arts
  10399.             RAISERROR (14043, 11, -1, '@updproc')
  10400.             RETURN (1)
  10401.         end
  10402.  
  10403.         if @delproc IS NULL
  10404.         begin
  10405.             CLOSE hCsynctran_arts
  10406.             DEALLOCATE hCsynctran_arts
  10407.             RAISERROR (14043, 11, -1, '@delproc')
  10408.             RETURN (1)
  10409.         end
  10410.  
  10411.         -- Determine if published table has identity  col
  10412.         select @identity_col = NULL
  10413.         if ObjectProperty(@tabid, 'TableHasIdentity') = 1 
  10414.             exec @retcode = dbo.sp_MSis_col_replicated @publication, @art_name, 'identity', @identity_col OUTPUT
  10415.                 
  10416.         -- Horizontal partition
  10417.         select @filter_clause = 'null'
  10418.         if @filter_id <> 0
  10419.         begin
  10420.             -- We don't handle manual filters;  allow all updates
  10421.             if ((@art_type & 0x3) = 0x3) 
  10422.                 select @filter_clause = ''
  10423.             else
  10424.                 select @filter_clause = RTRIM(LTRIM(CONVERT(nvarchar(4000), filter_clause)))
  10425.                      from sysarticles where artid = @artid
  10426.         end
  10427.     
  10428.         declare @fullname nvarchar(512)
  10429.         declare @indkey       int
  10430.         declare @indid        int
  10431.         declare @key          sysname
  10432.         declare @col          sysname
  10433.         declare @this_col      int
  10434.         declare @src_cols      int
  10435.         declare @primary_key_bitmap varbinary(4000)
  10436.         declare @byte varbinary(1)
  10437.         declare @i_byte            int
  10438.         declare @num_bytes        int
  10439.         declare @i_bit            tinyint    
  10440.         declare @bitmap_str    varchar(8000)
  10441.         declare @bitmap            varbinary(4000)
  10442.  
  10443.  
  10444.         -- Get qualified name
  10445.         exec dbo.sp_MSget_qualified_name @tabid, @fullname output
  10446.         
  10447.         -- Get number of columns in the partition.
  10448.         exec dbo.sp_MSget_col_position @tabid, @columns, @key, @col output, 
  10449.             @this_col output, 
  10450.             1, -- Get num of columns in the partition.
  10451.             @src_cols output
  10452.         select @num_bytes = @src_cols / 8 + 1
  10453.     
  10454.         -- Set varbinary length
  10455.         set @byte = 0
  10456.         set @primary_key_bitmap = @byte
  10457.         set @i_byte = 1
  10458.         while @i_byte < @num_bytes
  10459.         begin
  10460.             set @primary_key_bitmap = @primary_key_bitmap + @byte
  10461.             set @i_byte = @i_byte + 1
  10462.         end
  10463.     
  10464.         -- get index id
  10465.         exec @indid = dbo.sp_MStable_has_unique_index @tabid
  10466.         set @indkey = 1
  10467.         while @indkey < 16 and index_col(@fullname, @indid, @indkey) is not null
  10468.         begin
  10469.             set @key = index_col(@fullname, @indid, @indkey)
  10470.             exec dbo.sp_MSget_col_position @tabid, @columns, @key, @col output, @this_col output
  10471.             set @i_byte = 1 + (@this_col-1) / 8
  10472.             set @i_bit  = power(2, (@this_col-1) % 8 )
  10473.             set @byte = substring(@primary_key_bitmap, @i_byte, 1 )
  10474.             set @byte = @byte | @i_bit
  10475.             if @i_byte = 1
  10476.             begin
  10477.                 set @bitmap = @byte
  10478.             end
  10479.             else
  10480.             begin
  10481.                 set @bitmap = substring(@primary_key_bitmap, 1, @i_byte - 1)
  10482.                 set @bitmap = @bitmap + @byte
  10483.             end
  10484.  
  10485.             if @i_byte <> @num_bytes
  10486.             begin
  10487.                 set @primary_key_bitmap = @bitmap + 
  10488.                     substring(@primary_key_bitmap, @i_byte + 1, @num_bytes - @i_byte)
  10489.             end
  10490.             else
  10491.                 set @primary_key_bitmap = @bitmap
  10492.  
  10493.             select @indkey = @indkey + 1
  10494.         end
  10495.         exec @retcode = master..xp_varbintohexstr @primary_key_bitmap, @bitmap_str output
  10496.         if @retcode <> 0 or @@error <> 0
  10497.             return 1
  10498.  
  10499.         if @dest_owner is null 
  10500.         begin
  10501.             select @dest_owner = N'null'
  10502.         end
  10503.         select @replcmd = '{call sp_addsynctriggers (N' + 
  10504.             quotename(@dest_table,'''') + ', N' + 
  10505.             quotename(@dest_owner,'''') + ', N' +  
  10506.             quotename(@@SERVERNAME,'''') + ', N' +   
  10507.             quotename(db_name(),'''') + ', N' + 
  10508.             quotename(@publication,'''') + ', N' +  
  10509.             quotename(@insproc,'''') + ', N' +   
  10510.             quotename(@updproc,'''') + ', N' +   
  10511.             quotename(@delproc,'''') + ', N' +    
  10512.             quotename(@proc_owner,'''') + ', N' + 
  10513.             ISNULL(quotename(@identity_col,''''),'''null''') + ', N' + 
  10514.             ISNULL(quotename(@ts_col,''''), '''null''') + ', N''' + 
  10515.             replace(@filter_clause,'''', '''''')  + ''', ' + 
  10516.             @bitmap_str + ')}'
  10517.  
  10518.         insert into #art_commands values (@artid, @replcmd)
  10519.  
  10520.         FETCH hCsynctran_arts INTO @artid, @tabid, @dest_table, @dest_owner, @art_name, 
  10521.             @art_type, @filter_id, @columns
  10522.     end
  10523.  
  10524.     -- end SyncTran
  10525.     if @command_only = 0 
  10526.         select * from #art_commands order by id
  10527.     else
  10528.         select commands from #art_commands order by id
  10529.  
  10530.     CLOSE hCsynctran_arts
  10531.     DEALLOCATE hCsynctran_arts
  10532.  
  10533. go
  10534.  
  10535. EXEC dbo.sp_MS_marksystemobject sp_MSget_synctran_commands
  10536. GO
  10537.  
  10538. raiserror('Creating procedure sp_script_synctran_commands', 0,1)
  10539. GO
  10540. CREATE PROCEDURE sp_script_synctran_commands(
  10541.     @publication sysname,    /* publication name */
  10542.     @article sysname = 'all'    /* article name, all means all article */
  10543. ) AS
  10544.     declare @retcode int
  10545.     exec @retcode = dbo.sp_MSget_synctran_commands 
  10546.         @publication = @publication,
  10547.         @article = @article,
  10548.         @command_only = 1
  10549.     if @retcode <> 0 or @@error <> 0
  10550.         return (1)
  10551.  
  10552. go
  10553.  
  10554. dump tran master with no_log
  10555. go
  10556.  
  10557. EXEC dbo.sp_MS_marksystemobject sp_script_synctran_commands
  10558. GO
  10559.  
  10560. print ''
  10561. print 'Creating procedure sp_MSaddpub_snapshot'
  10562. go
  10563. CREATE PROCEDURE sp_MSaddpub_snapshot (
  10564.     @publication sysname,    
  10565.     @freqtype  int = 4 ,                  /* 4== Daily */
  10566.     @freqinterval int  = 1,             /* Every day */
  10567.     @freqsubtype int =  4,                 /* Sub interval = Minute */
  10568.     @freqsubinterval int = 5,              /* Every five minutes */
  10569.     @freqrelativeinterval int = 1, 
  10570.     @freqrecurrencefactor int = 0, 
  10571.     @activestartdate int = 0,             /* 12:00 am - 11:59 pm */
  10572.     @activeenddate int =99991231 ,         /* No start date */    
  10573.     @activestarttimeofday int = 0,         
  10574.     @activeendtimeofday int = 235959,     /* No end time */       
  10575.     @newagentid int = 0 OUTPUT
  10576. ) AS
  10577.  
  10578.  
  10579.     SET NOCOUNT ON
  10580.  
  10581.     /*
  10582.     ** Declarations.
  10583.     */
  10584.     DECLARE @retcode            int
  10585.     DECLARE @distributor        sysname
  10586.     DECLARE @distribdb          sysname
  10587.     DECLARE @distproc           nvarchar (255)
  10588.     DECLARE @agentname          nvarchar(100)
  10589.     DECLARE @database           sysname
  10590.     DECLARE @newid              int
  10591.     DECLARE @mergepublish_bit   smallint
  10592.     DECLARE @centralpublish_bit int
  10593.     DECLARE @fFoundPublication  int
  10594.     DECLARE @agent_args         nvarchar(4000)
  10595.     DECLARE @snapshot_jobid     binary(16)
  10596.     DECLARE @dist_rpcname       sysname
  10597.     DECLARE @publication_type   int
  10598.  
  10599.  
  10600.     /*
  10601.     ** Initializations
  10602.     */
  10603.     select @mergepublish_bit    = 4
  10604.     select @centralpublish_bit  = 1
  10605.     select @fFoundPublication   = 0
  10606.     
  10607.  
  10608.     EXEC @retcode = dbo.sp_helppublication @publication, @fFoundPublication output
  10609.  
  10610.     IF @@ERROR <> 0 OR @retcode <> 0
  10611.     BEGIN
  10612.         RETURN (1)
  10613.     END
  10614.         
  10615.     IF @fFoundPublication = 0 
  10616.     BEGIN
  10617.         SELECT @newagentid = 0
  10618.         RETURN (0)
  10619.     END
  10620.  
  10621.         
  10622.     /* 
  10623.     ** Make sure the publication does not already have a agent.
  10624.     */
  10625.     IF EXISTS (SELECT * FROM syspublications WHERE name = @publication and snapshot_jobid <> NULL)
  10626.     BEGIN
  10627.         RAISERROR (14101, 11, -1, @publication)
  10628.         RETURN(1)
  10629.     END
  10630.  
  10631.     /* Get publication_type */
  10632.     SELECT @publication_type = repl_freq from syspublications WHERe name = @publication
  10633.     
  10634.     /*
  10635.     ** Get distributor information
  10636.     */
  10637.     EXEC @retcode = dbo.sp_helpdistributor @distributor = @distributor OUTPUT, 
  10638.         @distribdb = @distribdb OUTPUT,
  10639.         @rpcsrvname = @dist_rpcname OUTPUT
  10640.     IF @@error <> 0 OR @retcode <> 0 or @distributor IS NULL OR @distribdb IS NULL
  10641.     BEGIN
  10642.         RAISERROR (14071, 16, -1)
  10643.         RETURN (1)
  10644.     END
  10645.  
  10646.     SELECT @database = DB_NAME()
  10647.  
  10648.     SELECT @distproc = RTRIM(@dist_rpcname) + '.' + @distribdb + '.dbo.sp_MSadd_snapshot_agent'
  10649.     
  10650.     SELECT @agent_args = '-Publisher ' + QUOTENAME(@@SERVERNAME)
  10651.     SELECT @agent_args = @agent_args + ' -PublisherDB ' + QUOTENAME(@database)
  10652.     SELECT @agent_args = @agent_args + ' -Distributor ' + QUOTENAME(@distributor)
  10653.     SELECT @agent_args = @agent_args + ' -Publication ' + QUOTENAME(@publication)
  10654.  
  10655.     BEGIN TRAN
  10656.  
  10657.     EXECUTE @retcode = @distproc 
  10658.         @publisher = @@SERVERNAME,
  10659.         @publisher_db = @database,
  10660.         @publication = @publication,  
  10661.         @publication_type = @publication_type,
  10662.         @local_job = 1,  
  10663.  
  10664.         @freqtype = @freqtype, 
  10665.         @freqinterval = @freqinterval, 
  10666.         @freqsubtype = @freqsubtype, 
  10667.         @freqsubinterval = @freqsubinterval, 
  10668.         @freqrelativeinterval = @freqrelativeinterval, 
  10669.         @freqrecurrencefactor = @freqrecurrencefactor, 
  10670.         @activestartdate = @activestartdate, 
  10671.         @activeenddate = @activeenddate, 
  10672.         @activestarttimeofday = @activestarttimeofday, 
  10673.         @activeendtimeofday =  @activeendtimeofday,
  10674.         @command = @agent_args,
  10675.         @snapshot_jobid = @snapshot_jobid OUTPUT
  10676.   
  10677.    IF @@ERROR <> 0 or @retcode <> 0
  10678.         GOTO UNDO
  10679.  
  10680.     -- Legacy, use non zero taskid to indicate agent already created at the distributor.
  10681.     UPDATE syspublications set snapshot_jobid =  @snapshot_jobid
  10682.         WHERE name =  @publication 
  10683.  
  10684.     IF @@ERROR <> 0 
  10685.         GOTO UNDO
  10686.  
  10687.     -- This is the output parameter to indicate agent created.
  10688.     SELECT  @newagentid = 1
  10689.  
  10690.     COMMIT TRAN
  10691.  
  10692.     return (0)  
  10693.     
  10694. UNDO:
  10695.     if @@TRANCOUNT = 1
  10696.         ROLLBACK TRAN
  10697.     else
  10698.         COMMIT TRAN
  10699.     return(1)
  10700. GO
  10701.  
  10702. EXEC dbo.sp_MS_marksystemobject sp_MSaddpub_snapshot
  10703. GO
  10704.  
  10705. dump tran master with no_log
  10706. GO
  10707.  
  10708. /*
  10709. ** SyncTran support procs
  10710. */
  10711. print ''
  10712. print 'Creating procedure sp_MSis_col_replicated'
  10713. go
  10714. create proc sp_MSis_col_replicated @publication sysname, 
  10715.     @article sysname, 
  10716.     @coltype nvarchar(10) = 'timestamp',  -- identity or timestamp
  10717.     @colname sysname = NULL OUTPUT 
  10718. as
  10719. begin
  10720.     declare @word tinyint, 
  10721.         @bit tinyint, 
  10722.         @mask binary(2), 
  10723.         @mval int,
  10724.         @colword binary(2), 
  10725.         @columns binary(32),
  10726.         @firstcol tinyint, 
  10727.         @colid smallint,
  10728.         @tabid int,
  10729.         @pubid int
  10730.         
  10731.  
  10732.     select @colname = NULL
  10733.  
  10734.     select @pubid = pubid from syspublications where name = @publication
  10735.  
  10736.     select @tabid = objid from sysarticles 
  10737.         where name = @article and pubid = @pubid
  10738.     
  10739.     if @coltype = 'timestamp'
  10740.     begin
  10741.         if ObjectProperty(@tabid, 'TableHasTimestamp') = 1 
  10742.         begin
  10743.  
  10744.             select @colname = name, @colid = colid from syscolumns 
  10745.                 where id = @tabid and type_name(xtype) = 'timestamp' 
  10746.             
  10747.             if @colname is not NULL
  10748.             begin                       
  10749.                 -- check if  timestamp is replicated
  10750.                 --  Obtain the byte offset and the bit offset, then set the
  10751.                 select @columns=columns from sysarticles where name = @article and pubid = @pubid
  10752.                 select @word = CONVERT(tinyint, 16 - FLOOR((@colid-1)/16))
  10753.                 select @bit = (@colid-1) % 16
  10754.                 select @mval = POWER(2, @bit)
  10755.                 select @mask = convert( binary(2), substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) )                                 
  10756.     
  10757.                 -- Fish out the byte we're interested in and save it in a
  10758.                 -- a temporary local variable.  
  10759.                 select @colword = convert( binary(2), SUBSTRING( convert(nchar(16),@columns), @word, 1) )
  10760.     
  10761.                 if convert( smallint, @colword ) & convert( smallint, @mask) = 0 
  10762.                 begin
  10763.                     select @colname = NULL
  10764.                     return (0)
  10765.                 end
  10766.                 else
  10767.                     return (1)
  10768.             end
  10769.             else
  10770.             begin
  10771.                 select @colname = NULL
  10772.                 return (0)
  10773.             end
  10774.         end
  10775.         else
  10776.         begin
  10777.             select @colname = NULL
  10778.             return (0)
  10779.         end
  10780.     end
  10781.     else if @coltype = 'identity'
  10782.     begin
  10783.         if ObjectProperty(@tabid, 'TableHasIdentity') = 1 
  10784.         begin
  10785.             select @colname = name, @colid = colid from syscolumns 
  10786.             where id = @tabid and ColumnProperty(@tabid, name, 'IsIdentity') = 1
  10787.             
  10788.             if @colname is not NULL
  10789.             begin                       
  10790.                 -- check if column is replicated
  10791.                 --  Obtain the byte offset and the bit offset, then set the
  10792.                 select @columns=columns from sysarticles where name = @article and pubid = @pubid
  10793.                 select @word = CONVERT(tinyint, 16 - FLOOR((@colid-1)/16))
  10794.                 select @bit = (@colid-1) % 16
  10795.                 select @mval = POWER(2, @bit)
  10796.                 select @mask = convert( binary(2), substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) )                                 
  10797.  
  10798.                 -- Fish out the byte we're interested in and save it in a
  10799.                 -- a temporary local variable.  
  10800.                 select @colword = convert( binary(2), SUBSTRING( convert(nchar(16),@columns), @word, 1) )
  10801.                 
  10802.                 if convert( smallint, @colword ) & convert( smallint, @mask) = 0 
  10803.                 begin
  10804.                     select @colname = NULL
  10805.                     return (0)
  10806.                 end
  10807.                 else
  10808.                     return (1)
  10809.             end
  10810.             else
  10811.             begin
  10812.                 select @colname = NULL
  10813.                 return (0)
  10814.             end
  10815.         end
  10816.         else
  10817.         begin
  10818.             select @colname = NULL
  10819.             return (0)
  10820.         end
  10821.     end
  10822.     else
  10823.     begin
  10824.         select @colname = NULL
  10825.         return (0)    
  10826.     end
  10827. end
  10828. go
  10829.  
  10830. EXEC dbo.sp_MS_marksystemobject sp_MSis_col_replicated
  10831. GO
  10832.  
  10833. print ''
  10834. print 'Creating procedure sp_MSis_pk_col'
  10835. go
  10836. create proc sp_MSis_pk_col @source_table sysname, @colname sysname, @indid int
  10837. as
  10838. begin
  10839.  
  10840.     declare @indkey int
  10841.     select @indkey = 1
  10842.  
  10843.     while @indkey < 16 and index_col(@source_table, @indid, @indkey) is not null
  10844.     begin
  10845.         if index_col(@source_table, @indid, @indkey) = @colname
  10846.             return (1)
  10847.  
  10848.         select @indkey = @indkey + 1
  10849.     end
  10850.  
  10851.     return (0)
  10852. end
  10853. GO
  10854.  
  10855. EXEC dbo.sp_MS_marksystemobject sp_MSis_pk_col
  10856. GO
  10857.  
  10858. print ''
  10859. print 'Creating procedure sp_MSmark_proc_norepl'
  10860. go
  10861.  
  10862. create procedure sp_MSmark_proc_norepl
  10863.     @procname sysname
  10864. as
  10865.     set nocount on
  10866.  
  10867.     -- CHECK PERMISSIONS (MUST BE DBO) --
  10868.     if not (is_member('db_owner')=1 or is_srvrolemember('sysadmin') = 1) 
  10869.     begin
  10870.         raiserror(20521,0,1)
  10871.         return 1
  10872.     end
  10873.  
  10874.     -- CHECK THE OBJECT NAME --
  10875.     if object_id(@procname, 'local') is null
  10876.     begin
  10877.         raiserror(20522,0,1,@procname)
  10878.         return 1
  10879.     end
  10880.  
  10881.     -- DO THE UPDATE --
  10882.     begin tran
  10883.     exec dbo.sp_replupdateschema @procname
  10884.     update sysobjects set replinfo = replinfo | 0x40
  10885.                         where id = object_id(@procname, 'local')
  10886.     commit tran
  10887.     return @@error 
  10888. go
  10889.  
  10890. EXEC dbo.sp_MS_marksystemobject sp_MSmark_proc_norepl
  10891. GO
  10892.  
  10893. create procedure sp_MSdrop_expired_subscription
  10894. AS
  10895. /*
  10896. ** This stored procedure is to periodically check the status of all the subscriptions 
  10897. ** of every merge publication. If any of them is out-of-date, i.e., has lost contact
  10898. ** with publisher for a certain length of time, we can declare the death of that replica
  10899. ** and cleanup their traces at the publisher side
  10900. */
  10901. declare @independent_agent  bit
  10902. declare @article            sysname
  10903. declare @publication        sysname
  10904. declare @pubid              int
  10905. declare @artid              int
  10906. declare @publisher          sysname
  10907. declare @subscriber         sysname
  10908. declare @subscriber_id      smallint
  10909. declare @subscriber_db      sysname
  10910. declare @publisher_db       sysname
  10911. declare @out_of_date        int
  10912. declare @distributor        sysname
  10913. declare @distribdb          sysname
  10914. declare @retention          int  -- in days         
  10915. declare @retcode            smallint
  10916. declare @distproc           nvarchar(255)
  10917. declare @localproc          nvarchar(255)
  10918. declare @msg                nvarchar(255)
  10919. declare @open_cursor        nvarchar(400)
  10920.  
  10921.     /*
  10922.     ** Security Check
  10923.     */
  10924. EXEC @retcode = dbo.sp_MSreplcheck_publish
  10925.     IF @@ERROR <> 0 or @retcode <> 0
  10926.         return (1)
  10927.  
  10928.     /*
  10929.     ** Get distribution server information for remote RPC call.
  10930.     */
  10931. EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  10932.      @distribdb   = @distribdb OUTPUT
  10933. IF @@ERROR <> 0 or @retcode <> 0
  10934.     BEGIN
  10935.         RAISERROR (20036, 16, -1)
  10936.         return (1)
  10937.     END
  10938.  
  10939.     
  10940. SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '.dbo.sp_MShelp_subscription_status '
  10941. select @publisher = @@SERVERNAME
  10942. select @publisher_db = db_name()
  10943.  
  10944. declare PC CURSOR LOCAL FAST_FORWARD for select DISTINCT name, pubid, independent_agent, retention from syspublications p
  10945.     open PC
  10946.     fetch PC into @publication, @pubid, @independent_agent, @retention
  10947.     WHILE (@@fetch_status <> -1)
  10948.         BEGIN
  10949.             -- Don't do anything if the retention is zero, this means 
  10950.             -- subscriptions to the publication will never expire
  10951.             IF @retention = 0
  10952.             BEGIN 
  10953.                 GOTO ZERO_RETENTION
  10954.             END
  10955.             declare SC CURSOR LOCAL FAST_FORWARD for select s.srvid, s.dest_db, a.name from syssubscriptions s, sysarticles a 
  10956.                 where a.pubid= @pubid and s.artid = a.artid and s.srvid<>-1 
  10957.                 for read only
  10958.             open SC
  10959.             fetch SC into @subscriber_id, @subscriber_db, @article
  10960.             WHILE (@@fetch_status <> -1)
  10961.                 BEGIN
  10962.                     select @subscriber=srvname from master..sysservers where srvid=@subscriber_id
  10963.                     exec @retcode = @distproc @publisher = @publisher, 
  10964.                                     @publisher_db = @publisher_db, 
  10965.                                     @publication = @publication, 
  10966.                                     @subscriber = @subscriber, 
  10967.                                     @subscriber_db = @subscriber_db,
  10968.                                     @retention = @retention,
  10969.                                     @out_of_date = @out_of_date OUTPUT,
  10970.                                     @independent_agent = @independent_agent
  10971.                     if @retcode<>0 or @@ERROR<>0 
  10972.                         begin
  10973.                             close SC
  10974.                             deallocate SC
  10975.                             close PC
  10976.                             deallocate PC
  10977.                             return (1)
  10978.                         end
  10979.                     IF (@out_of_date = 1)
  10980.                         begin
  10981.                             exec @retcode = dbo.sp_dropsubscription   -- publisher_db.dbo.sp_dropsubscription
  10982.                                 @publication = @publication,
  10983.                                 @article = @article,
  10984.                                 @subscriber = @subscriber,
  10985.                                 @destination_db = @subscriber_db
  10986.                             if @retcode <>0 or @@ERROR<>0
  10987.                                 begin
  10988.                                     close SC
  10989.                                     deallocate SC
  10990.                                     close PC
  10991.                                     deallocate PC
  10992.                                     return (1)
  10993.                                 end
  10994.                             raiserror(14157, 10, -1, @subscriber, @publication) 
  10995.                         end
  10996.                     fetch SC into @subscriber_id, @subscriber_db, @article
  10997.                 END
  10998.             CLOSE SC
  10999.             DEALLOCATE SC
  11000. ZERO_RETENTION:    
  11001.             fetch PC into @publication, @pubid, @independent_agent, @retention
  11002.         END
  11003.     CLOSE PC
  11004.     DEALLOCATE PC
  11005.  
  11006. GO
  11007. EXEC dbo.sp_MS_marksystemobject sp_MSdrop_expired_subscription
  11008. go
  11009.  
  11010.  
  11011. -- synctran supporting procs
  11012. raiserror('Creating procedure sp_MSscript_insert_statement', 0,1)
  11013. go
  11014. create procedure sp_MSscript_insert_statement
  11015.     @objid int,
  11016.     @columns binary(32)
  11017. as
  11018.     declare @cmd          nvarchar(4000)
  11019.     declare @cmd2         nvarchar(4000)
  11020.     declare @qualname     nvarchar(512)
  11021.     declare @colname      sysname
  11022.     declare @typestring   nvarchar(4000)
  11023.     declare @spacer       nvarchar(1)
  11024.     declare @ccoltype     sysname
  11025.     declare @src_cols     int
  11026.     declare @this_col     int
  11027.     declare @art_col      int
  11028.     declare @rc           int
  11029.     declare @num_col      int
  11030.     
  11031.     select @src_cols = count(*) from syscolumns where id = @objid
  11032.  
  11033.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  11034.  
  11035.     select @cmd2 = N'insert into ' + @qualname + N'( '
  11036.     
  11037.     -- col names
  11038.     select @spacer = N' '
  11039.     select @this_col = 1
  11040.     select @art_col = 1
  11041.     select @cmd = N''
  11042.  
  11043.     select @num_col = 0
  11044.     while @this_col <= @src_cols
  11045.     begin
  11046.         exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, @columns, 0, @colname output, @ccoltype output
  11047.         if @rc = 0  and EXISTS (select name from syscolumns where id=@objid and colid=@this_col and iscomputed<>1)
  11048.         begin
  11049.             if rtrim(@ccoltype) not like N'timestamp' and ColumnProperty(@objid, @colname, 'IsIdentity') != 1
  11050.             begin
  11051.                 select @num_col = @num_col + 1
  11052.                 if @cmd2 is not null
  11053.                 begin
  11054.                     exec dbo.sp_MSflush_command @cmd2 output, 1
  11055.                     select @cmd2 = null
  11056.                 end
  11057.                 select @cmd = @cmd + @spacer + QUOTENAME(@colname)
  11058.                 select @spacer = N','
  11059.                 exec dbo.sp_MSflush_command @cmd output, 0
  11060.             end
  11061.         end
  11062.         select @this_col = @this_col + 1
  11063.     end
  11064.  
  11065.     if @num_col > 0
  11066.     begin
  11067.         -- save off cmd fragment
  11068.         exec dbo.sp_MSflush_command @cmd output, 1
  11069.         insert into #proctext(procedure_text) values( N') 
  11070.          values (')
  11071.  
  11072.         -- col values
  11073.         select @spacer = N' '
  11074.         select @this_col = 1
  11075.         select @art_col = 1
  11076.         select @cmd = N''
  11077.         while @this_col <= @src_cols
  11078.         begin
  11079.             exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, @columns, 0, @colname output, @ccoltype output
  11080.             if @rc = 0 and EXISTS (select name from syscolumns where id=@objid and colid=@this_col and iscomputed<>1)
  11081.             begin
  11082.                 if rtrim(@ccoltype) not like N'timestamp' and ColumnProperty(@objid, @colname, 'IsIdentity') != 1
  11083.                 begin
  11084.                     select @cmd = @cmd + @spacer + N'@c' + convert(varchar(4), @this_col)
  11085.                     select @spacer = N','
  11086.                 end
  11087.             end
  11088.  
  11089.             exec dbo.sp_MSflush_command @cmd output, 0
  11090.             select @this_col = @this_col + 1
  11091.         end
  11092.  
  11093.         -- save off cmd fragment
  11094.         exec dbo.sp_MSflush_command @cmd output, 1
  11095.         insert into #proctext(procedure_text) values( N')
  11096.      ')
  11097.     end
  11098.     else
  11099.         -- set the @@rowcount
  11100.         insert into #proctext(procedure_text) values( N' select @retcode = @retcode
  11101.     ')
  11102.  
  11103. go
  11104.  
  11105. EXEC dbo.sp_MS_marksystemobject sp_MSscript_insert_statement
  11106. GO
  11107.  
  11108. raiserror('Creating procedure sp_MSscript_update_statement', 0,1)
  11109. go
  11110. create procedure sp_MSscript_update_statement
  11111.     @publication sysname,
  11112.     @article     sysname, 
  11113.     @objid int,
  11114.     @columns binary(32)
  11115. as
  11116.  
  11117.     declare @cmd          nvarchar(4000)
  11118.     declare @cmd2         nvarchar(4000)
  11119.     declare @qualname     nvarchar(512)
  11120.     declare @colname      sysname
  11121.     declare @typestring   nvarchar(4000)
  11122.     declare @spacer       nvarchar(1)
  11123.     declare @ccoltype     sysname
  11124.     declare @src_cols     int
  11125.     declare @this_col     int
  11126.     declare @rc           int
  11127.     declare @column          nvarchar(4000)
  11128.     declare @num_col      int
  11129.  
  11130.     declare @art_col      int -- position in the article partition.
  11131.     declare @isset          int
  11132.  
  11133.     select @src_cols = count(*) from syscolumns where id = @objid
  11134.  
  11135.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  11136.     select @cmd2 = N'update ' + @qualname + N' set'
  11137.  
  11138.     -- col names
  11139.     select @spacer = N' '
  11140.     select @this_col = 1
  11141.     select @cmd = N''
  11142.  
  11143.     -- If the table have only identity in pk and a ts col, update statement will be empty 
  11144.     -- and the query will fail. Prevent it here.
  11145.     select @num_col = 0
  11146.     select @art_col = 0
  11147.     -- script update
  11148.     while @this_col <= @src_cols 
  11149.     begin
  11150.         -- Get the ordinal of the article partition or not.
  11151.         exec @isset = dbo.sp_isarticlecolbitset @this_col, @columns
  11152.         if @isset != 0
  11153.             select @art_col = @art_col + 1
  11154.  
  11155.         exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, @columns, 0, @colname output, @ccoltype output
  11156.         if @rc = 0 and EXISTS (select name from syscolumns where id=@objid and colid=@this_col and iscomputed<>1)
  11157.         begin
  11158.             if rtrim(@ccoltype) not like N'timestamp' and ColumnProperty(@objid, @colname, 'IsIdentity') != 1
  11159.             begin
  11160.                 if @cmd2 is not null
  11161.                 begin
  11162.                     exec dbo.sp_MSflush_command @cmd2 output, 1
  11163.                     select @cmd2 = null
  11164.                 end
  11165.  
  11166.                 select @num_col = @num_col + 1
  11167.                 -- Optimization:
  11168.                 -- Get null or actual column name
  11169.                 -- Note: the output is quoted.
  11170.                 exec dbo.sp_MSget_synctran_column 
  11171.                         @ts_col = null,
  11172.                         @op_type = null , -- 'ins, 'upd', 'del'
  11173.                         @is_new = null,
  11174.                         @primary_key_bitmap = null,
  11175.                         @colname = @colname,
  11176.                         @this_col = @this_col,
  11177.                         @column = @column output,
  11178.                         @from_proc = 1,
  11179.                         @art_col = @art_col -- position in the partition.
  11180.  
  11181.  
  11182.                 select @cmd = @cmd + @spacer + QUOTENAME(@colname) + N' = ' + @column 
  11183.                 select @spacer = N','
  11184.                 -- flush command if necessary
  11185.                 exec dbo.sp_MSflush_command @cmd output, 0
  11186.  
  11187.             end
  11188.         end
  11189.         
  11190.         select @this_col = @this_col + 1
  11191.     end
  11192.  
  11193.     -- save off cmd fragment
  11194.     if @num_col > 0
  11195.     begin
  11196.         exec dbo.sp_MSflush_command @cmd output, 1
  11197.           
  11198.         -- Determine method of conflict detection and add where clause
  11199.         if ObjectProperty(@objid, 'TableHasTimestamp') = 1
  11200.         begin
  11201.             exec @rc = dbo.sp_MSis_col_replicated @publication, @article, 'timestamp', @colname OUTPUT 
  11202.             if @rc = 1
  11203.             begin
  11204.                 insert into #proctext(procedure_text) values( N'
  11205.     ') 
  11206.                 exec dbo.sp_MSscript_where_clause @objid, @columns, 'upd ts', @colname, 4
  11207.             end
  11208.         end
  11209.         else
  11210.         begin
  11211.             insert into #proctext(procedure_text) values( N'
  11212.     ')
  11213.             exec dbo.sp_MSscript_where_clause @objid, @columns, 'upd rc', null, 4
  11214.         end
  11215.     end 
  11216.     else
  11217.         -- set the @@rowcount
  11218.         insert into #proctext(procedure_text) values( N' select @retcode = @retcode
  11219.     ')
  11220. go
  11221.  
  11222. EXEC dbo.sp_MS_marksystemobject sp_MSscript_update_statement
  11223. GO
  11224.  
  11225. raiserror('Creating procedure sp_MSscript_delete_statement', 0,1)
  11226. go
  11227. create procedure sp_MSscript_delete_statement
  11228.     @publication sysname,
  11229.     @article     sysname, 
  11230.     @objid int,
  11231.     @columns binary(32)
  11232. as
  11233.     declare @cmd          nvarchar(4000)
  11234.     declare @qualname     nvarchar(512)
  11235.     declare @colname      sysname
  11236.     declare @typestring   nvarchar(4000)
  11237.     declare @spacer       nvarchar(1)
  11238.     declare @ccoltype     sysname
  11239.     declare @src_cols     int
  11240.     declare @this_col     int
  11241.     declare @art_col      int
  11242.     declare @rc           int
  11243.  
  11244.     select @src_cols = count(*) from syscolumns where id = @objid
  11245.  
  11246.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  11247.     select @cmd = N'delete ' + @qualname
  11248.     exec dbo.sp_MSflush_command @cmd output, 1
  11249.  
  11250.     -- Determine method of conflict detection and add where clause
  11251.     insert into #proctext(procedure_text) values( N'
  11252. ')
  11253.     if ObjectProperty(@objid, 'TableHasTimestamp') = 1
  11254.     begin
  11255.         exec @rc = dbo.sp_MSis_col_replicated @publication, @article, 'timestamp', @colname OUTPUT 
  11256.         if @rc = 1
  11257.             exec dbo.sp_MSscript_where_clause @objid, @columns, 'upd ts', @colname, 4
  11258.         else
  11259.             exec dbo.sp_MSscript_where_clause @objid, @columns, 'upd rc', null, 4
  11260.     end 
  11261.     else
  11262.         exec dbo.sp_MSscript_where_clause @objid, @columns, 'upd rc', null, 4
  11263. go
  11264.  
  11265. EXEC dbo.sp_MS_marksystemobject sp_MSscript_delete_statement
  11266. GO
  11267.  
  11268. raiserror('Creating procedure sp_MSscript_beginproc', 0,1)
  11269. go
  11270. create procedure sp_MSscript_beginproc 
  11271.     @publication  sysname, 
  11272.     @article      sysname, 
  11273.     @procname     sysname,
  11274.     @source_objid int        output,
  11275.     @columns      binary(32) output
  11276. as
  11277.     declare @cmd nvarchar(4000)
  11278.     declare @source_table sysname
  11279.     declare @owner sysname
  11280.  
  11281.     -- Retrieve underlying table name and replicated columns
  11282.     select @source_table = object_name(objid), @source_objid = objid, @columns = columns from sysarticles a, syspublications p
  11283.         where a.name = @article and
  11284.               p.name = @publication and
  11285.               a.pubid = p.pubid
  11286.  
  11287.     -- Get the object owner name
  11288.     select @owner = u.name from sysusers u, sysobjects o where 
  11289.         o.id = @source_objid and
  11290.         o.uid = u.uid
  11291.             
  11292.     if @source_table IS NULL
  11293.     begin
  11294.         raiserror (20506, 16, 1,  @source_table, 'sp_MSscript_beginproc')
  11295.         return 0
  11296.     end
  11297.  
  11298.     -- Construct proc name
  11299.     -- Create proc under the table owner account to preserve the ownership chain
  11300.     select @cmd = N'create procedure '+QUOTENAME(@owner)+ N'.'+ QUOTENAME(@procname) + N' @orig_server sysname, @orig_db sysname, '
  11301.     exec dbo.sp_MSflush_command @cmd output, 1
  11302.  
  11303.     return 1
  11304. go
  11305.  
  11306. EXEC dbo.sp_MS_marksystemobject sp_MSscript_beginproc
  11307. GO
  11308.  
  11309. raiserror('Creating procedure sp_MSscript_security', 0,1)
  11310. go
  11311. create procedure sp_MSscript_security 
  11312.     @publication sysname
  11313. as
  11314.     declare @cmd nvarchar(4000)
  11315.  
  11316.     -- insert into #proctext(procedure_text) values(N'declare @retcode int')
  11317.     insert into #proctext(procedure_text) values(N'exec @retcode = dbo.sp_MSreplcheck_pull')
  11318.     insert into #proctext(procedure_text) values(N'@publication = ''' + @publication + '''
  11319. ' )
  11320.     insert into #proctext(procedure_text) values(N'if @retcode <> 0 or @@error <> 0' )
  11321.     insert into #proctext(procedure_text) values(N' return -1
  11322.  
  11323. ')
  11324.                     
  11325. go
  11326.  
  11327. EXEC dbo.sp_MS_marksystemobject sp_MSscript_security
  11328. GO
  11329.  
  11330. raiserror('Creating procedure sp_MSscript_endproc', 0,1)
  11331. go
  11332. create procedure sp_MSscript_endproc 
  11333.     @objid int, 
  11334.     @op_type varchar(3) = 'ins', -- 'ins', 'upd', 'del'
  11335.     @columns binary(32),
  11336.     @outvars nvarchar(4000)
  11337. as
  11338.     declare @cmd nvarchar(4000)
  11339.     declare @qualname nvarchar(512)
  11340.  
  11341.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  11342.  
  11343.     insert into #proctext(procedure_text) values(N'
  11344.  
  11345.  if @@ROWCOUNT = 0
  11346.  begin
  11347.      exec sp_MSreplraiserror 20515
  11348.      return -1
  11349.  end')
  11350.                     
  11351.     if @outvars <> null
  11352.     begin   
  11353.         insert into #proctext(procedure_text) values(N'
  11354.  else
  11355.  begin 
  11356. ')
  11357.         if @op_type = 'upd'
  11358.             -- Script out pk var assigment that used in sp_MSscript_where_clause
  11359.             exec dbo.sp_MSscript_pkvar_assignment @objid, @columns, 1
  11360.  
  11361.         insert into #proctext(procedure_text) values(N'
  11362. ')
  11363.  
  11364.         select @cmd = N'    select ' + @outvars 
  11365.         insert into #proctext(procedure_text) values( @cmd)
  11366.         select @cmd = N'
  11367.      from ' + @qualname 
  11368.         insert into #proctext(procedure_text) values( @cmd)
  11369.  
  11370.         insert into #proctext(procedure_text) values( N'
  11371. ')
  11372.         if @op_type = 'ins'
  11373.             exec dbo.sp_MSscript_where_clause @objid, @columns, 'new pk', null, 4
  11374.         else if @op_type = 'upd'
  11375.             exec dbo.sp_MSscript_where_clause @objid, @columns, 'old pk', null, 4
  11376.  
  11377.         insert into #proctext(procedure_text) values( N'    return 0
  11378. ')
  11379.         insert into #proctext(procedure_text) values( N'end
  11380.  
  11381. ')
  11382.     end
  11383.     else
  11384.     begin
  11385.         insert into #proctext(procedure_text) values( N'
  11386.  else 
  11387.      return 0')
  11388.     end
  11389. go
  11390.  
  11391. EXEC dbo.sp_MS_marksystemobject sp_MSscript_endproc
  11392. GO
  11393.  
  11394. raiserror('Creating procedure sp_MStable_not_modifiable', 0,1)
  11395. go
  11396. create proc sp_MStable_not_modifiable
  11397.     @objid   int,
  11398.     @columns binary(32)
  11399. as
  11400.     declare @colname      sysname
  11401.     declare @typestring   nvarchar(4000)
  11402.     declare @src_cols     int
  11403.     declare @this_col     int
  11404.     declare @art_col      int
  11405.     declare @isset        int
  11406.     declare @found int, @repl_columns int
  11407.  
  11408.     select @this_col = 1
  11409.     select @art_col = 1
  11410.     select @found = 0, @repl_columns = 0
  11411.     select @src_cols = count(*) from syscolumns where id = @objid
  11412.  
  11413.     while @this_col <= @src_cols 
  11414.     begin
  11415.         exec @isset = dbo.sp_isarticlecolbitset @this_col, @columns
  11416.  
  11417.         if @isset != 0 and EXISTS (select name from syscolumns where id=@objid and @this_col=colid and iscomputed<>1)
  11418.         begin
  11419.             select @repl_columns = @repl_columns + 1
  11420.             exec dbo.sp_MSget_type @objid, @this_col, @colname output, @typestring OUTPUT
  11421.  
  11422.             if @typestring = N'timestamp' or ColumnProperty(@objid, @colname, 'IsIdentity') = 1
  11423.                 select @found = 1
  11424.  
  11425.         end
  11426.         select @this_col = @this_col + 1
  11427.     end
  11428.  
  11429.     if @found = 1 and @repl_columns = 1
  11430.         return 1
  11431.     else
  11432.         return 0
  11433. go
  11434.  
  11435.  
  11436. EXEC dbo.sp_MS_marksystemobject sp_MStable_not_modifiable
  11437. GO
  11438.  
  11439. raiserror('Creating procedure sp_MSscript_sync_ins_proc', 0,1)
  11440. go
  11441. create procedure sp_MSscript_sync_ins_proc 
  11442.     @publication sysname, 
  11443.     @article     sysname,
  11444.     @procname    sysname
  11445. as
  11446.     declare @source_objid int
  11447.     declare @colname sysname
  11448.     declare @indid int
  11449.     declare @cmd          nvarchar(4000)
  11450.     declare @ins_cmd      nvarchar(4000)
  11451.     declare @columns      binary(32)
  11452.     declare @outvars      nvarchar(4000)
  11453.     declare @rc           int
  11454.  
  11455.     set nocount on
  11456.     -- Create temp table
  11457.     create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) NULL)
  11458.  
  11459.     -- preamble common to all synctran procs
  11460.     exec @rc = dbo.sp_MSscript_beginproc @publication, @article, @procname, @source_objid output, @columns output
  11461.     if @rc = 0
  11462.         return
  11463.     
  11464.     -- construct parameter list
  11465.     exec dbo.sp_MSscript_params @source_objid, @columns, null, 1,  @outvars output
  11466.  
  11467.     -- construct body of procedure
  11468.     insert into #proctext(procedure_text) values( N'
  11469.  as
  11470. ')
  11471.  
  11472.     -- set cycle detection
  11473.     insert into #proctext(procedure_text) values(N'declare @retcode int
  11474.  
  11475. ')
  11476.  
  11477.     insert into #proctext(procedure_text) values( N'exec @retcode = dbo.sp_replsetoriginator @orig_server, @orig_db
  11478. ')
  11479.     insert into #proctext(procedure_text) values( N'if @retcode <> 0 or @@error <> 0 return -1
  11480.  
  11481. ')
  11482.  
  11483.     -- script out security check
  11484.     exec dbo.sp_MSscript_security @publication
  11485.  
  11486.      -- script out subscription validation
  11487.     exec dbo.sp_MSscript_validate_subscription @publication, @article
  11488.  
  11489.     -- Work around for case where article has 1 col that is not user-modfied (identity, timestamp)
  11490.     exec @rc = dbo.sp_MStable_not_modifiable @source_objid, @columns
  11491.     if @rc = 1
  11492.         insert into #proctext(procedure_text) values( N'exec sp_MSreplraiserror 20516
  11493.  
  11494. ')
  11495.      
  11496.     else
  11497.     begin
  11498.         exec @indid = dbo.sp_MStable_has_unique_index @source_objid 
  11499.         if @outvars <> null and @indid = 0
  11500.            -- no insert/update allowed if timestamp/identity col and no unique index
  11501.             insert into #proctext(procedure_text) values( N'exec sp_MSreplraiserror 20516
  11502.  
  11503. ')
  11504.     
  11505.         else
  11506.         begin
  11507.                 
  11508.             -- script insert statemnt
  11509.             exec dbo.sp_MSscript_insert_statement @source_objid, @columns
  11510.  
  11511.             -- script closing 
  11512.             exec dbo.sp_MSscript_endproc @source_objid, 'ins', @columns, @outvars
  11513.         end
  11514.     end
  11515.  
  11516.     -- send fragments to client
  11517.     select procedure_text from #proctext order by c1 asc
  11518.  
  11519. go
  11520.  
  11521. EXEC dbo.sp_MS_marksystemobject sp_MSscript_sync_ins_proc
  11522. GO
  11523.  
  11524. raiserror('Creating procedure sp_MSscript_sync_upd_proc', 0,1)
  11525. go
  11526. create procedure sp_MSscript_sync_upd_proc 
  11527.     @publication sysname, 
  11528.     @article     sysname,
  11529.     @procname    sysname
  11530. as
  11531.     declare @source_objid int
  11532.     declare @colname      sysname
  11533.     declare @indid        int
  11534.     declare @cmd          nvarchar(4000)
  11535.     declare @ins_cmd      nvarchar(4000)
  11536.     declare @columns      binary(32)
  11537.     declare @outvars      nvarchar(4000)
  11538.     declare @rc           int
  11539.  
  11540.     set nocount on
  11541.  
  11542.     -- Create temp table
  11543.     create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) NULL)
  11544.  
  11545.     -- preamble common to all synctran procs
  11546.     exec @rc = dbo.sp_MSscript_beginproc @publication, @article, @procname, @source_objid output, @columns output
  11547.     if @rc = 0
  11548.         return
  11549.  
  11550.     -- construct parameter list
  11551.     exec dbo.sp_MSscript_params @source_objid, @columns, null, 1, @outvars output
  11552.     insert into #proctext(procedure_text) values( N', 
  11553. ')
  11554.     exec dbo.sp_MSscript_params @source_objid, @columns, N'_old', 0, null
  11555.  
  11556.     -- Script bitmap parameter
  11557.     insert into #proctext(procedure_text) values( N', @bitmap varbinary(4000)')
  11558.  
  11559.     -- construct body of procedure
  11560.     insert into #proctext(procedure_text) values( N'
  11561.  as
  11562. ')
  11563.  
  11564.     -- set cycle detection
  11565.     insert into #proctext(procedure_text) values(N'declare @retcode int
  11566.  
  11567. ')
  11568.     insert into #proctext(procedure_text) values( N'exec @retcode = dbo.sp_replsetoriginator @orig_server, @orig_db
  11569. ')
  11570.     insert into #proctext(procedure_text) values( N'if @retcode <> 0 or @@error <> 0 return -1
  11571.     
  11572. ')
  11573.  
  11574.     -- script out security check
  11575.     exec dbo.sp_MSscript_security @publication
  11576.  
  11577.      -- script out subscription validation
  11578.     exec dbo.sp_MSscript_validate_subscription @publication, @article
  11579.  
  11580.     -- Work around for case where article has 1 col that is not user-modfied (identity, timestamp)
  11581.     exec @rc = dbo.sp_MStable_not_modifiable @source_objid, @columns
  11582.     if @rc = 1
  11583.         insert into #proctext(procedure_text) values( N'exec sp_MSreplraiserror 20516
  11584.  
  11585. ')
  11586.      
  11587.     else
  11588.     begin
  11589.         exec @indid = dbo.sp_MStable_has_unique_index @source_objid
  11590.         if @outvars <> null and @indid = 0
  11591.             -- no insert/update allowed if timestamp/identity col and no unique index
  11592.             insert into #proctext(procedure_text) values( N'exec sp_MSreplraiserror 20516
  11593.  
  11594. ')
  11595.         else
  11596.         begin
  11597.             -- script update statemnt
  11598.             exec dbo.sp_MSscript_update_statement @publication, @article, @source_objid, @columns
  11599.  
  11600.             -- script closing 
  11601.             exec dbo.sp_MSscript_endproc @source_objid, 'upd', @columns, @outvars
  11602.         end
  11603.     end
  11604.  
  11605.     -- send fragments to client
  11606.     select procedure_text from #proctext order by c1 asc
  11607.  
  11608. go
  11609.  
  11610. EXEC dbo.sp_MS_marksystemobject sp_MSscript_sync_upd_proc
  11611. GO
  11612.  
  11613. raiserror('Creating procedure sp_MSscript_sync_del_proc', 0,1)
  11614. go
  11615. create procedure sp_MSscript_sync_del_proc 
  11616.     @publication sysname, 
  11617.     @article     sysname,
  11618.     @procname    sysname
  11619. as
  11620.     declare @source_objid int
  11621.     declare @colname sysname
  11622.     declare @indid int
  11623.     declare @cmd          nvarchar(4000)
  11624.     declare @ins_cmd      nvarchar(4000)
  11625.     declare @columns      binary(32)
  11626.     declare @outvars      nvarchar(4000)
  11627.     declare @rc           int
  11628.  
  11629.     set nocount on
  11630.  
  11631.     -- Create temp table
  11632.     create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) NULL)
  11633.     
  11634.     -- preamble common to all synctran procs
  11635.     exec @rc = dbo.sp_MSscript_beginproc @publication, @article, @procname, @source_objid output, @columns output
  11636.     if @rc = 0
  11637.         return
  11638.          
  11639.     -- construct parameter list
  11640.     exec dbo.sp_MSscript_params @source_objid, @columns, N'_old', 0, null
  11641.     
  11642.     -- construct body of procedure
  11643.     insert into #proctext(procedure_text) values( N'
  11644.  as
  11645. ')
  11646.  
  11647.     -- set cycle detection
  11648.     insert into #proctext(procedure_text) values(N'declare @retcode int
  11649.  
  11650. ')
  11651.     insert into #proctext(procedure_text) values( N'exec @retcode = dbo.sp_replsetoriginator @orig_server, @orig_db
  11652. ')
  11653.     insert into #proctext(procedure_text) values( N'if @retcode <> 0 or @@error <> 0 return -1
  11654.  
  11655. ')
  11656.  
  11657.     -- script out security check
  11658.     exec dbo.sp_MSscript_security @publication
  11659.     
  11660.      -- script out subscription validation
  11661.     exec dbo.sp_MSscript_validate_subscription @publication, @article
  11662.  
  11663.     -- Work around for case where article has 1 col that is not user-modfied (identity, timestamp)
  11664.     exec @rc = dbo.sp_MStable_not_modifiable @source_objid, @columns
  11665.     if @rc = 1
  11666.         insert into #proctext(procedure_text) values( N'exec sp_MSreplraiserror 20516
  11667.  
  11668. ')
  11669.      
  11670.     else
  11671.         begin
  11672.             exec @indid = dbo.sp_MStable_has_unique_index @source_objid
  11673.             if @indid = 0
  11674.                 -- no delete allowed if  no unique index
  11675.                 insert into #proctext(procedure_text) values( N'exec sp_MSreplraiserror 20516
  11676.  
  11677. ')
  11678.             else
  11679.             begin    
  11680.                 -- script insert statemnt
  11681.                 exec dbo.sp_MSscript_delete_statement @publication, @article, @source_objid, @columns
  11682.  
  11683.                 -- script closing 
  11684.                 exec dbo.sp_MSscript_endproc @source_objid, 'del', @columns, null
  11685.             end
  11686.         end
  11687.  
  11688.         -- send fragments to client
  11689.         select procedure_text from #proctext order by c1 asc
  11690. go
  11691.  
  11692. EXEC dbo.sp_MS_marksystemobject sp_MSscript_sync_del_proc
  11693. GO
  11694.  
  11695. print ''
  11696. print 'Creating procedure sp_MSgen_sync_tran_procs'
  11697. go
  11698. create procedure sp_MSgen_sync_tran_procs
  11699.     @publication    sysname,        -- table name 
  11700.     @article        sysname,
  11701.     @ins_proc       sysname,
  11702.     @upd_proc       sysname,
  11703.     @del_proc       sysname
  11704.  
  11705. as
  11706.     set nocount on
  11707.  
  11708.     declare @cmd nvarchar(4000)
  11709.     declare @dbname sysname
  11710.     declare @owner sysname
  11711.     declare @retcode int
  11712.  
  11713.     select @owner = user_name(o.uid) from sysobjects o , sysarticles a where o.id=a.objid and a.name=@article
  11714.  
  11715.     -- We are now going to create procs, so start a transaction
  11716.     begin tran gen_procs
  11717.        -- Call out to individual create proc routines
  11718.        select @dbname = db_name()
  11719.        select @cmd = 'sp_MSscript_sync_ins_proc [' + @publication + '], [' + @article  + '], [' + @ins_proc + ']'
  11720.        exec master..xp_execresultset @cmd, @dbname
  11721.  
  11722.        select @cmd = 'sp_MSscript_sync_upd_proc [' + @publication + '], [' + @article  + '], [' + @upd_proc + ']'
  11723.        exec master..xp_execresultset @cmd, @dbname
  11724.  
  11725.        select @cmd = 'sp_MSscript_sync_del_proc  [' + @publication + '], [' + @article  + '], [' + @del_proc  + ']'
  11726.        exec master..xp_execresultset @cmd, @dbname
  11727.  
  11728.         -- Grant permissions
  11729.         select @cmd = 'grant exec on ' + quotename(@owner) + '.' + quotename(@ins_proc) + ' to public'
  11730.         exec (@cmd)
  11731.         select @cmd = 'grant exec on ' + quotename(@owner) + '.' + quotename(@upd_proc) + ' to public'
  11732.         exec (@cmd)
  11733.         select @cmd = 'grant exec on ' + quotename(@owner) + '.' + quotename(@del_proc) + ' to public'
  11734.         exec (@cmd)
  11735.  
  11736.         -- Mark procedures as system procs so they don't show up in the UI
  11737.         if @owner in ('dbo','INFORMATION_SCHEMA')
  11738.         begin
  11739.             select @cmd = 'exec dbo.sp_MS_marksystemobject ''' + quotename(@owner) + '.' + quotename(@ins_proc) + '''' 
  11740.             exec (@cmd)
  11741.             select @cmd = 'exec dbo.sp_MS_marksystemobject ''' + quotename(@owner) + '.' + quotename(@upd_proc) + ''''
  11742.             exec (@cmd)
  11743.             select @cmd = 'exec dbo.sp_MS_marksystemobject ''' + quotename(@owner) + '.' + quotename(@del_proc) + ''''
  11744.             exec (@cmd)
  11745.         end
  11746.  
  11747.         -- Mark procedures to set 'NOT FOR REPL' bit
  11748.         select @cmd = 'exec dbo.sp_MSmark_proc_norepl ''' + quotename(@owner) + '.' + quotename(@ins_proc) + ''''
  11749.         exec (@cmd)
  11750.         select @cmd = 'exec dbo.sp_MSmark_proc_norepl ''' + quotename(@owner) + '.' + quotename(@upd_proc) + ''''
  11751.         exec (@cmd)
  11752.         select @cmd = 'exec dbo.sp_MSmark_proc_norepl ''' + quotename(@owner) + '.' + quotename(@del_proc) + ''''
  11753.         exec (@cmd)
  11754.  
  11755.     -- Commit tran
  11756.     commit tran
  11757. go
  11758.  
  11759. EXEC dbo.sp_MS_marksystemobject sp_MSgen_sync_tran_procs
  11760. GO
  11761.  
  11762. print ''
  11763. print 'Creating procedure sp_articlesynctranprocs'
  11764. go
  11765.  
  11766. CREATE PROCEDURE sp_articlesynctranprocs
  11767.     @publication sysname,         -- publication name 
  11768.     @article sysname,              -- article name 
  11769.     @ins_proc sysname,       -- name of sproc supporting Sync Tran inserts associated with this article
  11770.     @upd_proc sysname,       -- name of sproc supporting Sync Tran updates associated with this article
  11771.     @del_proc sysname,       -- name of sproc supporting Sync Tran deletes associated with this article
  11772.     @autogen       nvarchar(5) = 'true' -- indicates wether or not to auto generate sprocs
  11773. AS
  11774.     SET NOCOUNT ON
  11775.  
  11776.     -- Declarations.
  11777.     DECLARE @pubid int
  11778.     DECLARE @artid int
  11779.     DECLARE @retcode int
  11780.     DECLARE @autogen_id bit
  11781.     DECLARE @ins_proc_id int
  11782.     DECLARE @upd_proc_id int
  11783.     DECLARE @del_proc_id int
  11784.     
  11785.     /* 
  11786.     ** Security Check.
  11787.     */
  11788.     exec @retcode = dbo.sp_MSreplcheck_publish
  11789.     if @@ERROR <> 0 or @retcode <> 0
  11790.         return(1)
  11791.     
  11792.     -- Parameter Check: @article. The @article name cannot be NULL and must conform 
  11793.     -- to the rules for identifiers.
  11794.     IF @article IS NULL
  11795.         BEGIN
  11796.             RAISERROR (14043, 16, -1, '@article')
  11797.             RETURN (1)
  11798.         END
  11799.  
  11800.     EXECUTE @retcode = dbo.sp_validname @article
  11801.     IF @retcode <> 0
  11802.         RETURN(1)
  11803.     
  11804.     -- Parameter Check: @publication.
  11805.     -- The @publication name cannot be NULL and must conform to the rules
  11806.     -- for identifiers.
  11807.     IF @publication IS NULL
  11808.         BEGIN
  11809.             RAISERROR (14043, 16, -1, '@publication')
  11810.             RETURN (1)
  11811.         END
  11812.  
  11813.     EXECUTE @retcode = dbo.sp_validname @publication
  11814.     IF @retcode <> 0
  11815.         RETURN (1)
  11816.  
  11817.     -- Parameter Check: @ins_proc, @upd_proc, @del_proc.
  11818.     -- The sproc names cannot be NULL and must conform to the rules
  11819.     -- for identifiers
  11820.  
  11821.     IF @ins_proc IS NULL
  11822.         BEGIN
  11823.             RAISERROR (14043, 16, -1, '@ins_proc')
  11824.             RETURN (1)
  11825.         END
  11826.  
  11827.     EXECUTE @retcode = dbo.sp_validname @ins_proc
  11828.     IF @retcode <> 0
  11829.         RETURN (1)
  11830.  
  11831.     IF @upd_proc IS NULL
  11832.         BEGIN
  11833.             RAISERROR (14043, 16, -1, '@upd_proc')
  11834.             RETURN (1)
  11835.         END
  11836.  
  11837.     EXECUTE @retcode = dbo.sp_validname @upd_proc
  11838.     IF @retcode <> 0
  11839.         RETURN (1)
  11840.  
  11841.     IF @del_proc IS NULL
  11842.         BEGIN
  11843.             RAISERROR (14043, 16, -1, '@del_proc')
  11844.             RETURN (1)
  11845.         END
  11846.  
  11847.     EXECUTE @retcode = dbo.sp_validname @del_proc
  11848.     IF @retcode <> 0
  11849.         RETURN (1)
  11850.  
  11851.     -- Parameter Check:  @autogen
  11852.     IF @autogen IS NULL OR LOWER(@autogen) NOT IN ('true', 'false')
  11853.     BEGIN
  11854.         RAISERROR (14148, 16, -1, '@autogen')
  11855.         RETURN (1)
  11856.     END
  11857.  
  11858.     IF LOWER(@autogen) = 'true' 
  11859.         SELECT @autogen_id = 1
  11860.     ELSE 
  11861.         SELECT @autogen_id = 0
  11862.  
  11863.     -- Retrieve pubid & artid
  11864.     SELECT @pubid = a.pubid, @artid = a.artid 
  11865.     FROM sysarticles a, syspublications p
  11866.     WHERE p.name = @publication AND a.name = @article AND
  11867.         a.pubid = p.pubid
  11868.     IF @pubid IS NULL OR @artid IS NULL
  11869.     BEGIN
  11870.         if @pubid IS NULL RAISERROR (20026, 16, 1, @publication)
  11871.         if @artid IS NULL RAISERROR (20026, 16, 1, @publication)
  11872.         RETURN (1)
  11873.     END
  11874.  
  11875.        BEGIN TRAN sp_articlesynctranprocs
  11876.  
  11877.         -- if @autogen is true, generate the sprocs
  11878.         IF @autogen_id = 1
  11879.         BEGIN
  11880.             EXECUTE @retcode =  dbo.sp_MSgen_sync_tran_procs @publication, @article, 
  11881.                 @ins_proc, @upd_proc, @del_proc
  11882.             IF @retcode <> 0
  11883.             BEGIN
  11884.                 IF @@TRANCOUNT <> 0
  11885.                     ROLLBACK tran sp_articlesynctranprocs
  11886.                 RETURN (1)
  11887.             END
  11888.         END
  11889.  
  11890.         --retrieve sproc id's, fail if they don't exist
  11891.         SELECT @ins_proc_id = id FROM sysobjects WHERE name = @ins_proc
  11892.         SELECT @upd_proc_id = id FROM sysobjects WHERE name = @upd_proc
  11893.         SELECT @del_proc_id = id FROM sysobjects WHERE name = @del_proc
  11894.  
  11895.         IF (@ins_proc_id IS NULL) OR (@upd_proc_id IS NULL) OR (@del_proc_id IS NULL)
  11896.         BEGIN
  11897.             if @ins_proc_id IS NULL RAISERROR (20500, 16, 1, @ins_proc)
  11898.             if @upd_proc_id IS NULL RAISERROR (20500, 16, 1, @upd_proc)
  11899.             if @del_proc_id IS NULL RAISERROR (20500, 16, 1, @del_proc)
  11900.             IF @@TRANCOUNT <> 0
  11901.                 ROLLBACK tran sp_articlesynctranprocs
  11902.             RETURN (1)
  11903.         END
  11904.  
  11905.         -- perform insert into sysarticleupdates
  11906.         -- BUGUBG need to mark this as a system table, so this sproc can live in master db
  11907.         INSERT sysarticleupdates(pubid, artid, sync_ins_proc, sync_upd_proc, sync_del_proc, autogen)
  11908.             VALUES (@pubid, @artid, @ins_proc_id, @upd_proc_id, @del_proc_id, @autogen_id)
  11909.  
  11910.         IF @@ERROR <> 0
  11911.             BEGIN
  11912.                 IF @@TRANCOUNT <> 0
  11913.                     ROLLBACK tran sp_articlesynctranprocs
  11914.                 RETURN (1)
  11915.             END
  11916.  
  11917.     COMMIT TRAN
  11918. go
  11919.  
  11920. EXEC dbo.sp_MS_marksystemobject sp_articlesynctranprocs
  11921. GO
  11922.  
  11923. print ''
  11924. print 'Creating procedure sp_reinitsubscription'
  11925. go
  11926.  
  11927. CREATE PROCEDURE sp_reinitsubscription (
  11928.     @publication sysname = 'all',    /* publication name */
  11929.     @article sysname = 'all',        /* article name */
  11930.     -- Force user to specify the subscriber name
  11931.     @subscriber sysname,             /* subscriber name */
  11932.     @destination_db sysname = 'all'   /* destination database name */
  11933. ) AS
  11934.  
  11935.     DECLARE @retcode int
  11936.     DECLARE @distributor sysname
  11937.     DECLARE @distribdb sysname
  11938.     declare @active tinyint
  11939.     declare @subscribed tinyint
  11940.     declare @automatic tinyint
  11941.     DECLARE @artid int
  11942.     DECLARE @srvid smallint
  11943.     DECLARE @distproc nvarchar (255)
  11944.     DECLARE @dbname sysname
  11945.     DECLARE @sub_ts binary(10) -- must be binary(10) type.
  11946.     DECLARE @sync_type tinyint
  11947.     DECLARE @immediate_sync bit
  11948.     DECLARE @subscription_type int
  11949.     DECLARE @push int
  11950.     DECLARE @pub sysname
  11951.     DECLARE @dest_db sysname
  11952.     DECLARE @sub_name sysname
  11953.     DECLARE @art_name sysname
  11954.     DECLARE @none tinyint
  11955.     declare @login_name sysname
  11956.  
  11957.  
  11958.   
  11959.     -- Initialization
  11960.     select @active = 2
  11961.     select @subscribed = 1
  11962.     select @dbname = DB_NAME()
  11963.     SELECT @none = 2            /* Const: synchronization type 'none' */
  11964.     SELECT @automatic = 1       /* Const: synchronization type 'automatic' */
  11965.     select @push = 0
  11966.  
  11967.     /* 
  11968.     ** Security Check.
  11969.     ** We use login_name stored in syssubscriptions to manage security 
  11970.     */
  11971.  
  11972.     /* Validate names */
  11973.  
  11974.     EXECUTE @retcode = dbo.sp_validname @publication
  11975.     IF @@ERROR <> 0 OR @retcode <> 0
  11976.         RETURN (1)
  11977.  
  11978.     /* article name can be a quoted name
  11979.     EXECUTE @retcode = dbo.sp_validname @article
  11980.     IF @@ERROR <> 0 OR @retcode <> 0
  11981.         RETURN (1)
  11982.     */
  11983.  
  11984.     -- Subscriber can be NULL
  11985.     IF @subscriber IS NOT NULL
  11986.     BEGIN
  11987.         EXECUTE @retcode = dbo.sp_validname @subscriber
  11988.         IF @@ERROR <> 0 OR @retcode <> 0
  11989.             RETURN (1)
  11990.  
  11991.         EXECUTE @retcode = dbo.sp_validname @destination_db
  11992.         IF @@ERROR <> 0 OR @retcode <> 0
  11993.             RETURN (1)
  11994.     END
  11995.  
  11996.     -- Replace 'all' with '%'
  11997.     if LOWER(@publication) = 'all'
  11998.         SELECT @publication = '%'
  11999.  
  12000.     if LOWER(@article) = 'all'
  12001.         SELECT @article = '%'
  12002.  
  12003.     if LOWER(@subscriber) = 'all'
  12004.         SELECT @subscriber = '%'
  12005.  
  12006.     if LOWER(@destination_db) = 'all'
  12007.         SELECT @destination_db = '%'
  12008.  
  12009.     /*
  12010.     ** Parameter Check:  @publication
  12011.     ** Check to make sure that the publication exists, that it's not NULL,
  12012.     ** and that it conforms to the rules for identifiers.
  12013.     */
  12014.     IF NOT EXISTS (SELECT * FROM syspublications WHERE name LIKE @publication)
  12015.         BEGIN
  12016.         IF @publication = '%'
  12017.                 RAISERROR (14008, 11, -1)
  12018.         ELSE
  12019.                 RAISERROR (20026, 11, -1, @publication)
  12020.         RETURN (1)
  12021.         END
  12022.  
  12023.     /*
  12024.     ** Parameter Check:  @article
  12025.     ** Check to make sure that the article exists, that it's not null,
  12026.     ** and that it conforms to the rules for identifiers.
  12027.     */
  12028.     IF NOT EXISTS (SELECT *
  12029.                      FROM sysarticles a,
  12030.                           syspublications b
  12031.                 WHERE a.name LIKE @article
  12032.                       AND a.pubid = b.pubid
  12033.                       AND b.name LIKE @publication)
  12034.  
  12035.         BEGIN
  12036.         IF @article = '%'
  12037.                 RAISERROR (14009, 11, -1, @publication)
  12038.         ELSE
  12039.                 RAISERROR (20027, 11, -1, @article)
  12040.         RETURN (1)
  12041.         END
  12042.  
  12043.     -- Don't check subscriber and dest_db for virtual subscriptions
  12044.     IF @subscriber IS NOT NULL
  12045.     BEGIN    
  12046.         /*
  12047.         ** Parameter Check:  @subscriber
  12048.         ** Check to make sure that the subscriber exists
  12049.         */
  12050.         if @subscriber <> '%' select @subscriber = UPPER(@subscriber)
  12051.         
  12052.         IF NOT EXISTS (SELECT *
  12053.                          FROM master..sysservers
  12054.                         WHERE ((@subscriber = N'%') OR (UPPER(srvname) = UPPER(@subscriber)))
  12055.                           AND (srvstatus & 4) <> 0)
  12056.  
  12057.             BEGIN
  12058.                 RAISERROR (14063, 11, -1)
  12059.                 RETURN (1)
  12060.             END
  12061.     END
  12062.  
  12063.     -- Wrong dest_db will be caught by the following query
  12064.  
  12065.     -- Check to make sure the subscription exists 
  12066.     IF  @publication <> '%' AND
  12067.         @subscriber <> '%' AND
  12068.  
  12069.         NOT EXISTS (SELECT *
  12070.           FROM syssubscriptions sub,
  12071.                sysarticles art,
  12072.                syspublications pub,
  12073.                master..sysservers ss
  12074.          WHERE pub.name LIKE @publication
  12075.            AND art.name LIKE @article
  12076.            AND ((UPPER(ss.srvname) = UPPER(@subscriber) 
  12077.            AND sub.srvid = ss.srvid)
  12078.            OR (@subscriber is NULL 
  12079.            AND pub.allow_anonymous = 1))
  12080.            AND sub.artid = art.artid
  12081.            AND art.pubid = pub.pubid
  12082.            AND sub.dest_db LIKE @destination_db)
  12083.     BEGIN
  12084.         RAISERROR (14055, 16, -1)
  12085.         RETURN (1)
  12086.     END
  12087.  
  12088.     EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  12089.                                        @distribdb = @distribdb OUTPUT
  12090.     IF @@ERROR <> 0
  12091.     BEGIN
  12092.         RAISERROR (14071, 16, -1)
  12093.         RETURN (1)
  12094.     END
  12095.  
  12096.     IF @retcode <> 0 OR @distribdb IS NULL OR @distributor IS NULL
  12097.     BEGIN
  12098.         RAISERROR (14071, 16, -1)
  12099.         RETURN (1)
  12100.     END
  12101.  
  12102.     DECLARE hCresyncsub CURSOR LOCAL FAST_FORWARD FOR
  12103.         -- non immediate_sync pubs
  12104.         SELECT pub.name,
  12105.                pub.immediate_sync,
  12106.                art.name,
  12107.                ss.srvname,
  12108.                sub.dest_db,
  12109.                sub.sync_type,
  12110.                sub.subscription_type,
  12111.                sub.login_name
  12112.           FROM syssubscriptions sub,
  12113.                sysarticles art,
  12114.                syspublications pub,
  12115.                master..sysservers ss
  12116.          WHERE pub.name LIKE @publication
  12117.            AND art.name LIKE @article
  12118.            AND ((@subscriber = N'%') OR (UPPER(ss.srvname) = UPPER(@subscriber)))
  12119.            AND sub.srvid = ss.srvid
  12120.            AND sub.artid = art.artid
  12121.            AND art.pubid = pub.pubid
  12122.            AND sub.dest_db LIKE @destination_db
  12123.            AND sub.status = @active
  12124.            AND pub.immediate_sync = 0
  12125.         
  12126.         UNION
  12127.         -- Immediate_sync pubs
  12128.         SELECT DISTINCT
  12129.                pub.name,
  12130.                immediate_sync,
  12131.                '%', -- art.name is '%' from immediate_sync pub
  12132.                ss.srvname,
  12133.                sub.dest_db,
  12134.                sub.sync_type,
  12135.                sub.subscription_type,
  12136.                sub.login_name
  12137.           FROM syssubscriptions sub,
  12138.                sysarticles art,
  12139.                syspublications pub,
  12140.                master..sysservers ss
  12141.          WHERE pub.name LIKE @publication -- Ignore @article
  12142.            AND ((@subscriber = N'%') OR (UPPER(ss.srvname) = UPPER(@subscriber)))
  12143.            AND sub.srvid = ss.srvid
  12144.            AND sub.artid = art.artid
  12145.            AND art.pubid = pub.pubid
  12146.            AND sub.dest_db LIKE @destination_db
  12147.            AND sub.status = @active
  12148.            AND pub.immediate_sync = 1
  12149.                  
  12150.         UNION
  12151.         -- For anonymous subscribers
  12152.         SELECT pub.name,
  12153.                immediate_sync,
  12154.                '%', -- art.name is '%' for immediate_sync pub
  12155.                CONVERT(sysname, NULL), -- subscriber name (null represent virtual)
  12156.                'virtual', -- destination_db for virtual subscription is hardcoded in 
  12157.                          -- sp_MSadd_subscription.
  12158.                @automatic, -- sub.sync_type is auto tor anonymous subscriber
  12159.                @push,      -- virtual subscription is push type,
  12160.                'sa'
  12161.           FROM syspublications pub
  12162.          WHERE pub.name LIKE @publication -- Ignore @article
  12163.            AND pub.allow_anonymous = 1 
  12164.            AND (@subscriber = '%' OR @subscriber IS NULL) 
  12165.                  
  12166.     FOR READ ONLY
  12167.  
  12168.     OPEN hCresyncsub 
  12169.  
  12170.     -- Note: Don't overwrite the variables used in the cursor.
  12171.     FETCH hCresyncsub INTO @pub, @immediate_sync, @art_name, @sub_name, 
  12172.         @dest_db, @sync_type, @subscription_type, @login_name
  12173.  
  12174.     WHILE (@@fetch_status <> -1)
  12175.     BEGIN
  12176.         -- Security Check
  12177.         IF  suser_sname(suser_sid()) <> @login_name AND is_srvrolemember('sysadmin') <> 1  
  12178.             AND is_member ('db_owner') <> 1
  12179.         BEGIN
  12180.                 RAISERROR (14126, 11, -1)
  12181.                 RETURN (1)
  12182.         END
  12183.  
  12184.          if @sync_type = @none
  12185.          begin
  12186.             raiserror(21071, 10, -1, @art_name, @sub_name, @dest_db, @pub)
  12187.             FETCH hCresyncsub INTO @pub, @immediate_sync, @art_name, @sub_name, 
  12188.                 @dest_db, @sync_type, @subscription_type, @login_name
  12189.             continue
  12190.          end
  12191.  
  12192.         -- If @article is not 'all' for immediate_sync publication
  12193.         -- report error and skip.
  12194.         IF @immediate_sync = 1 AND @article != '%'
  12195.         BEGIN
  12196.             RAISERROR (14122, 16, -1)
  12197.             FETCH hCresyncsub INTO @pub, @immediate_sync, @art_name, @sub_name, 
  12198.                 @dest_db, @sync_type, @subscription_type, @login_name
  12199.             CONTINUE
  12200.         END
  12201.  
  12202.         begin tran
  12203.         save TRAN sp_reinitsubscription
  12204.  
  12205.         -- Reset subscription status to subscribed and activate it later.
  12206.         -- This is to reset its snapshot transaction ts to the new one.
  12207.         -- We don't need to do it for anonymous subscriber since its snapshot
  12208.         -- transaction ts will be updated automatically by the snapshot agent.
  12209.         IF @sub_name IS NOT NULL
  12210.         BEGIN
  12211.             EXEC @retcode = dbo.sp_changesubstatus
  12212.                 @publication = @pub,
  12213.                 @article = @art_name,
  12214.                 @subscriber = @sub_name,
  12215.                 @destination_db = @dest_db,
  12216.                 @status = 'subscribed'
  12217.             IF @@ERROR <> 0 OR @retcode <> 0
  12218.             BEGIN
  12219.                 CLOSE hCresyncsub
  12220.                 DEALLOCATE hCresyncsub
  12221.                 RAISERROR (14070, 16, -1)
  12222.                 GOTO UNDO
  12223.             END
  12224.         END
  12225.  
  12226.         -- Reset the subscription guid at the distributor for immediate_sync publication.
  12227.          -- Reset subscription creation datetime used by retention cleanup.
  12228.         SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSreset_subscription'
  12229.         EXEC @retcode = @distproc 
  12230.             @publisher = @@SERVERNAME, 
  12231.             @publisher_db = @dbname, 
  12232.             @publication = @pub,
  12233.             @subscriber = @sub_name, 
  12234.             @subscriber_db = @dest_db,
  12235.             @subscription_type = @subscription_type
  12236.  
  12237.         IF @@ERROR <> 0 OR @retcode <> 0
  12238.         BEGIN
  12239.             CLOSE hCresyncsub
  12240.             DEALLOCATE hCresyncsub
  12241.             GOTO UNDO
  12242.         END
  12243.  
  12244.         -- Activate the subscription again if the publication is immediate_sync or
  12245.         -- the subscription is no_sync type.
  12246.         -- Otherwise, the snapshot agent will activate the subscription
  12247.         IF (@immediate_sync = 1 AND @subscriber IS NOT NULL)
  12248.         BEGIN
  12249.             -- Set subscription status back to active again.
  12250.             EXEC @retcode = dbo.sp_changesubstatus
  12251.                 @publication = @pub,
  12252.                 @article = @art_name,
  12253.                 @subscriber = @sub_name,
  12254.                 @destination_db = @dest_db,
  12255.                 @status = 'active'
  12256.             IF @@ERROR <> 0 OR @retcode <> 0
  12257.             BEGIN
  12258.                 CLOSE hCresyncsub
  12259.                 DEALLOCATE hCresyncsub
  12260.                 RAISERROR (14070, 16, -1)
  12261.                 GOTO UNDO
  12262.             END
  12263.         END
  12264.     
  12265.         COMMIT TRAN 
  12266.  
  12267.         FETCH hCresyncsub INTO @pub, @immediate_sync, @art_name, @sub_name, 
  12268.             @dest_db, @sync_type, @subscription_type, @login_name
  12269.     END
  12270.  
  12271.     CLOSE hCresyncsub
  12272.     DEALLOCATE hCresyncsub
  12273.  
  12274.     RETURN(0)
  12275.  
  12276. UNDO:
  12277.     IF @@TRANCOUNT > 0
  12278.     begin
  12279.         ROLLBACK TRAN sp_reinitsubscription
  12280.         COMMIT TRAN
  12281.     end
  12282.     return 1
  12283. go
  12284.  
  12285. EXEC dbo.sp_MS_marksystemobject sp_reinitsubscription
  12286. GO
  12287.  
  12288. dump tran master with no_log
  12289. GO
  12290.  
  12291. --------------------------------------------------------------------
  12292. --------------------------------------------------------------------
  12293.  
  12294. print ''
  12295. print 'Creating procedure sp_getarticlepkcolbitmap'
  12296. go
  12297.  
  12298. create procedure sp_getarticlepkcolbitmap @tabid int, @colbitmap binary(32) output
  12299. as
  12300. declare @pkindid int
  12301. declare @indkey int
  12302. declare @colid int
  12303. declare @word tinyint
  12304. declare @mval    int
  12305. declare @mask    binary(2)
  12306. declare @wordval binary(2)
  12307. declare @objname nvarchar(265)
  12308.  
  12309. select @colbitmap = 0x00
  12310. select @pkindid = indid from sysindexes where id = @tabid and status & 2048 <> 0
  12311. select @indkey = 1
  12312. select @objname = QUOTENAME(user_name(OBJECTPROPERTY(@tabid, 'OwnerId'))) + N'.' + QUOTENAME(object_name( @tabid )) 
  12313.  
  12314. while @indkey <= 16 and index_col( @objname, @pkindid, @indkey ) is not null
  12315. begin
  12316.     select @colid = colid from syscolumns where id = @tabid 
  12317.            and name = index_col( @objname, @pkindid, @indkey )
  12318.     select @word = convert(tinyint, 16 - floor((@colid-1)/16))
  12319.  
  12320.     select @mval = power(2, (@colid-1) % 16 )
  12321.     select @mask = convert( binary(2), substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) )                                 
  12322.  
  12323.     select @wordval = convert( binary(2), substring( convert( nchar(16), @colbitmap ), @word, 1 ) )
  12324.     select @wordval = convert( binary(2), convert( smallint, @wordval) | convert( smallint, @mask) )
  12325.  
  12326.     select @colbitmap = convert(binary(32), STUFF( convert(nchar(16),@colbitmap), @word, 1, convert( nchar(1),@wordval))) 
  12327.       
  12328.     select @indkey = @indkey + 1
  12329. end
  12330. go
  12331.  
  12332. EXEC dbo.sp_MS_marksystemobject sp_getarticlepkcolbitmap
  12333. GO
  12334.  
  12335. --------------------------------------------------------------------
  12336. --------------------------------------------------------------------
  12337.  
  12338. print ''
  12339. print 'Creating procedure sp_gettypestring'
  12340. go
  12341.  
  12342. create procedure sp_gettypestring @tabid int, @colid int, @typestring nvarchar(255) output
  12343. as
  12344. declare @coltypename sysname
  12345. declare @coltype  tinyint
  12346. declare @colvar   bit
  12347. declare @collen   smallint
  12348. declare @colprec  tinyint
  12349. declare @colscale tinyint
  12350.  
  12351. select @coltypename = st.name, @coltype = st.xtype, @colvar = st.variable, 
  12352.        @collen = sc.length, @colprec = sc.xprec, @colscale = sc.xscale
  12353. from systypes st, syscolumns sc 
  12354. where sc.id = @tabid
  12355. and sc.colid = @colid
  12356. and st.xtype = sc.xtype
  12357. and st.xtype = st.xusertype
  12358.  
  12359. select @typestring = @coltypename
  12360.  
  12361. if @coltypename in (N'char', N'varchar', N'binary', N'varbinary')
  12362. begin
  12363.     select @typestring = @typestring + N'(' + convert(nvarchar,@collen) + N')'
  12364. end
  12365. else if @coltypename in (N'nchar', N'nvarchar' )
  12366. begin
  12367.     select @typestring = @typestring + N'(' + convert(nvarchar,@collen/2) + N')'
  12368. end
  12369. else if @coltype = 108 or @coltype = 106
  12370. begin
  12371.     select @typestring = @typestring + N'(' + convert(nvarchar,@colprec) + N',' + convert(nvarchar,@colscale) + N')'
  12372. end
  12373. else if @coltype = 189
  12374. begin
  12375.     select @typestring = N'binary(8)'
  12376. end
  12377.     
  12378. go
  12379.  
  12380. EXEC dbo.sp_MS_marksystemobject sp_gettypestring
  12381. GO
  12382.  
  12383. --------------------------------------------------------------------
  12384. --------------------------------------------------------------------
  12385.  
  12386. print ''
  12387. print 'Creating procedure sp_isarticlecolbitset'
  12388. go
  12389.  
  12390. create procedure sp_isarticlecolbitset @colid int, @colbitmap binary(32)
  12391. as
  12392. declare @word tinyint
  12393. declare @mval int
  12394. declare @mask  smallint
  12395.  
  12396. select @word = convert(tinyint, 16 - floor((@colid-1)/16))
  12397. select @mval = power(2, (@colid-1) % 16 )
  12398. select @mask = convert( smallint, convert( binary(2), substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) ) )
  12399.  
  12400.  
  12401. if convert( binary(2), substring( convert( nchar(16),@colbitmap), @word, 1 ) ) & @mask = @mask 
  12402. begin   
  12403.    return 1
  12404. end
  12405. else
  12406. begin
  12407.    return 0
  12408. end
  12409.  
  12410. go
  12411.  
  12412. EXEC dbo.sp_MS_marksystemobject sp_isarticlecolbitset
  12413. GO
  12414.  
  12415. --------------------------------------------------------------------
  12416. --------------------------------------------------------------------
  12417.  
  12418. print ''
  12419. print 'sp_scriptpkwhereclause'
  12420. go
  12421.  
  12422. create procedure sp_scriptpkwhereclause @src_objid int, @src_cols int, @pkcolumns binary(32)
  12423. as
  12424. declare @this_col int
  12425. declare @art_col int
  12426. declare @spacer nvarchar(10)
  12427. declare @isset int
  12428. declare @cmd nvarchar(4000)
  12429.  
  12430. -- create WHERE clause
  12431.  
  12432. select @this_col = 1
  12433. select @art_col = 1
  12434. select @spacer = N' '
  12435. select @cmd = N'where'
  12436.  
  12437. while @this_col <= @src_cols 
  12438. begin
  12439.     exec @isset = dbo.sp_isarticlecolbitset @this_col, @pkcolumns
  12440.     if @isset != 0 and EXISTS (select name from syscolumns where id=@src_objid and @this_col=colid and iscomputed<>1)
  12441.     begin
  12442.         select @cmd = @cmd + @spacer + QUOTENAME(col_name( @src_objid, @this_col)) + N' = @pkc' + convert( nvarchar, @art_col ) 
  12443.         select @art_col = @art_col + 1
  12444.         select @spacer = N' and '
  12445.  
  12446.         if len( @cmd ) > 3000
  12447.         begin
  12448.             insert into #proctext(procedure_text) values( @cmd )
  12449.             select @cmd = N''
  12450.         end
  12451.     end
  12452.     select @this_col = @this_col + 1
  12453. end
  12454.  
  12455. insert into #proctext(procedure_text) values( @cmd )
  12456.  
  12457. go
  12458.  
  12459. EXEC dbo.sp_MS_marksystemobject sp_scriptpkwhereclause
  12460. GO
  12461.  
  12462. --------------------------------------------------------------------
  12463. --------------------------------------------------------------------
  12464.  
  12465. print ''
  12466. print 'Create procedure sp_scriptupdateparams'
  12467. go
  12468.  
  12469. create procedure sp_scriptupdateparams @src_objid int, @src_cols int, @artcolumns binary(32), @pkcolumns binary(32)
  12470. as
  12471. declare @this_col int
  12472. declare @art_col int
  12473. declare @spacer nvarchar(10)
  12474. declare @isset int
  12475. declare @cmd nvarchar(4000)
  12476. declare @typestring nvarchar(255)
  12477.  
  12478. -- add colval parameters
  12479.  
  12480. select @this_col = 1
  12481. select @art_col = 1
  12482. select @spacer = N' '
  12483. select @cmd = ''
  12484.  
  12485. while @this_col <= @src_cols 
  12486. begin
  12487.    exec @isset = dbo.sp_isarticlecolbitset @this_col, @artcolumns
  12488.    if @isset != 0 and EXISTS (select name from syscolumns where id=@src_objid and @this_col=colid and iscomputed<>1)
  12489.    begin
  12490.         exec dbo.sp_gettypestring @src_objid, @this_col, @typestring OUTPUT
  12491.         select @cmd = @cmd + @spacer + N'@c' + convert( nvarchar, @art_col ) + N' ' + @typestring 
  12492.         select @art_col = @art_col + 1
  12493.         select @spacer = N','
  12494.  
  12495.         if len( @cmd ) > 3000
  12496.         begin
  12497.         insert into #proctext(procedure_text) values( @cmd )
  12498.             select @cmd = N''
  12499.         end
  12500.    end
  12501.    select @this_col = @this_col + 1
  12502. end
  12503.  
  12504. -- add pkval parameters
  12505.  
  12506. select @this_col = 1
  12507. select @art_col = 1
  12508.  
  12509. while @this_col <= @src_cols 
  12510. begin
  12511.    exec @isset = dbo.sp_isarticlecolbitset @this_col, @pkcolumns
  12512.    if @isset != 0 and EXISTS (select name from syscolumns where id=@src_objid and @this_col=colid and iscomputed<>1)
  12513.    begin
  12514.         exec dbo.sp_gettypestring @src_objid, @this_col, @typestring OUTPUT
  12515.         select @cmd = @cmd + @spacer + N'@pkc' + convert( nvarchar, @art_col ) + N' ' + @typestring 
  12516.         select @art_col = @art_col + 1
  12517.         select @spacer = N','
  12518.  
  12519.         if len( @cmd ) > 3000
  12520.         begin
  12521.         insert into #proctext(procedure_text) values( @cmd )
  12522.             select @cmd = N''
  12523.         end
  12524.    end
  12525.    select @this_col = @this_col + 1
  12526. end
  12527.  
  12528. insert into #proctext(procedure_text) values ( @cmd )
  12529.  
  12530. go
  12531.  
  12532. EXEC dbo.sp_MS_marksystemobject sp_scriptupdateparams
  12533. GO
  12534.  
  12535. --------------------------------------------------------------------
  12536. --------------------------------------------------------------------
  12537.  
  12538. print ''
  12539. print 'Creating procedure sp_scriptinsproc'
  12540. go
  12541.  
  12542. create procedure sp_scriptinsproc @artid int
  12543. as
  12544. declare @cmd          nvarchar(4000)
  12545. declare @dest_owner   nvarchar(255)
  12546. declare @dest_tabname sysname
  12547. declare @src_objid    int
  12548. declare @columns      binary(32)
  12549. declare @ins_cmd      nvarchar(255)
  12550. declare @dest_proc    sysname
  12551. declare @src_cols     int
  12552. declare @this_col     int
  12553. declare @art_col      int
  12554. declare @isset        int
  12555.  
  12556. declare @typestring   nvarchar(255)
  12557. declare @spacer       nvarchar(1)
  12558.  
  12559. if not exists( select * from sysarticles where artid = @artid AND (type & 1) = 1 )
  12560. begin
  12561.     raiserror (14155, 16, 1 )
  12562.     return 1
  12563. end
  12564.  
  12565. -------- create temp table for command fragments
  12566.  
  12567. create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) NULL)
  12568.  
  12569. -------- get sysarticles information
  12570.  
  12571. select @dest_owner = dest_owner, @dest_tabname = dest_table, 
  12572.        @src_objid = objid, @columns = columns, @ins_cmd = ins_cmd
  12573. from sysarticles
  12574. where artid = @artid
  12575.  
  12576. if @dest_owner is not null
  12577. begin
  12578.     select @dest_owner = QUOTENAME( @dest_owner ) + N'.'
  12579. end
  12580. else
  12581. begin
  12582.     select @dest_owner = N''
  12583. end
  12584.  
  12585.  
  12586. -------- get dest proc name
  12587.  
  12588. if( 1 != charindex( N'CALL', upper(@ins_cmd) ) ) or @ins_cmd is null
  12589. begin
  12590.     raiserror (14156, 16, 1 )
  12591.     return 1
  12592. end
  12593.  
  12594. select @dest_proc = substring( @ins_cmd, 6, len( @ins_cmd ) - 4 )
  12595. select @cmd = N'create procedure ' + QUOTENAME(@dest_proc)
  12596.  
  12597. -------- construct parameter list
  12598.  
  12599. select @this_col = 1
  12600. select @art_col = 1
  12601. select @src_cols = max(colid) from syscolumns where id = @src_objid
  12602. select @spacer = N' '
  12603.  
  12604. while @this_col <= @src_cols 
  12605. begin
  12606.    exec @isset = dbo.sp_isarticlecolbitset @this_col, @columns
  12607.    if @isset != 0 and EXISTS (select name from syscolumns where id=@src_objid and @this_col=colid and iscomputed<>1)
  12608.    begin
  12609.         if len( @cmd ) > 3000
  12610.         begin
  12611.         insert into #proctext(procedure_text) values( @cmd )
  12612.             select @cmd = N''
  12613.         end
  12614.  
  12615.         exec dbo.sp_gettypestring @src_objid, @this_col, @typestring OUTPUT
  12616.         select @cmd = @cmd + @spacer + N'@c' + convert( nvarchar, @art_col ) + N' ' + @typestring 
  12617.         select @art_col = @art_col + 1
  12618.         select @spacer = N','
  12619.    end
  12620.    select @this_col = @this_col + 1
  12621. end
  12622.  
  12623.  
  12624. -- save off cmd fragment
  12625.  
  12626. insert into #proctext(procedure_text) values( @cmd )
  12627.  
  12628. insert into #proctext(procedure_text) values( N'as' )
  12629.  
  12630. ------- construct proc body
  12631.  
  12632. select @cmd = N'insert into ' + @dest_owner + QUOTENAME(@dest_tabname) + N' values ('
  12633. select @this_col = 1
  12634. select @art_col = 1
  12635. select @spacer = N' '
  12636.  
  12637. while @this_col <= @src_cols 
  12638. begin
  12639.     exec @isset = dbo.sp_isarticlecolbitset @this_col, @columns
  12640.     if @isset != 0 and EXISTS (select name from syscolumns where colid=@this_col and iscomputed<>1 and id = @src_objid)
  12641.     begin
  12642.         if len( @cmd ) > 3000
  12643.         begin
  12644.         insert into #proctext(procedure_text) values( @cmd )
  12645.             select @cmd = N''
  12646.         end
  12647.  
  12648.         select @cmd = @cmd + @spacer + N'@c' + convert( nvarchar, @art_col ) 
  12649.         select @art_col = @art_col + 1
  12650.         select @spacer = N','
  12651.     end
  12652.     select @this_col = @this_col + 1
  12653. end
  12654.  
  12655. -- finish up proc body
  12656.  
  12657. select @cmd = @cmd + N' )'
  12658.  
  12659. -- save off cmd fragement
  12660.  
  12661. insert into #proctext(procedure_text) values( @cmd )
  12662.  
  12663. -- send fragements to client
  12664.  
  12665. select procedure_text from #proctext order by c1 asc
  12666.  
  12667. go
  12668.  
  12669. EXEC dbo.sp_MS_marksystemobject sp_scriptinsproc
  12670. GO
  12671.  
  12672. ----------------------------------------------------
  12673. ---------------------------------------------------
  12674. print ''
  12675. print 'Creating procedure sp_scriptdelproc'
  12676. go
  12677.  
  12678. create procedure sp_scriptdelproc @artid int
  12679. as
  12680. declare @cmd          nvarchar(4000)
  12681. declare @dest_owner   nvarchar(255)
  12682. declare @dest_tabname sysname
  12683. declare @src_objid    int
  12684. declare @pkcolumns    binary(32)
  12685. declare @del_cmd      nvarchar(255)
  12686. declare @dest_proc    sysname
  12687. declare @src_cols     int
  12688. declare @this_col     int
  12689. declare @art_col      int
  12690. declare @isset        int
  12691.  
  12692. declare @typestring   nvarchar(255)
  12693. declare @spacer       nvarchar(10)
  12694.  
  12695. if not exists( select * from sysarticles where artid = @artid AND (type & 1) = 1 )
  12696. begin
  12697.     raiserror (14155, 16, 1 )
  12698.     return 1
  12699. end
  12700.  
  12701. -------- create temp table for command fragments
  12702.  
  12703. create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) NULL)
  12704.  
  12705. -- get sysarticles information
  12706.  
  12707. select @dest_owner = dest_owner, @dest_tabname = dest_table, 
  12708.        @src_objid = objid, @del_cmd = del_cmd
  12709. from sysarticles
  12710. where artid = @artid
  12711.  
  12712. if @dest_owner is not null
  12713. begin
  12714.     select @dest_owner = QUOTENAME( @dest_owner ) + N'.'
  12715. end
  12716. else
  12717. begin
  12718.     select @dest_owner = N''
  12719. end
  12720.  
  12721. -------- get dest proc name
  12722.  
  12723. if( 1 != charindex( N'CALL', upper(@del_cmd) ) ) or @del_cmd is null
  12724. begin
  12725.     raiserror (14156, 16, 1 )
  12726.     return 1
  12727. end
  12728.  
  12729. select @dest_proc = substring( @del_cmd, 6, len( @del_cmd ) - 4 )
  12730. select @cmd = N'create procedure ' + QUOTENAME(@dest_proc)
  12731.  
  12732. -------- construct parameter list
  12733.  
  12734. select @this_col = 1
  12735. select @art_col = 1
  12736. select @src_cols = max(colid) from syscolumns where id = @src_objid
  12737. select @spacer = N' '
  12738.  
  12739. exec dbo.sp_getarticlepkcolbitmap @src_objid, @pkcolumns output
  12740.  
  12741. while @this_col <= @src_cols 
  12742. begin
  12743.    exec @isset = dbo.sp_isarticlecolbitset @this_col, @pkcolumns
  12744.    if @isset != 0 and EXISTS (select name from syscolumns where id=@src_objid and @this_col=colid and iscomputed<>1)
  12745.    begin
  12746.         if len( @cmd ) > 3000
  12747.         begin
  12748.         insert into #proctext(procedure_text) values( @cmd )
  12749.             select @cmd = N''
  12750.         end
  12751.  
  12752.         exec dbo.sp_gettypestring @src_objid, @this_col, @typestring OUTPUT
  12753.         select @cmd = @cmd + @spacer + N'@pkc' + convert( nvarchar, @art_col ) + N' ' + @typestring 
  12754.         select @art_col = @art_col + 1
  12755.         select @spacer = N','
  12756.    end
  12757.    select @this_col = @this_col + 1
  12758. end
  12759.  
  12760.  
  12761. -- save off 
  12762.  
  12763. insert into #proctext(procedure_text) values( @cmd )
  12764. insert into #proctext(procedure_text) values( N'as' )
  12765.  
  12766. ------- construct proc body
  12767.  
  12768. insert into #proctext(procedure_text) values( N'delete ' + @dest_owner + QUOTENAME(@dest_tabname) ) 
  12769.  
  12770. exec dbo.sp_scriptpkwhereclause @src_objid, @src_cols, @pkcolumns
  12771.  
  12772. -- flush to client
  12773.  
  12774. select procedure_text from #proctext order by c1 asc
  12775.  
  12776.  
  12777. go
  12778.  
  12779. EXEC dbo.sp_MS_marksystemobject sp_scriptdelproc
  12780. GO
  12781.  
  12782. ----------------------------------------------------------------------------------------------
  12783. ----------------------------------------------------------------------------------------------
  12784. ----------------------------------------------------------------------------------------------
  12785.  
  12786. print ''
  12787. print 'Creating procedure sp_scriptupdproc'
  12788. go
  12789.  
  12790. create procedure sp_scriptupdproc @artid int
  12791. as
  12792. declare @cmd          nvarchar(4000)
  12793. declare @dest_owner   nvarchar(255)
  12794. declare @dest_tabname sysname
  12795. declare @src_objid    int
  12796. declare @artcolumns   binary(32)
  12797. declare @pkcolumns    binary(32)
  12798. declare @upd_cmd      nvarchar(255)
  12799. declare @dest_proc    sysname
  12800. declare @src_cols     int
  12801. declare @this_col     int
  12802. declare @art_col      int
  12803. declare @pkart_col    int
  12804. declare @isset        int
  12805.  
  12806. declare @typestring   nvarchar(255)
  12807. declare @spacer       nvarchar(10)
  12808.  
  12809. if not exists( select * from sysarticles where artid = @artid AND (type & 1) = 1 )
  12810. begin
  12811.     raiserror (14155, 16, 1 )
  12812.     return 1
  12813. end
  12814.  
  12815. -------- create temp table for command fragments
  12816.  
  12817. create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) NULL)
  12818.  
  12819. -------- get sysarticles information
  12820.  
  12821. select @dest_owner = dest_owner, @dest_tabname = dest_table, 
  12822.        @src_objid = objid, @artcolumns = columns, @upd_cmd = upd_cmd
  12823. from sysarticles
  12824. where artid = @artid
  12825.  
  12826. if @dest_owner is not null
  12827. begin
  12828.     select @dest_owner = QUOTENAME( @dest_owner ) + N'.'
  12829. end
  12830. else
  12831. begin
  12832.     select @dest_owner = N''
  12833. end
  12834.  
  12835. -------- get dest proc name
  12836.  
  12837. if( 1 != charindex( N'CALL', upper(@upd_cmd) ) ) or @upd_cmd is null
  12838. begin
  12839.     raiserror (14156, 16, 1 )
  12840.     return 1
  12841. end
  12842.  
  12843. select @dest_proc = substring( @upd_cmd, 6, len( @upd_cmd ) - 4 )
  12844.  
  12845. insert into #proctext( procedure_text ) values (  N'create procedure ' + QUOTENAME(@dest_proc) + N' ')
  12846.  
  12847. -------- construct parameter list
  12848.  
  12849. select @src_cols = max(colid) from syscolumns where id = @src_objid
  12850.  
  12851. exec dbo.sp_getarticlepkcolbitmap @src_objid, @pkcolumns output
  12852.  
  12853. exec dbo.sp_scriptupdateparams @src_objid, @src_cols, @artcolumns, @pkcolumns
  12854.  
  12855. insert into #proctext(procedure_text) values ( N'as' )
  12856.  
  12857. -------- now create the update statement
  12858.  
  12859. -- construct test to see if pk has changed 
  12860. -- only do this if the article has columns not included in the pk
  12861.  
  12862. if @artcolumns != @pkcolumns
  12863. begin
  12864.     select @cmd = N'if'
  12865.  
  12866.     select @this_col = 1
  12867.     select @art_col = 1
  12868.     select @pkart_col = 1
  12869.     select @spacer = ' '
  12870.  
  12871.     while @this_col <= @src_cols
  12872.     begin
  12873.         exec @isset = dbo.sp_isarticlecolbitset @this_col, @artcolumns
  12874.         if @isset != 0 and EXISTS (select name from syscolumns where id=@src_objid and @this_col=colid and iscomputed<>1)
  12875.         begin
  12876.             exec @isset = dbo.sp_isarticlecolbitset @this_col, @pkcolumns
  12877.             if @isset != 0
  12878.             begin
  12879.                 select @cmd = @cmd + @spacer + N'@c'+convert( nvarchar, @art_col ) + N' = @pkc' + convert( nvarchar, @pkart_col ) 
  12880.                 select @spacer = N' and '
  12881.                 select @pkart_col = @pkart_col + 1
  12882.                 if len( @cmd ) > 3000
  12883.                 begin
  12884.                 insert into #proctext(procedure_text) values( @cmd )
  12885.                     select @cmd = N''
  12886.                 end
  12887.             end
  12888.             select @art_col = @art_col + 1
  12889.         end
  12890.         select @this_col = @this_col + 1
  12891.     end
  12892.  
  12893.     insert into #proctext(procedure_text) values( @cmd )
  12894.  
  12895.     -- construct update if pk hasn't changed
  12896.  
  12897.     select @cmd = N'update ' + @dest_owner + QUOTENAME(@dest_tabname) + N' set'
  12898.  
  12899.     -- create SET clause
  12900.  
  12901.     select @this_col = 1
  12902.     select @art_col = 1
  12903.     select @spacer = N' '
  12904.  
  12905.     while @this_col <= @src_cols
  12906.     begin
  12907.         exec @isset = dbo.sp_isarticlecolbitset @this_col, @artcolumns
  12908.         if @isset != 0  and EXISTS (select name from syscolumns where id=@src_objid and @this_col=colid and iscomputed<>1)
  12909.         begin
  12910.             exec @isset = dbo.sp_isarticlecolbitset @this_col, @pkcolumns
  12911.             if @isset = 0
  12912.             begin
  12913.                 select @cmd = @cmd + @spacer + QUOTENAME(col_name( @src_objid, @this_col)) + N' = @c' + convert( nvarchar, @art_col ) 
  12914.                 select @spacer = N','
  12915.  
  12916.                 if len( @cmd ) > 3000
  12917.                 begin
  12918.                     insert into #proctext(procedure_text) values( @cmd )
  12919.                     select @cmd = N''
  12920.                 end
  12921.             end
  12922.             select @art_col = @art_col + 1
  12923.         end
  12924.         select @this_col = @this_col + 1
  12925.     end
  12926.  
  12927.     insert into #proctext(procedure_text) values( @cmd )
  12928.  
  12929.     exec dbo.sp_scriptpkwhereclause @src_objid, @src_cols, @pkcolumns
  12930.  
  12931.     insert into #proctext(procedure_text) values( N'else' )
  12932.  
  12933. end -- end if artcols != pkcols
  12934.  
  12935. -- construct update if pk has changed
  12936.  
  12937. select @cmd = N'update ' + @dest_owner + QUOTENAME(@dest_tabname) + N' set'
  12938.  
  12939. -- create SET clause
  12940.  
  12941. select @this_col = 1
  12942. select @art_col = 1
  12943. select @spacer = N' '
  12944.  
  12945. while @this_col <= @src_cols
  12946. begin
  12947.     exec @isset = dbo.sp_isarticlecolbitset @this_col, @artcolumns
  12948.     if @isset != 0 and EXISTS (select name from syscolumns where id=@src_objid and @this_col=colid and iscomputed<>1)
  12949.     begin
  12950.         select @cmd = @cmd + @spacer + QUOTENAME(col_name( @src_objid, @this_col)) + N' = @c' + convert( nvarchar, @art_col ) 
  12951.         select @art_col = @art_col + 1
  12952.         select @spacer = N','
  12953.  
  12954.         if len( @cmd ) > 3000
  12955.         begin
  12956.         insert into #proctext(procedure_text) values( @cmd )
  12957.             select @cmd = N''
  12958.         end
  12959.     end
  12960.     select @this_col = @this_col + 1
  12961. end
  12962.  
  12963. insert into #proctext(procedure_text) values( @cmd )
  12964.  
  12965. exec dbo.sp_scriptpkwhereclause @src_objid, @src_cols, @pkcolumns
  12966.  
  12967. -- flush to client
  12968.  
  12969. select procedure_text from #proctext order by c1 asc
  12970.  
  12971. go
  12972.  
  12973. EXEC dbo.sp_MS_marksystemobject sp_scriptupdproc
  12974. GO
  12975.  
  12976. --------------------------------------------------------------------------
  12977. --------------------------------------------------------------------------
  12978.  
  12979. print ''
  12980. print 'Creating procedure sp_scriptmappedupdproc'
  12981. go
  12982.  
  12983. create procedure sp_scriptmappedupdproc @artid int
  12984. as
  12985. declare @cmd          nvarchar(4000)
  12986. declare @dest_owner   nvarchar(255)
  12987. declare @dest_tabname sysname
  12988. declare @src_objid    int
  12989. declare @artcolumns   binary(32)
  12990. declare @pkcolumns    binary(32)
  12991. declare @upd_cmd      nvarchar(255)
  12992. declare @dest_proc    sysname
  12993. declare @src_cols     int
  12994. declare @art_cols     int
  12995. declare @this_col     int
  12996. declare @art_col      int
  12997. declare @pkart_col    int
  12998. declare @isset        int
  12999. declare @bytestr      nvarchar(10)
  13000. declare @bitstr       nvarchar(10)
  13001. declare @typestring   nvarchar(255)
  13002. declare @spacer       nvarchar(10)
  13003. declare @exists_else  bit
  13004.  
  13005. select @exists_else     = 0
  13006.  
  13007. if not exists( select * from sysarticles where artid = @artid AND (type & 1) = 1 )
  13008. begin
  13009.     raiserror (14155, 16, 1 )
  13010.     return 1
  13011. end
  13012.  
  13013. -------- create temp table for command fragments
  13014.  
  13015. create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) )
  13016.  
  13017. -------- get sysarticles information
  13018.  
  13019. select @dest_owner = dest_owner, @dest_tabname = dest_table, 
  13020.        @src_objid = objid, @artcolumns = columns, @upd_cmd = upd_cmd
  13021. from sysarticles
  13022. where artid = @artid
  13023.  
  13024. if @dest_owner is not null
  13025. begin
  13026.     select @dest_owner = QUOTENAME( @dest_owner ) + N'.'
  13027. end
  13028. else
  13029. begin
  13030.     select @dest_owner = N''
  13031. end
  13032.  
  13033. -------- get dest proc name
  13034.  
  13035. if( 1 != charindex( N'MCALL', upper(@upd_cmd) ) ) or @upd_cmd is null
  13036. begin
  13037.     raiserror (14156, 16, 1 )
  13038.     return 1
  13039. end
  13040.  
  13041. select @dest_proc = substring( @upd_cmd, 7, len( @upd_cmd ) - 5 )
  13042. insert into #proctext( procedure_text ) values ( N'create procedure ' + QUOTENAME(@dest_proc) + N' ' )
  13043.   
  13044.  
  13045. -------- construct parameter list
  13046.  
  13047. select @src_cols = max(colid) from syscolumns where id = @src_objid
  13048.  
  13049. exec dbo.sp_getarticlepkcolbitmap @src_objid, @pkcolumns output
  13050.  
  13051. exec dbo.sp_scriptupdateparams @src_objid, @src_cols, @artcolumns, @pkcolumns
  13052.  
  13053. ----- add changed data bitmap
  13054.  
  13055. select @this_col = 1
  13056. select @art_col = 1
  13057.  
  13058. while @this_col <= @src_cols
  13059. begin
  13060.    exec @isset = dbo.sp_isarticlecolbitset @this_col, @artcolumns
  13061.    if @isset != 0 and EXISTS (select name from syscolumns where colid=@this_col and iscomputed<>1 and id = @src_objid)
  13062.    begin
  13063.         select @art_col = @art_col + 1
  13064.    end
  13065.    select @this_col = @this_col + 1
  13066. end
  13067.  
  13068. -- Note that bitmap size is based on number of article columns
  13069. -- (computed by loop above) not source table columns
  13070.  
  13071. select @cmd = N',@bitmap binary(' + convert(nvarchar,1+(@art_col-1) / 8) + N')'
  13072.  
  13073. insert into #proctext(procedure_text) values( @cmd )
  13074. insert into #proctext(procedure_text) values( N'as' )
  13075.  
  13076.  
  13077. -- construct IF statement
  13078. -- do this only if the article contains columns not included in the pk
  13079.  
  13080. if @artcolumns != @pkcolumns
  13081. begin
  13082.     select @this_col = 1
  13083.     select @art_col = 1
  13084.     select @spacer = N' '
  13085.  
  13086.     select @cmd = N'if'
  13087.  
  13088.     while @this_col <= @src_cols
  13089.     begin
  13090.         exec @isset = dbo.sp_isarticlecolbitset @this_col, @artcolumns
  13091.         if @isset != 0 and EXISTS (select name from syscolumns where id=@src_objid and @this_col=colid and iscomputed<>1)
  13092.         begin 
  13093.             exec @isset = dbo.sp_isarticlecolbitset @this_col, @pkcolumns
  13094.             if @isset != 0
  13095.             begin
  13096.                 select @bytestr = convert( nvarchar, 1 + (@art_col-1) / 8 )
  13097.                 select @bitstr =  convert( nvarchar, power(2, (@art_col-1) % 8 ) )
  13098.  
  13099.                 select @cmd = @cmd + @spacer + N'substring(@bitmap,' + @bytestr + N',1) & ' + @bitstr +  
  13100.                          N' = ' + @bitstr 
  13101.                 
  13102.                 select @spacer = N' or '
  13103.  
  13104.                 if len( @cmd ) > 3000
  13105.                 begin
  13106.                     insert into #proctext(procedure_text) values( @cmd )
  13107.                     select @cmd = N''
  13108.                 end
  13109.             end
  13110.             select @art_col = @art_col + 1
  13111.         end
  13112.         select @this_col = @this_col + 1
  13113.     end
  13114.  
  13115.     insert into #proctext(procedure_text) values( @cmd )
  13116.  
  13117. end  -- if artcolumns != pkcolumns
  13118.  
  13119. -- construct update statement including PK columns
  13120.  
  13121. insert into #proctext(procedure_text) values( N'update ' + @dest_owner + QUOTENAME(@dest_tabname) + N' set' )
  13122.  
  13123. -- create SET clause consisting of CASE statements
  13124.  
  13125. select @this_col = 1
  13126. select @art_col = 1
  13127. select @spacer = N''
  13128.  
  13129. while @this_col <= @src_cols
  13130. begin
  13131.     exec @isset = dbo.sp_isarticlecolbitset @this_col, @artcolumns
  13132.     if @isset != 0  and EXISTS (select name from syscolumns where colid=@this_col and iscomputed<>1 and id = @src_objid)
  13133.     begin
  13134.         select @bytestr = convert( nvarchar, 1 + (@art_col-1) / 8 )
  13135.         select @bitstr =  convert( nvarchar, power(2, (@art_col-1) % 8 ) )
  13136.  
  13137.         insert into #proctext(procedure_text) values (
  13138.              @spacer + QUOTENAME(col_name( @src_objid, @this_col)) + N' = case substring(@bitmap,' + @bytestr + N',1) & ' + @bitstr +  
  13139.              N' when ' + @bitstr + N' then ' + N'@c'+ convert( nvarchar, @art_col ) + 
  13140.              N' else ' + QUOTENAME(col_name( @src_objid, @this_col)) + N' end' )
  13141.  
  13142.         select @spacer = ',' 
  13143.  
  13144.         select @art_col = @art_col + 1
  13145.     end
  13146.     select @this_col = @this_col + 1
  13147. end
  13148.  
  13149. -- create where clause
  13150.  
  13151. exec dbo.sp_scriptpkwhereclause @src_objid, @src_cols, @pkcolumns
  13152.  
  13153.  
  13154. -- construct UPDATE that does not set PK cols
  13155. -- only do this if the article contains columns that are not included
  13156. -- in the pk
  13157.  
  13158. if @artcolumns != @pkcolumns
  13159. begin
  13160.  
  13161.     -- create SET clause consisting of CASE statements
  13162.  
  13163.     select @this_col = 1
  13164.     select @art_col = 1
  13165.     select @spacer = N''
  13166.  
  13167.     while @this_col <= @src_cols
  13168.     begin
  13169.         exec @isset = dbo.sp_isarticlecolbitset @this_col, @artcolumns
  13170.         if @isset != 0  and EXISTS (select name from syscolumns where colid=@this_col and iscomputed<>1 and id = @src_objid)
  13171.         begin
  13172.             exec @isset = dbo.sp_isarticlecolbitset @this_col, @pkcolumns 
  13173.             if @isset = 0 
  13174.             begin
  13175.                 if (@exists_else = 0)
  13176.                 begin
  13177.                     insert into #proctext(procedure_text) values( N'else' )
  13178.                     insert into #proctext(procedure_text) values( N'update ' + @dest_owner + QUOTENAME(@dest_tabname) + N' set' )
  13179.                     select @exists_else = 1
  13180.                 end
  13181.                 select @bytestr = convert( nvarchar, 1 + (@art_col-1) / 8 )
  13182.                 select @bitstr =  convert( nvarchar, power(2, (@art_col-1) % 8 ) )
  13183.  
  13184.                 insert into #proctext(procedure_text) values (
  13185.                      @spacer + QUOTENAME(col_name( @src_objid, @this_col)) + N' = case substring(@bitmap,' + @bytestr + N',1) & ' + @bitstr +  
  13186.                      N' when ' + @bitstr + N' then ' + N'@c'+ convert( nvarchar, @art_col ) + 
  13187.                      N' else ' + QUOTENAME(col_name( @src_objid, @this_col)) + N' end' )
  13188.  
  13189.                 select @spacer = ',' 
  13190.             end
  13191.             select @art_col = @art_col + 1
  13192.         end
  13193.         select @this_col = @this_col + 1
  13194.     end
  13195.  
  13196.     if @exists_else=1
  13197.         exec dbo.sp_scriptpkwhereclause @src_objid, @src_cols, @pkcolumns
  13198. end
  13199.  
  13200. select procedure_text from #proctext order by c1 asc
  13201.  
  13202. go
  13203.  
  13204. EXEC dbo.sp_MS_marksystemobject sp_scriptmappedupdproc
  13205. GO
  13206.  
  13207. --------------------------------------------------------------------------
  13208. --------------------------------------------------------------------------
  13209.  
  13210. print ''
  13211. print 'Creating procedure sp_fetchshowcmdsinput'
  13212. go
  13213.  
  13214. create procedure sp_fetchshowcmdsinput @numcmds int
  13215. as
  13216. create table #rcmds( article_id int NOT NULL, partial_command int NOT NULL, command varbinary(1024) NULL, 
  13217. xactid binary(10) NOT NULL, xact_seqno binary(10) NOT NULL, publication_id int NOT NULL, 
  13218. command_id int NOT NULL, command_type int NOT NULL, originator_srvname nvarchar(128) NULL, 
  13219. originator_db nvarchar(128) NULL)
  13220. insert into #rcmds exec dbo.sp_replcmds @numcmds
  13221. select convert( varbinary(16), xact_seqno ), 0, 0, article_id, command_type, partial_command, command from #rcmds order by xact_seqno, article_id, command_id asc
  13222. drop table #rcmds
  13223. go
  13224.  
  13225. EXEC dbo.sp_MS_marksystemobject sp_fetchshowcmdsinput
  13226. GO
  13227.  
  13228. --------------------------------------------------------------------------
  13229. --------------------------------------------------------------------------
  13230.  
  13231. print ''
  13232. print 'Creating procedure sp_replshowcmds'
  13233. go
  13234.  
  13235. create procedure sp_replshowcmds @maxtrans int = 1
  13236. as
  13237. declare @query nvarchar(1024)
  13238. declare @dbname sysname
  13239. select @dbname = db_name()
  13240.  
  13241. select @query = 'execute dbo.sp_fetchshowcmdsinput ' + convert( nvarchar, @maxtrans )
  13242. execute master..xp_printstatements @query, @dbname
  13243. go
  13244.  
  13245. EXEC dbo.sp_MS_marksystemobject sp_replshowcmds
  13246. GO
  13247.  
  13248. print ''
  13249. print 'Creating procedure sp_publication_validation'
  13250. go
  13251.  
  13252. create procedure sp_publication_validation
  13253. @publication sysname,
  13254. @rowcount_only bit = 1,
  13255. @full_or_fast tinyint = 2,  -- full (value 0) does COUNT(*) 
  13256.                             -- fast (value 1) uses sysindexes.rows if table (not view); 
  13257.                             -- conditional fast (VALUE 2) , first tries fast method, but
  13258.                             -- reverts to full if fast method shows differences.
  13259. @shutdown_agent bit = 0     -- Set for last article in publication, which will signal subscriber synchronization agent to shutdown
  13260.                             -- immediately after successful validation
  13261. as
  13262.  
  13263. set nocount on
  13264.  
  13265. declare @publication_id int
  13266. declare @article sysname
  13267. declare @article2 sysname
  13268. declare @retcode int
  13269. declare @publish_bit int
  13270.  
  13271. -- Security Check
  13272. exec @retcode = dbo.sp_MSreplcheck_publish
  13273. if @@ERROR <> 0 or @retcode <> 0
  13274.     return(1)
  13275.     
  13276. set @publish_bit = 1
  13277.  
  13278. -- Check if the database is published for transactional
  13279. if not exists (select * from master..sysdatabases where name = db_name() and (category & @publish_bit) = @publish_bit)
  13280. begin
  13281.     raiserror(20026, 16, -1, @publication)
  13282.     return 1
  13283. end
  13284.  
  13285. -- Get Publication Information
  13286. select @publication_id = pubid from syspublications where name = @publication
  13287. if @publication_id is null
  13288. begin
  13289.     raiserror(20026, 16, -1, @publication)
  13290.     return 1
  13291. end
  13292.  
  13293. declare hC CURSOR LOCAL FAST_FORWARD for select name from sysarticles where pubid = @publication_id and
  13294. (status & 1) <> 0 -- active articles only
  13295. open hC
  13296. fetch hC into @article
  13297. while (@@fetch_status <> -1)
  13298. begin
  13299.     set @article2 = @article
  13300.  
  13301.     -- Look ahead to next article
  13302.     fetch hC into @article
  13303.  
  13304.     -- If we are at the last article, pass the @shutdown_agent value
  13305.     if (@@fetch_status = -1) 
  13306.     begin
  13307.         exec @retcode = dbo.sp_article_validation @publication, @article2, @rowcount_only = @rowcount_only,
  13308.             @full_or_fast = @full_or_fast, @shutdown_agent = @shutdown_agent
  13309.  
  13310.     end
  13311.     else
  13312.         exec @retcode = dbo.sp_article_validation @publication, @article2, @rowcount_only = @rowcount_only,
  13313.             @full_or_fast = @full_or_fast
  13314.     
  13315.     if @retcode <> 0 or @@error <> 0
  13316.     begin
  13317.         close hC
  13318.         deallocate hC
  13319.         return 1
  13320.     end
  13321. end
  13322. close hC
  13323. deallocate hC
  13324. go
  13325.  
  13326. EXEC dbo.sp_MS_marksystemobject sp_publication_validation
  13327. GO
  13328.  
  13329. print ''
  13330. print 'Creating procedure sp_article_validation'
  13331. go
  13332. create procedure sp_article_validation
  13333. @publication sysname,
  13334. @article sysname,
  13335. -- The following are values passed to the sp_table_validation call at the subscriber.
  13336. @rowcount_only bit = 1,                     
  13337. @full_or_fast tinyint = 2,  -- full (value 0) does COUNT(*) 
  13338.                             -- fast (value 1) uses sysindexes.rows if table (not view); 
  13339.                             -- conditional fast (VALUE 2) , first tries fast method, but
  13340.                             -- reverts to full if fast method shows differences.
  13341. @shutdown_agent bit = 0     -- If 1 will raise error 20578, which will signal subscriber synchronization agent to shutdown
  13342.                             -- immediately after successful validation
  13343. as
  13344.  
  13345. declare @publication_guid uniqueidentifier
  13346. declare @publication_id int
  13347. declare @article_guid uniqueidentifier
  13348. declare @article_id int
  13349. declare @source_name sysname
  13350. declare @destination_table sysname
  13351. declare @destination_owner sysname
  13352. declare @columns varbinary(32) 
  13353. declare @command varchar (4096)
  13354. declare @retcode int
  13355. declare @actual_rowcount int
  13356. declare @actual_checksum numeric
  13357. declare @status int
  13358. declare @active int
  13359. declare @vertical_partition bit
  13360. declare @publish_bit int
  13361. declare @table_name sysname                    -- base table name var to passed to sp_table_validation
  13362.     
  13363. set nocount on
  13364.  
  13365. -- Security Check
  13366. exec @retcode = dbo.sp_MSreplcheck_publish
  13367. if @@ERROR <> 0 or @retcode <> 0
  13368.     return(1)
  13369.  
  13370. set @active = 1
  13371. set @publish_bit = 1
  13372.  
  13373. -- Check if the database is published for transactional
  13374. if not exists (select * from master..sysdatabases where name = db_name() and (category & @publish_bit) = @publish_bit)
  13375. begin
  13376.     raiserror(20026, 16, -1, @publication)
  13377.     return 1
  13378. end
  13379.  
  13380. -- Get Publication Information
  13381. select @publication_id = pubid from syspublications where name = @publication
  13382. if @publication_id is null
  13383. begin
  13384.     raiserror(20026, 16, -1, @publication)
  13385.     return 1
  13386. end
  13387.  
  13388. -- Get Article Information
  13389. select @article_id = artid, @source_name = OBJECT_NAME(sync_objid),  
  13390.     @destination_table = dest_table, @destination_owner = dest_owner, 
  13391.     @status = status, @table_name = OBJECT_NAME(objid),
  13392.     @columns = columns from sysarticles where name = @article and pubid=@publication_id
  13393. if @article_id is null
  13394. begin
  13395.     raiserror(20027, 16, -1, @article)
  13396.     return 1
  13397. end
  13398.  
  13399. -- Make sure article status is 'active' 
  13400. if (@status & @active) <> @active
  13401. begin
  13402.     -- Article is not active
  13403.     raiserror(20523, 16, -1, @article)
  13404.     return 1
  13405. end
  13406.  
  13407. -- Check if table has vertical partition
  13408. if exists (select * from sysarticles a, syscolumns b
  13409.     where (CONVERT(bit, convert(binary(2), SUBSTRING(convert(nvarchar,a.columns), CONVERT(tinyint, 16 - FLOOR((colid-1)/16)), 1)) & POWER(2, ((colid-1)%16))) = 0
  13410.            OR CONVERT(bit, convert(binary(2), SUBSTRING(convert( nvarchar,a.columns), CONVERT(tinyint, 16 - FLOOR((colid-1)/16)), 1)) & POWER(2, ((colid-1)%16))) IS NULL)
  13411.            AND a.objid = b.id
  13412.            AND a.name = @article
  13413.            AND a.pubid = @publication_id)
  13414. begin
  13415.     set @vertical_partition = 1
  13416.  
  13417.     -- partitions only support row count validation, override specified value
  13418.     set @rowcount_only = 1
  13419. end
  13420. else
  13421.     set @vertical_partition = 0
  13422.  
  13423. begin tran -- The table validation and posting to the log MUST happen with a transaction
  13424.  
  13425. -- Get publisher's rowcount and/or checksum for the article
  13426. if @rowcount_only = 1
  13427. begin
  13428.     exec @retcode = dbo.sp_table_validation @table = @source_name, @expected_rowcount = @actual_rowcount OUTPUT,
  13429.         @rowcount_only = 1, @full_or_fast = 0, @table_name = @table_name   -- always do full count at publisher
  13430.     if @retcode <> 0 or @@error <> 0 
  13431.     begin
  13432.         commit tran
  13433.         return 1
  13434.     end
  13435. end
  13436. else  -- get checksum
  13437. begin
  13438.     exec @retcode = dbo.sp_table_validation @table = @source_name, @expected_rowcount = @actual_rowcount OUTPUT,
  13439.         @expected_checksum = @actual_checksum OUTPUT, @rowcount_only = 0, 
  13440.         @full_or_fast = 0, @table_name = @table_name   -- always do full count at publisher
  13441.     if @retcode <> 0 or @@error <> 0 
  13442.     begin
  13443.         commit tran
  13444.         return 1
  13445.     end
  13446. end
  13447.  
  13448. -- Post sp_table_validation on behalf of the article and send to subscribers
  13449. if @rowcount_only = 1
  13450. begin
  13451.     select @command = 'exec dbo.sp_table_validation @table = ''' + @destination_table + ''', @expected_rowcount = ' +
  13452.         convert(varchar(10), @actual_rowcount) + ', @rowcount_only = 1' +
  13453.         ', @full_or_fast = ' + convert(varchar(10), @full_or_fast) +
  13454.         ', @shutdown_agent = ' + convert(varchar(10), @shutdown_agent)
  13455. end
  13456. else
  13457. begin
  13458.     select @command = 'exec dbo.sp_table_validation @table = ''' + @destination_table + ''', @expected_rowcount = ' +
  13459.         convert(varchar(10), @actual_rowcount) + ', @expected_checksum = ' + 
  13460.         convert(varchar(100), @actual_checksum) + ', @rowcount_only = 0' + 
  13461.         ', @full_or_fast = ' + convert(varchar(10), @full_or_fast) +
  13462.         ', @shutdown_agent = ' + convert(varchar(10), @shutdown_agent)
  13463. end 
  13464.  
  13465. -- Add owner param if destination owner is not NULL
  13466. if (@destination_owner IS NOT NULL)
  13467. begin
  13468.     select @command = @command +
  13469.     ', @owner = ''' + @destination_owner + ''''
  13470. end
  13471.  
  13472. -- DEBUG select @command
  13473.  
  13474. exec @retcode = dbo.sp_replpostcmd 
  13475.     0,              -- partial flag
  13476.     @publication_id, 
  13477.     @article_id, 
  13478.     35,             -- SQL Server Only command type
  13479.     @command
  13480. if @retcode <> 0 or @@error <> 0
  13481. begin
  13482.     commit tran
  13483.     return 1
  13484. end
  13485.  
  13486. commit tran
  13487.  
  13488. go
  13489.  
  13490. EXEC dbo.sp_MS_marksystemobject sp_article_validation
  13491. GO
  13492.  
  13493. print ''
  13494. print 'Creating procedure sp_MSdrop_6x_replication_agent'
  13495. go
  13496. create procedure sp_MSdrop_6x_replication_agent
  13497. @job_id UNIQUEIDENTIFIER,
  13498. @category_id int
  13499. as
  13500.     declare @distbit int
  13501.     declare @db_name sysname
  13502.     declare @cmd varchar(4000)
  13503.  
  13504.     select @distbit = 16
  13505.  
  13506.     declare hCdatabase CURSOR LOCAL FAST_FORWARD FOR
  13507.         select name from master.dbo.sysdatabases 
  13508.             where
  13509.             category & @distbit <> 0 
  13510.         for read only
  13511.  
  13512.     open hCdatabase
  13513.     fetch next from hCdatabase into @db_name
  13514.     while (@@fetch_status <> -1)
  13515.     begin
  13516.  
  13517.         if @category_id = 13
  13518.         begin
  13519.             select @cmd = 'delete from ' + @db_name + '.dbo.MSlogreader_agents where job_id = convert (uniqueidentifier, ''' +
  13520.                 convert (varchar(100), @job_id) + ''')'
  13521.             exec (@cmd)
  13522.         end
  13523.         else if @category_id = 15   
  13524.         begin
  13525.             select @cmd = @db_name + '.dbo.sp_MSdrop_6x_publication'
  13526.             exec @cmd @job_id = @job_id
  13527.         end
  13528.         else
  13529.             return 0
  13530.  
  13531.         if @@ERROR <> 0
  13532.             return 1
  13533.         
  13534.         fetch next from hCdatabase into @db_name
  13535.     end
  13536.     close hCdatabase
  13537.     deallocate hCdatabase
  13538. go
  13539.  
  13540. EXEC dbo.sp_MS_marksystemobject sp_MSdrop_6x_replication_agent
  13541. GO
  13542.  
  13543. ---------------------------------------------------------------------------
  13544. ---------------------------------------------------------------------------
  13545.  
  13546. grant execute on dbo.sp_enumfullsubscribers to public
  13547. go
  13548. grant execute on dbo.sp_addpublication to public
  13549. go
  13550. grant execute on dbo.sp_changepublication to public
  13551. go
  13552. grant execute on dbo.sp_changesubscription to public
  13553. go
  13554. grant execute on dbo.sp_articlecolumn to public
  13555. go
  13556. grant execute on dbo.sp_helparticle to public
  13557. go
  13558. grant execute on dbo.sp_helparticlecolumns to public
  13559. go
  13560. grant execute on dbo.sp_helppublication to public
  13561. go
  13562. grant execute on dbo.sp_publication_validation to public
  13563. go
  13564. grant execute on dbo.sp_article_validation to public
  13565. go
  13566. grant execute on dbo.sp_helpsubscription to public
  13567. go
  13568. grant execute on dbo.sp_articlefilter to public
  13569. go
  13570. grant execute on dbo.sp_articleview to public
  13571. go
  13572. grant execute on dbo.sp_addarticle to public
  13573. go
  13574. grant execute on dbo.sp_changesubstatus to public
  13575. go
  13576. grant execute on dbo.sp_addsubscription to public
  13577. go
  13578. grant execute on dbo.sp_changearticle to public
  13579. go
  13580. grant execute on dbo.sp_droparticle to public
  13581. go
  13582. grant execute on dbo.sp_droppublication to public
  13583. go
  13584. grant execute on dbo.sp_dropsubscription to public
  13585. go
  13586. grant execute on dbo.sp_subscribe to public
  13587. go
  13588. grant execute on dbo.sp_unsubscribe to public
  13589. go
  13590. grant execute on dbo.sp_refreshsubscriptions to public
  13591. go
  13592. grant execute on dbo.sp_reinitsubscription to public
  13593. go
  13594. -- SyncTran
  13595. grant exec on dbo.sp_articlesynctranprocs to public
  13596. go
  13597. -- custom proc gen.
  13598. grant exec on dbo.sp_getarticlepkcolbitmap to public
  13599. go
  13600. grant exec on dbo.sp_gettypestring to public
  13601. go
  13602. grant exec on dbo.sp_isarticlecolbitset to public
  13603. go
  13604. grant exec on dbo.sp_scriptpkwhereclause to public
  13605. go
  13606. grant exec on dbo.sp_scriptupdateparams to public
  13607. go
  13608. grant exec on dbo.sp_scriptinsproc to public
  13609. go
  13610. grant exec on dbo.sp_scriptdelproc to public
  13611. go
  13612. grant exec on dbo.sp_scriptupdproc to public
  13613. go
  13614. grant exec on dbo.sp_scriptmappedupdproc to public
  13615. go
  13616. grant exec on dbo.sp_script_synctran_commands to public
  13617. go
  13618. grant exec on dbo.sp_MSget_synctran_commands to public
  13619. go
  13620. grant exec on dbo.sp_MSactivate_auto_sub to public
  13621. go
  13622. grant execute on dbo.sp_MSscript_insert_statement to public
  13623. grant execute on dbo.sp_MSscript_update_statement to public
  13624. grant execute on dbo.sp_MSscript_delete_statement to public
  13625. grant execute on dbo.sp_MSscript_beginproc  to public
  13626. grant execute on dbo.sp_MSscript_security  to public
  13627. grant execute on dbo.sp_MSscript_validate_subscription  to public
  13628. grant execute on dbo.sp_MSscript_endproc  to public
  13629. grant execute on dbo.sp_MSscript_sync_ins_proc  to public
  13630. grant execute on dbo.sp_MSscript_sync_upd_proc  to public
  13631. grant execute on dbo.sp_MSscript_sync_del_proc  to public
  13632. grant execute on dbo.sp_MSmark_proc_norepl to public
  13633. grant execute on dbo.sp_MSvalidate_subscription to public
  13634. go
  13635.  
  13636. dump tran master with no_log
  13637. go
  13638. sp_configure 'allow updates',0
  13639. go
  13640. reconfigure with override
  13641. go
  13642.  
  13643. print ''
  13644. print 'Checking objects created by repltran.sql.'
  13645. go
  13646.  
  13647. --obsolete   exec dbo.sp_check_objects 'repl'
  13648. -- exec dbo.sp_MS_upd_sysobj_category 2  --set sysobjects.category | 2 based on crdate.
  13649. go
  13650.  
  13651.  
  13652. print ''
  13653. print 'repltran.sql completed successfully.'
  13654. go
  13655.  
  13656. dump tran master with no_log
  13657. go
  13658. checkpoint
  13659. go
  13660. -- - -----
  13661.