home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD 4 / SuperCD_4.iso / server / servpak1.65 / instrepl.sql < prev    next >
Text File  |  1996-07-29  |  241KB  |  8,452 lines

  1.  
  2. /*
  3. ** instrepl.sql            1996/02/13 22:03
  4. **
  5. **
  6. ** Copyright Microsoft, Inc. 1994, 1995, 1996
  7. ** All Rights Reserved.
  8. ** Use, duplication, or disclosure by the United States Government
  9. ** is subject to restrictions as set forth in subdivision (c) (1) (ii)
  10. ** of the Rights in Technical Data and Computer Software clause
  11. ** at CFR 252.227-7013. Microsoft, Inc. One Microsoft Way, Redmond WA
  12. ** 98052.
  13. */
  14.  
  15. go
  16. use master
  17. go
  18. dump tran master with no_log
  19. go
  20. set nocount on
  21. go
  22.  
  23. exec sp_configure 'update',1
  24. go
  25. reconfigure with override
  26. go
  27.  
  28. exec sp_MS_upd_sysobj_category 1 --Capture time for use below.
  29.  
  30. go
  31.  
  32. if exists (select * from sysobjects
  33.         where sysstat & 0xf = 4
  34.             and name = 'sp_addarticle')
  35.     drop procedure sp_addarticle
  36. go
  37.  
  38. if exists (select * from sysobjects
  39.     where sysstat & 0xf = 4
  40.             and name = 'sp_articlecolumn')
  41.     drop procedure sp_articlecolumn
  42. go
  43.  
  44. if exists (select * from sysobjects
  45.         where sysstat & 0xf = 4
  46.             and name = 'sp_articlefilter')
  47.     drop procedure sp_articlefilter
  48. go
  49.  
  50. if exists (select * from sysobjects
  51.     where sysstat & 0xf = 4
  52.             and name = 'sp_articletextcol')
  53.     drop procedure sp_articletextcol
  54. go
  55.  
  56. if exists (select * from sysobjects
  57.     where sysstat & 0xf = 4
  58.             and name = 'sp_textcolstatus')
  59.     drop procedure sp_textcolstatus
  60. go
  61.  
  62. if exists (select * from sysobjects
  63.         where sysstat & 0xf = 4
  64.             and name = 'sp_articleview')
  65.     drop procedure sp_articleview
  66. go
  67.  
  68. if exists (select * from sysobjects
  69.         where sysstat & 0xf = 4
  70.             and name = 'sp_addpublication')
  71.     drop procedure sp_addpublication
  72. go
  73.  
  74. if exists (select * from sysobjects
  75.         where sysstat & 0xf = 4
  76.             and name = 'sp_addpublisher')
  77.     drop procedure sp_addpublisher
  78. go
  79.  
  80. if exists (select * from sysobjects
  81.         where sysstat & 0xf = 4
  82.             and name = 'sp_addsubscriber')
  83.     drop procedure sp_addsubscriber
  84. go
  85.  
  86. if exists (select * from sysobjects
  87.         where sysstat & 0xf = 4
  88.             and name = 'sp_addsubscription')
  89.     drop procedure sp_addsubscription
  90. go
  91.  
  92.  
  93. IF EXISTS (SELECT * FROM sysobjects
  94.         WHERE sysstat & 0xf = 4
  95.             AND name = 'sp_changearticle')
  96.     DROP PROCEDURE sp_changearticle
  97. go
  98.  
  99.  
  100. IF EXISTS (SELECT * FROM sysobjects
  101.         WHERE sysstat & 0xf = 4
  102.             AND name = 'sp_changepublication')
  103.     DROP PROCEDURE sp_changepublication
  104. go
  105.  
  106. if exists (select * from sysobjects
  107.         where sysstat & 0xf = 4
  108.             and name = 'sp_changesubscriber')
  109.     drop procedure sp_changesubscriber
  110. go
  111.  
  112. IF EXISTS (SELECT * FROM sysobjects
  113.         WHERE sysstat & 0xf = 4
  114.             AND name = 'sp_changesubscription')
  115.     DROP PROCEDURE sp_changesubscription
  116. go
  117.  
  118. IF EXISTS (SELECT * FROM sysobjects
  119.         WHERE sysstat & 0xf = 4
  120.             AND name = 'sp_create_distribution_tables')
  121.     DROP PROCEDURE sp_create_distribution_tables
  122. go
  123.  
  124. dump tran master with no_log
  125. go
  126.  
  127. if exists (select * from sysobjects
  128.         where sysstat & 0xf = 4
  129.             and name = 'sp_hcchangesubstatus1')
  130.     drop procedure sp_hcchangesubstatus1
  131. go
  132.  
  133. if exists (select * from sysobjects
  134.         where sysstat & 0xf = 4
  135.             and name = 'sp_hcchangesubstatus2')
  136.     drop procedure sp_hcchangesubstatus2
  137. go
  138.  
  139. if exists (select * from sysobjects
  140.         where sysstat & 0xf = 4
  141.             and name = 'sp_changesubstatus')
  142.     drop procedure sp_changesubstatus
  143. go
  144.  
  145. if exists (select * from sysobjects
  146.         where sysstat & 0xf = 4
  147.             and name = 'sp_distcounters')
  148.     drop procedure sp_distcounters
  149. go
  150.  
  151. if exists (select * from sysobjects
  152.         where sysstat & 0xf = 4
  153.             and name = 'sp_droparticle')
  154.     drop procedure sp_droparticle
  155. go
  156.  
  157. if exists (select * from sysobjects
  158.         where sysstat & 0xf = 4
  159.             and name = 'sp_droppublication')
  160.     drop procedure sp_droppublication
  161. go
  162.  
  163. if exists (select * from sysobjects
  164.         where sysstat & 0xf = 4
  165.             and name = 'sp_droppublisher')
  166.     drop procedure sp_droppublisher
  167. go
  168.  
  169. if exists (select * from sysobjects
  170.         where sysstat & 0xf = 4
  171.             and name = 'sp_dropsubscriber')
  172.     drop procedure sp_dropsubscriber
  173. go
  174.  
  175. if exists (select * from sysobjects
  176.         where sysstat & 0xf = 4
  177.             and name = 'sp_dropsubscription')
  178.     drop procedure sp_dropsubscription
  179. go
  180.  
  181. if exists (select * from sysobjects
  182.         where sysstat & 0xf = 4
  183.             and name = 'sp_dsninfo')
  184.     drop procedure sp_dsninfo
  185. go
  186.  
  187. if exists (select * from sysobjects
  188.         where sysstat & 0xf = 4
  189.             and name = 'sp_enumdsn')
  190.     drop procedure sp_enumdsn
  191. go
  192.  
  193. if exists (select * from sysobjects
  194.         where sysstat & 0xf = 4
  195.             and name = 'sp_enumfullsubscribers')
  196.     drop procedure sp_enumfullsubscribers
  197. go
  198.  
  199. if exists (select * from sysobjects
  200.         where sysstat & 0xf = 4
  201.             and name = 'sp_helparticle')
  202.     drop procedure sp_helparticle
  203. go
  204.  
  205. if exists (select * from sysobjects
  206.         where sysstat & 0xf = 4
  207.             and name = 'sp_helparticlecolumns')
  208.     drop procedure sp_helparticlecolumns
  209. go
  210.  
  211. if exists (select * from sysobjects
  212.         where sysstat & 0xf = 4
  213.             and name = 'sp_helpdistributor')
  214.     drop procedure sp_helpdistributor
  215. go
  216.  
  217. if exists (select * from sysobjects
  218.         where sysstat & 0xf = 4
  219.             and name = 'sp_helppublication')
  220.     drop procedure sp_helppublication
  221. go
  222.  
  223. if exists (select * from sysobjects
  224.         where sysstat & 0xf = 4
  225.             and name = 'sp_helppublicationsync')
  226.     drop procedure sp_helppublicationsync
  227. go
  228.  
  229. if exists (select * from sysobjects
  230.         where sysstat & 0xf = 4
  231.             and name = 'sp_helpreplicationdb')
  232.     drop procedure sp_helpreplicationdb
  233. go
  234.  
  235. if exists (select * from sysobjects
  236.         where sysstat & 0xf = 4
  237.             and name = 'sp_helpsubscriberinfo')
  238.     drop procedure sp_helpsubscriberinfo
  239. go
  240.  
  241. if exists (select * from sysobjects
  242.         where sysstat & 0xf = 4
  243.             and name = 'sp_helpsubscription')
  244.     drop procedure sp_helpsubscription
  245. go
  246.  
  247. if exists (select * from sysobjects
  248.         where sysstat & 0xf = 4
  249.             and name = 'sp_publishdb')
  250.     drop procedure sp_publishdb
  251. go
  252.  
  253. if exists (select * from sysobjects
  254.         where sysstat & 0xf = 4
  255.             and name = 'sp_replica')
  256.     drop procedure sp_replica
  257. go
  258.  
  259. if exists (select * from sysobjects
  260.         where sysstat & 0xf = 4
  261.             and name = 'sp_replsync')
  262.     drop procedure sp_replsync
  263. go
  264.  
  265. if exists (select * from sysobjects
  266.         where sysstat & 0xf = 4
  267.             and name = 'sp_subscribe')
  268.     drop procedure sp_subscribe
  269. go
  270.  
  271. if exists (select * from sysobjects
  272.         where sysstat & 0xf = 4
  273.             and name = 'sp_MSuninstall_publishing')
  274.     drop procedure sp_MSuninstall_publishing
  275. go
  276.  
  277. if exists (select * from sysobjects
  278.         where sysstat & 0xf = 4
  279.             and name = 'sp_unsubscribe')
  280.     drop procedure sp_unsubscribe
  281. go
  282.  
  283. if exists (select * from sysobjects
  284.         where sysstat & 0xf = 4
  285.             and name = 'xp_dsninfo')
  286.     exec sp_dropextendedproc 'xp_dsninfo'
  287. go
  288.  
  289. if exists (select * from sysobjects
  290.         where sysstat & 0xf = 4
  291.             and name = 'xp_enumdsn')
  292.     exec sp_dropextendedproc 'xp_enumdsn'
  293. go
  294.  
  295. CREATE PROCEDURE sp_helpdistributor (
  296.     @distributor varchar(30)  = '%' OUTPUT, /* The distribution server name */
  297.     @distribdb   varchar(30)  = '%' OUTPUT, /* The distribution database script */
  298.         @directory   varchar(255) = '%' OUTPUT, /* The working directory */
  299.         @account     varchar(255) = '%' OUTPUT, /* The Windows NT user account */
  300.     @local varchar(5) = NULL        /* Get local server values */
  301.         ) AS
  302.  
  303.     /*
  304.     ** Declarations.
  305.     */
  306.     DECLARE @loc_distributor varchar(30)
  307.     DECLARE @loc_distribdb varchar(30)
  308.     DECLARE @loc_directory varchar(255)
  309.     DECLARE @loc_account varchar(255)
  310.     DECLARE @proc varchar(255)
  311.  
  312.     SET NOCOUNT ON
  313.  
  314.     /*
  315.     ** If @local flag, get current server's distribution values.
  316.     */
  317.     IF LOWER (@local) = 'local'
  318.     SELECT @loc_distributor = @@SERVERNAME
  319.     /*
  320.     ** Get the distribution server
  321.     */
  322.     ELSE
  323.         BEGIN
  324.         SELECT @loc_distributor = srvname
  325.           FROM master..sysservers
  326.          WHERE srvstatus & 8 <> 0
  327.     
  328.          IF @@error <> 0
  329.         BEGIN
  330.             RAISERROR (14071, 16, -1)
  331.             RETURN (1)
  332.         END
  333.     END
  334.  
  335.     /*
  336.     ** If remote distribuiton, execute sp_helpdistributor on distribution
  337.     ** server.
  338.     */
  339.     IF @loc_distributor <> @@SERVERNAME
  340.        BEGIN
  341.         SELECT @proc = RTRIM(@loc_distributor) + '.master..sp_helpdistributor '
  342.             EXECUTE @proc
  343.         @loc_distributor OUTPUT,
  344.         @loc_distribdb OUTPUT,
  345.         @loc_directory OUTPUT,
  346.         @loc_account OUTPUT,
  347.         @local = 'local'
  348.         IF @@ERROR <> 0
  349.            RETURN (1)
  350.  
  351.             GOTO DONE
  352.        END
  353.  
  354.     /*
  355.     ** Fetch the distribution database name.
  356.     */
  357.     IF (@distributor = '%' AND @distribdb = '%' AND @directory = '%'
  358.     AND @account = '%') OR @distribdb IS NULL
  359.        BEGIN
  360.         SELECT @proc = 'master..xp_regread '
  361.         EXECUTE @proc 'HKEY_LOCAL_MACHINE',
  362.               'SOFTWARE\Microsoft\MSSQLServer\Replication',
  363.               'DistributionDB',
  364.             @param = @loc_distribdb OUTPUT
  365.     
  366.         IF @@ERROR <> 0 RETURN (1)
  367.     END    
  368.     /*
  369.     ** Fetch the distribution working directory.
  370.     */
  371.     IF (@distributor = '%' AND @distribdb = '%' AND @directory = '%'
  372.     AND @account = '%') OR @directory IS NULL
  373.        BEGIN
  374.         SELECT @proc = 'master..xp_regread '
  375.         EXECUTE @proc 'HKEY_LOCAL_MACHINE',
  376.               'SOFTWARE\Microsoft\MSSQLServer\Replication',
  377.               'WorkingDirectory',
  378.             @param = @loc_directory OUTPUT
  379.     
  380.         IF @@ERROR <> 0 RETURN (1)
  381.        END
  382.  
  383.     /*
  384.     ** Fetch the distribution account name.
  385.     */
  386.     IF (@distributor = '%' AND @distribdb = '%' AND @directory = '%'
  387.     AND @account = '%') OR @account IS NULL
  388.        BEGIN
  389.         SELECT @proc = 'master..xp_regread '
  390.         EXECUTE @proc 'HKEY_LOCAL_MACHINE',
  391.               'SYSTEM\CurrentControlSet\Services\SQLExecutive',
  392.               'ObjectName',
  393.             @param = @loc_account OUTPUT
  394.     
  395.         IF @@ERROR <> 0 RETURN (1)
  396.        END
  397.  
  398. DONE:
  399.  
  400.     /*
  401.     ** Return result set if no output parameters
  402.     */
  403.  
  404.     IF @distributor = '%' AND @distribdb = '%' AND @directory = '%'
  405.     AND @account = '%'
  406.  
  407.     SELECT 'distributor'           = @loc_distributor,
  408.                'distribution database' = @loc_distribdb,
  409.                'directory'             = @loc_directory,
  410.                'account'               = @loc_account
  411.  
  412.     /*
  413.     ** Return output parameters if requested.
  414.     */
  415.  
  416.     IF @distributor IS NULL
  417.         SELECT @distributor = @loc_distributor
  418.     IF @distribdb IS NULL
  419.         SELECT @distribdb = @loc_distribdb
  420.     IF @directory IS NULL
  421.         SELECT @directory = @loc_directory
  422.     IF @account IS NULL
  423.     SELECT @account = @loc_account
  424.  
  425.     RETURN (0)
  426. go
  427.  
  428. /*
  429. ** Create replication stored procedures.
  430. ** Part 2:  create all other stored procedures.
  431. */
  432.  
  433. print ''
  434. print 'Creating procedure sp_addpublication.'
  435. go
  436. CREATE PROCEDURE sp_addpublication (
  437.     @publication varchar(30),                /* publication name */
  438.     @taskid int,                   /* associated scheduler task */
  439.     @restricted varchar (10) = 'false',    /* publication security */
  440.     @sync_method varchar(13) = 'native',   /* (bcp) native, (bcp) character */
  441.     @repl_freq varchar(10) = 'continuous', /* continuous, snapshot */
  442.     @description varchar (255) = NULL,     /* publication description */
  443.     @status varchar(8) = 'inactive'        /* publication status; 0=inactive, 1=active */
  444.     ) AS
  445.  
  446.     SET NOCOUNT ON
  447.  
  448.     /*
  449.     ** Declarations.
  450.     */
  451.  
  452.     DECLARE @retcode    int         /* return code value for procedure execution */
  453.     DECLARE @rid bit                /* value for restricted column */
  454.     DECLARE @rfid tinyint           /* identifier for replication frequency */
  455.     DECLARE @publish_bit smallint   /* publication bit (flag) in sysobjects */
  456.     DECLARE @smid tinyint           /* identifier for sync method */
  457.     DECLARE @statid tinyint         /* status id based on @status */
  458.     DECLARE @distributor varchar(30)
  459.     DECLARE @distproc varchar (255)
  460.  
  461.  
  462.     SELECT @publish_bit = 32
  463.  
  464.     /*
  465.     ** Security Check
  466.     ** Only the System Administratr (SA) or the Database Owner (dbo) can
  467.     ** publish a table.
  468.     */
  469.  
  470.     IF suser_id() <> 1 AND user_id() <> 1
  471.         BEGIN
  472.             RAISERROR (15000, 14, -1)
  473.             RETURN (1)
  474.         END
  475.  
  476.     /*
  477.     ** Check to see if the database has been activated for publication.
  478.     */
  479.  
  480.     IF (SELECT category & 1
  481.           FROM master..sysdatabases
  482.          WHERE name = DB_NAME()) = 0
  483.  
  484.     BEGIN
  485.             RAISERROR (14013, 16, -1)
  486.         RETURN (1)
  487.     END
  488.  
  489.     /*
  490.     ** Parameter Check: @publication.
  491.     ** The @publication name must conform to the rules for identifiers,
  492.     ** and must not be the keyword 'all'.
  493.     */
  494.  
  495.     IF @publication IS NULL
  496.         BEGIN
  497.             RAISERROR (14043, 16, -1, 'The publication')
  498.             RETURN (1)
  499.         END
  500.  
  501.     EXECUTE @retcode = sp_validname @publication
  502.  
  503.     IF @@ERROR <> 0 OR @retcode <> 0
  504.     RETURN (1)
  505.  
  506.     IF LOWER (@publication) = 'all'
  507.         BEGIN
  508.             RAISERROR (14034, 16, -1)
  509.             RETURN (1)
  510.         END
  511.  
  512.     /*
  513.     ** Get distribution server information for remote RPC
  514.     ** task verification.
  515.     */
  516.     EXEC @retcode = sp_helpdistributor @distributor = @distributor OUTPUT
  517.     IF @@error <> 0 OR @retcode <> 0
  518.         BEGIN
  519.         RAISERROR (14071, 16, -1)
  520.             RETURN (1)
  521.     END
  522.  
  523.     /*
  524.     ** Parameter Check:  @taskid
  525.     ** The @taskid must exists in the systasks table.  The @taskid
  526.     ** must also be unique.
  527.     */
  528.     SELECT @distproc = RTRIM(@distributor) + '.msdb..sp_verifytaskid'
  529.     EXECUTE @retcode = @distproc @taskid = @taskid, @subsystem = 'Sync'
  530.     IF @@ERROR <> 0 or @retcode <> 0
  531.         BEGIN
  532.             RAISERROR (14002, 16, -1, @taskid)
  533.             RETURN (1)
  534.         END
  535.  
  536.     IF EXISTS (SELECT * FROM syspublications WHERE taskid = @taskid)
  537.         BEGIN
  538.             RAISERROR (14045, 16, -1)
  539.             RETURN (1)
  540.         END
  541.  
  542.     /*
  543.     ** Parameter Check: @sync_method
  544.     ** The synchronization method must be one of the following:
  545.     **
  546.     **      0  [bcp] native
  547.     **      1  [bcp] character
  548.     */
  549.  
  550.     SELECT @sync_method = LOWER(@sync_method)
  551.     IF @sync_method IS NULL OR @sync_method NOT IN ('native', 'character', 'bcp native', 'bcp character')
  552.         BEGIN
  553.             RAISERROR (14014, 16, -1)
  554.             RETURN (1)
  555.         END
  556.  
  557.     IF @sync_method IN ('character', 'bcp character')
  558.         SELECT @smid = 1
  559.     ELSE
  560.         SELECT @smid = 0
  561.  
  562.     /*
  563.     ** Parameter Check: @repl_freq.
  564.     ** Make sure that the replication frequency is one of the following:
  565.     **
  566.     **  id  frequency
  567.     **  ==  ==========
  568.     **   0  continuous
  569.     **   1  snapshot
  570.     */
  571.  
  572.     SELECT @repl_freq = LOWER(@repl_freq)
  573.     IF @repl_freq IS NULL OR @repl_freq NOT IN ('continuous', 'snapshot')
  574.         BEGIN
  575.             RAISERROR (14015, 16, -1)
  576.             RETURN (1)
  577.         END
  578.  
  579.     IF @repl_freq = 'snapshot' SELECT @rfid = 1
  580.     ELSE SELECT @rfid = 0
  581.  
  582.     /*
  583.     **  Check if the publication already exists.
  584.     */
  585.  
  586.     IF EXISTS (SELECT * FROM syspublications WHERE name = @publication)
  587.         BEGIN
  588.             RAISERROR (14016, 16, -1, @publication)
  589.             RETURN (1)
  590.         END
  591.  
  592.     /*
  593.     ** Parameter Check:  @restricted.
  594.     */
  595.  
  596.     IF (@restricted IS NULL) OR (LOWER(@restricted) NOT IN ('true', 'false'))
  597.         BEGIN
  598.             RAISERROR (14017, 16, -1)
  599.             RETURN (1)
  600.         END
  601.  
  602.     IF LOWER(@restricted) = 'true'
  603.         SELECT @rid = 1
  604.     ELSE
  605.         SELECT @rid = 0
  606.  
  607.     /*
  608.     ** Parameter Check:  @status.
  609.     ** The @status value can be:
  610.     **
  611.     **      statid  status
  612.     **      ======  ========
  613.     **           0  inactive
  614.     **           1  active
  615.     */
  616.  
  617.     IF @status IS NULL OR LOWER(@status) NOT IN ('inactive', 'active')
  618.         BEGIN
  619.             RAISERROR (14012, 16, -1)
  620.             RETURN (1)
  621.         END
  622.  
  623.     IF LOWER(@status) = 'active' SELECT @statid = 1
  624.     ELSE SELECT @statid = 0
  625.  
  626.     /*
  627.     **  Add publication to syspublications.
  628.     */
  629.  
  630.     INSERT syspublications(description, name, repl_freq,
  631.                            restricted, status, sync_method, taskid)
  632.     VALUES (@description, @publication, @rfid, @rid, @statid, @smid, @taskid)
  633.  
  634.     IF @@ERROR <> 0
  635.         BEGIN
  636.             RAISERROR (14018, 16, -1)
  637.             RETURN (1)
  638.         END
  639. go
  640.  
  641. print ''
  642. print 'Creating procedure sp_changepublication.'
  643. go
  644. CREATE PROCEDURE sp_changepublication (
  645.     @publication varchar(30) = NULL,        /* Publication name */
  646.     @property varchar(15) = NULL,           /* The property to change */
  647.     @value varchar(255) = NULL              /* The new property value */
  648.     ) AS
  649.  
  650.     SET NOCOUNT ON
  651.  
  652.     /*
  653.     ** Declarations.
  654.     */
  655.  
  656.     DECLARE @cmd varchar(255)
  657.     DECLARE @pubid int
  658.     DECLARE @replfreqid tinyint
  659.     DECLARE @restrictedid bit
  660.     DECLARE @retcode int
  661.     DECLARE @statusid tinyint
  662.     DECLARE @syncmethodid tinyint
  663.     DECLARE @taskid int
  664.     DECLARE @distributor varchar(30)
  665.     DECLARE @distproc varchar (255)
  666.     DECLARE @subscribed int
  667.     
  668.  
  669.     select @subscribed = 1
  670.  
  671.     /*
  672.     ** Security Check
  673.     ** Only the System Administrator (SA) or the Database Owner (dbo) can
  674.     ** perform this procedure.
  675.     */
  676.  
  677.     IF suser_id() <> 1 AND user_id() <> 1
  678.         BEGIN
  679.             RAISERROR (15000, 14, -1)
  680.             RETURN (1)
  681.         END
  682.  
  683.     /*
  684.     ** Check to see if the database has been activated for publication.
  685.     */
  686.  
  687.     IF (SELECT category & 1
  688.           FROM master..sysdatabases
  689.          WHERE name = DB_NAME()) = 0
  690.  
  691.     BEGIN
  692.             RAISERROR (14013, 16, -1)
  693.         RETURN (1)
  694.     END
  695.  
  696.     /*
  697.     ** Parameter Check:  @property.
  698.     ** If the @property parameter is NULL, print the options.
  699.     */
  700.  
  701.     IF @property IS NULL
  702.         BEGIN
  703.             CREATE TABLE #tab1 (properties varchar(30))
  704.             INSERT INTO #tab1 VALUES ('name')
  705.             INSERT INTO #tab1 VALUES ('description')
  706.             INSERT INTO #tab1 VALUES ('taskid')
  707.             INSERT INTO #tab1 VALUES ('sync_method')
  708.             INSERT INTO #tab1 VALUES ('status')
  709.             INSERT INTO #tab1 VALUES ('repl_freq')
  710.             INSERT INTO #tab1 VALUES ('restricted')
  711.             PRINT ''
  712.             SELECT * FROM #tab1
  713.             RETURN (0)
  714.         END
  715.  
  716.     /*
  717.     ** Parameter Check:  @publication.
  718.     ** Make sure that the publication exists.
  719.     */
  720.  
  721.     IF @publication IS NULL
  722.         BEGIN
  723.             RAISERROR (14043, 16, -1, 'The publication')
  724.             RETURN (1)
  725.         END
  726.  
  727.     EXECUTE @retcode = sp_validname @publication
  728.  
  729.     IF @@ERROR <> 0 OR @retcode <> 0
  730.     RETURN (1)
  731.  
  732.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  733.  
  734.     IF @pubid IS NULL
  735.         BEGIN
  736.             RAISERROR (15001, 11, -1, @publication)
  737.             RETURN (1)
  738.         END
  739.     ELSE
  740.  
  741.     /*
  742.     ** Parameter Check:  @property.
  743.     ** Check to make sure that @property is a valid property in
  744.     ** syspublications.
  745.     */
  746.  
  747.     IF LOWER(@property) NOT IN ('name', 'description', 'taskid', 'sync_method', 'status', 'repl_freq', 'restricted')
  748.         BEGIN
  749.             RAISERROR (14078, 16, -1)
  750.             RETURN (1)
  751.         END
  752.  
  753.     /*
  754.     ** Change the property.
  755.     */
  756.  
  757.     IF LOWER(@property) IN ('name', 'description')
  758.         BEGIN
  759.  
  760.             IF LOWER(@property) = 'name'
  761.                 BEGIN
  762.  
  763.                     IF @value IS NULL
  764.                         BEGIN
  765.                             RAISERROR (14043, 16, -1, 'The publication')
  766.                             RETURN (1)
  767.                         END
  768.  
  769.                     EXECUTE @retcode = sp_validname @value
  770.  
  771.                     IF @@ERROR <> 0 OR @retcode <> 0
  772.             RETURN (1)
  773.  
  774.                     IF EXISTS (SELECT * FROM syspublications WHERE name = @value)
  775.                         BEGIN
  776.                             RAISERROR (14016, 16, -1, @value)
  777.                             RETURN (1)
  778.                         END
  779.  
  780.                 END
  781.  
  782.             SELECT @cmd = ''
  783.             SELECT @cmd = @cmd + 'UPDATE syspublications '
  784.             SELECT @cmd = @cmd + '   SET ' + @property + ' = ''' + @value + ''''
  785.             SELECT @cmd = @cmd + ' WHERE pubid = ' + STR(@pubid)
  786.             EXECUTE (@cmd)
  787.             IF @@ERROR <> 0 RETURN (1)
  788.         END
  789.  
  790.     IF LOWER(@property) = 'taskid'
  791.        BEGIN
  792.         SELECT @taskid = CONVERT(int, @value)
  793.             /*
  794.             ** Get distribution server information for remote RPC
  795.             ** task verification.
  796.             */
  797.             EXEC @retcode = sp_helpdistributor @distributor = @distributor OUTPUT
  798.             IF @@error <> 0 OR @retcode <> 0
  799.                BEGIN
  800.               RAISERROR (14071, 16, -1)
  801.                   RETURN (1)
  802.            END
  803.  
  804.         /*
  805.         ** The @taskid must exists in the systasks table.  The @taskid
  806.         ** must also be unique.
  807.         */
  808.         SELECT @distproc = RTRIM(@distributor) + '.msdb..sp_verifytaskid'
  809.         EXECUTE @retcode = @distproc @taskid = @taskid,
  810.            @subsystem = 'Sync'
  811.             IF @@ERROR <> 0 or @retcode <> 0
  812.         BEGIN
  813.             RAISERROR (14002, 16, -1, @taskid)
  814.             RETURN (1)
  815.             END
  816.  
  817.         IF EXISTS (SELECT * FROM syspublications WHERE taskid = @taskid)
  818.         BEGIN
  819.             RAISERROR (14045, 16, -1)
  820.             RETURN (1)
  821.         END
  822.  
  823.         UPDATE syspublications SET taskid = @taskid
  824.             WHERE pubid = @pubid
  825.  
  826.             IF @@ERROR <> 0 RETURN (1)
  827.        END
  828.  
  829.     IF LOWER(@property) = 'sync_method'
  830.         BEGIN
  831.  
  832.             /*
  833.             ** Check for a valid synchronization method.
  834.             */
  835.  
  836.             IF LOWER(@value) NOT IN ('native', 'character', 'bcp native', 'bcp character')
  837.                 BEGIN
  838.                     RAISERROR (14026, 16, -1)
  839.                     RETURN (1)
  840.                 END
  841.  
  842.             /*
  843.             ** Determine the integer value for the sync_method.
  844.             */
  845.  
  846.             IF LOWER(@value) IN ('native', 'bcp native')
  847.                 SELECT @syncmethodid = 0
  848.             ELSE IF LOWER(@value) IN ('character', 'bcp character')
  849.                 SELECT @syncmethodid = 1
  850.  
  851.             /*
  852.             ** Update the publication with the new synchronization method.
  853.             */
  854.  
  855.             UPDATE syspublications
  856.                SET sync_method = @syncmethodid
  857.              WHERE pubid = @pubid
  858.  
  859.             IF @@ERROR <> 0 RETURN (1)
  860.  
  861.         END
  862.  
  863.     IF LOWER(@property) = 'status'
  864.         BEGIN
  865.  
  866.             /*
  867.             ** Check to make sure that we have a valid status.
  868.             */
  869.  
  870.             IF LOWER(@value) NOT IN ('active', 'inactive')
  871.                 BEGIN
  872.                     RAISERROR (14024, 16, -1)
  873.                     RETURN (1)
  874.                 END
  875.  
  876.             /*
  877.             ** Determine the integer value for the status.
  878.             */
  879.  
  880.             IF LOWER(@value) = 'active'
  881.                 SELECT @statusid = 1
  882.             ELSE
  883.                 SELECT @statusid = 0
  884.  
  885.             /*
  886.             ** Update the publication with the new status.
  887.             */
  888.  
  889.             UPDATE syspublications
  890.                SET status = @statusid
  891.              WHERE pubid = @pubid
  892.  
  893.             IF @@ERROR <> 0 RETURN (1)
  894.  
  895.         END
  896.  
  897.     IF LOWER(@property) = 'repl_freq'
  898.         BEGIN
  899.  
  900.         /*
  901.         ** Only unsubscribed publications may have this modified.
  902.         */
  903.         IF EXISTS (SELECT * FROM syssubscriptions
  904.         WHERE status <> @subscribed
  905.         AND artid IN (SELECT artid FROM sysarticles where pubid
  906.            = @pubid))
  907.         BEGIN
  908.             RAISERROR (14033, 11, -1)
  909.             RETURN (1)
  910.         END
  911.     
  912.             /*
  913.             ** Check for a valid replication frequency value.
  914.             */
  915.  
  916.             IF LOWER(@value) NOT IN ('continuous', 'snapshot')
  917.                 BEGIN
  918.                     RAISERROR (14015, 16, -1)
  919.                     RETURN (1)
  920.                 END
  921.  
  922.             /*
  923.             ** Determine the integer value for the replication frequency.
  924.             */
  925.  
  926.             IF LOWER(@value) = 'continuous'
  927.                 SELECT @replfreqid = 0
  928.             ELSE
  929.                 SELECT @replfreqid = 1
  930.  
  931.             /*
  932.             ** Update the publication with the new replication frequency.
  933.             */
  934.  
  935.             UPDATE syspublications
  936.                SET repl_freq = @replfreqid
  937.              WHERE pubid = @pubid
  938.  
  939.             IF @@ERROR <> 0 RETURN (1)
  940.  
  941.         END
  942.  
  943.     IF LOWER(@property) = 'restricted'
  944.         BEGIN
  945.  
  946.             /*
  947.             ** Check for a valid restricted value.
  948.             */
  949.  
  950.             IF LOWER(@value) NOT IN ('true', 'false')
  951.                 BEGIN
  952.                     RAISERROR (14017, 16, -1)
  953.                     RETURN (1)
  954.                 END
  955.  
  956.             /*
  957.             ** Determine the integer value for the restricted column.
  958.             */
  959.  
  960.             IF LOWER(@value) = 'true'
  961.                 SELECT @restrictedid = 1
  962.             ELSE
  963.                 SELECT @restrictedid = 0
  964.  
  965.             /*
  966.             ** Update the publication with the new restriction value.
  967.             */
  968.  
  969.             UPDATE syspublications
  970.                SET restricted = @restrictedid
  971.              WHERE pubid = @pubid
  972.  
  973.             IF @@ERROR <> 0 RETURN (1)
  974.  
  975.         END
  976.  
  977.     /*
  978.     ** Return succeed.
  979.     */
  980.  
  981.     RAISERROR (14077, 10, -1)
  982.     RETURN (0)
  983. GO
  984.  
  985. print ''
  986. print 'Creating procedure sp_changesubscription.'
  987. GO
  988. CREATE PROCEDURE sp_changesubscription (
  989.     @publication varchar(30) = NULL,        /* Publication name */
  990.     @article varchar(30) = NULL,            /* Article name */
  991.     @subscriber varchar(30),              /* Subscriber name */
  992.     @property varchar(15) = NULL,           /* The property to change */
  993.     @value varchar(255) = NULL              /* The new property value */
  994.     ) AS
  995.  
  996.     SET NOCOUNT ON
  997.  
  998.     /*
  999.     ** Declarations.
  1000.     */
  1001.  
  1002.     DECLARE @artid int
  1003.     DECLARE @inactive tinyint
  1004.     DECLARE @pubid int
  1005.     DECLARE @retcode int
  1006.     DECLARE @srvid int
  1007.     DECLARE @subscribed tinyint
  1008.     DECLARE @subscriber_bit smallint
  1009.     DECLARE @synctypeid int
  1010.     DECLARE @none tinyint
  1011.     DECLARE @automatic tinyint
  1012.     DECLARE @manual tinyint
  1013.  
  1014.     /*
  1015.     ** Initializations.
  1016.     */
  1017.  
  1018.     SELECT @inactive = 0        /* Const: subscription status 'inactive' */
  1019.     SELECT @subscribed = 1      /* Const: subscription status 'subscribed' */
  1020.     SELECT @subscriber_bit = 4  /* Const: subscription server status */
  1021.     SELECT @none = 2            /* Const: synchronization type 'none' */
  1022.     SELECT @automatic = 1       /* Const: synchronization type 'automatic' */
  1023.     SELECT @manual = 0          /* Const: synchronization type 'manual' */
  1024.  
  1025.     /*
  1026.     ** Security Check.
  1027.     */
  1028.     IF suser_id() <> 1 AND user_id() <> 1
  1029.         BEGIN
  1030.             RAISERROR (15000, 14, -1)
  1031.             RETURN (1)
  1032.         END
  1033.  
  1034.     /*
  1035.     ** Parameter Check:  @property.
  1036.     ** If the @property parameter is NULL, print the options.
  1037.     */
  1038.  
  1039.     IF @property IS NULL
  1040.         BEGIN
  1041.             CREATE TABLE #tab1 (properties varchar(30))
  1042.             INSERT INTO #tab1 VALUES ('sync_type')
  1043.             INSERT INTO #tab1 VALUES ('dest_db')
  1044.             SELECT * FROM #tab1
  1045.             RETURN (0)
  1046.         END
  1047.  
  1048.     /*
  1049.     ** Parameter Check:  @publication.
  1050.     ** Make sure that the publication exists.
  1051.     */
  1052.  
  1053.     IF @publication IS NULL
  1054.         BEGIN
  1055.             RAISERROR (14043, 16, -1, 'The publication')
  1056.             RETURN (1)
  1057.         END
  1058.  
  1059.     EXECUTE @retcode = sp_validname @publication
  1060.  
  1061.     IF @@ERROR <> 0 OR @retcode <> 0
  1062.     RETURN (1)
  1063.  
  1064.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  1065.  
  1066.     IF @pubid IS NULL
  1067.         BEGIN
  1068.             RAISERROR (15001, 11, -1, @publication)
  1069.             RETURN (1)
  1070.         END
  1071.     ELSE
  1072.  
  1073.     /*
  1074.     ** Check to see that the article exists in sysarticles.
  1075.     ** Fetch the article identification number.
  1076.     */
  1077.  
  1078.     IF @article IS NULL
  1079.         BEGIN
  1080.             RAISERROR (14043, 16, -1, 'The article')
  1081.             RETURN (1)
  1082.         END
  1083.  
  1084.     EXECUTE @retcode = sp_validname @article
  1085.  
  1086.     IF @retcode <> 0
  1087.     RETURN (1)
  1088.  
  1089.     SELECT @artid = artid
  1090.       FROM sysarticles
  1091.      WHERE name = @article
  1092.        AND pubid = @pubid
  1093.  
  1094.     IF @artid IS NULL
  1095.         BEGIN
  1096.             RAISERROR (15001, 11, -1, @article)
  1097.             RETURN (1)
  1098.         END
  1099.  
  1100.     /*
  1101.     ** Parameter Check:  @subscriber.
  1102.     ** Check to make sure we have a valid subscriber.
  1103.     */
  1104.  
  1105.     IF @subscriber IS NULL
  1106.         BEGIN
  1107.             RAISERROR (14043, 16, -1, 'The subscriber')
  1108.             RETURN (1)
  1109.         END
  1110.  
  1111.     EXECUTE @retcode = sp_validname @subscriber
  1112.  
  1113.     IF @retcode <> 0
  1114.     RETURN (1)
  1115.  
  1116.     SELECT @srvid = srvid
  1117.       FROM master..sysservers
  1118.      WHERE srvname = @subscriber
  1119.        AND (srvstatus & @subscriber_bit) <> 0
  1120.  
  1121.     IF @srvid IS NULL
  1122.         BEGIN
  1123.             RAISERROR (14010, 16, -1)
  1124.            RETURN (1)
  1125.         END
  1126.  
  1127.     /*
  1128.     ** Check to see if you have a subscription on this publication/article.
  1129.     */
  1130.  
  1131.     IF NOT EXISTS (SELECT *
  1132.                      FROM syssubscriptions
  1133.                     WHERE artid = @artid
  1134.                       AND srvid = @srvid)
  1135.         BEGIN
  1136.             RAISERROR (14050, 11, -1)
  1137.             RETURN(1)
  1138.         END
  1139.  
  1140.     /*
  1141.     ** Parameter Check:  @property.
  1142.     ** Check to make sure that @property is a valid property in
  1143.     ** sysarticles.
  1144.     */
  1145.  
  1146.     IF LOWER(@property) NOT IN ('sync_type', 'dest_db')
  1147.         BEGIN
  1148.             RAISERROR (14051, 16, -1)
  1149.             RETURN (1)
  1150.         END
  1151.  
  1152.     /*
  1153.     ** Change the property.
  1154.     */
  1155.  
  1156.     IF LOWER(@property) = 'sync_type'
  1157.         BEGIN
  1158.  
  1159.             /*
  1160.             ** Check to make sure that we have a valid sync_type.
  1161.             */
  1162.  
  1163.             IF LOWER(@value) NOT IN ('manual', 'automatic', 'none')
  1164.                 BEGIN
  1165.                     RAISERROR (14052, 16, -1)
  1166.                     RETURN (1)
  1167.                 END
  1168.  
  1169.             /*
  1170.             ** Determine the integer value for the sync_type.
  1171.             */
  1172.  
  1173.         IF LOWER(@value) = 'automatic'
  1174.         SELECT @synctypeid = @automatic
  1175.         ELSE IF LOWER(@value) = 'manual'
  1176.         SELECT @synctypeid = @manual
  1177.         ELSE
  1178.         SELECT @synctypeid = @none
  1179.  
  1180.             /*
  1181.             ** Update the subscription with the new sync_type.
  1182.             */
  1183.  
  1184.             UPDATE syssubscriptions
  1185.                SET sync_type = @synctypeid
  1186.              WHERE artid = @artid
  1187.                AND srvid = @srvid
  1188.  
  1189.             IF @@ERROR <> 0
  1190.                 BEGIN
  1191.                     RAISERROR (14053, 16, -1)
  1192.                     RETURN (1)
  1193.                 END
  1194.  
  1195.         END
  1196.  
  1197.     IF LOWER(@property) = 'dest_db'
  1198.         BEGIN
  1199.  
  1200.             /*
  1201.             ** Check to make sure that we have a valid dest_db.
  1202.             */
  1203.  
  1204.             EXECUTE @retcode = sp_validname @value
  1205.  
  1206.             IF @@ERROR <> 0 OR @retcode <> 0
  1207.         RETURN (1)
  1208.  
  1209.             /*
  1210.             ** Update the subscription with the new destination database.
  1211.             */
  1212.  
  1213.             IF EXISTS (SELECT *
  1214.                          FROM syssubscriptions
  1215.                         WHERE artid = @artid
  1216.                           AND srvid = @srvid
  1217.                           AND status = @inactive)
  1218.  
  1219.                 BEGIN
  1220.  
  1221.                     UPDATE syssubscriptions
  1222.                        SET dest_db = @value
  1223.                      WHERE artid = @artid
  1224.                        AND srvid = @srvid
  1225.  
  1226.                     IF @@ERROR <> 0
  1227.                         BEGIN
  1228.                             RAISERROR (14053, 16, -1)
  1229.                             RETURN (1)
  1230.                         END
  1231.                 END
  1232.  
  1233.             ELSE
  1234.                 BEGIN
  1235.                     RAISERROR (14007, 16, -1)
  1236.                     RETURN (1)
  1237.                 END
  1238.         END
  1239.  
  1240.     /*
  1241.     ** Return succeed.
  1242.     */
  1243.  
  1244.     RAISERROR (14054, 10, -1)
  1245.     RETURN (0)
  1246. go
  1247.  
  1248. print ''
  1249. print 'Creating procedure sp_helparticle.'
  1250. go
  1251.  
  1252. CREATE PROCEDURE sp_helparticle (
  1253.         @publication varchar(30),         /* The publication name */
  1254.         @article varchar(30) = '%',       /* The article name */
  1255.     @returnfilter bit = 1             /* Return filter flag */
  1256.         ) AS
  1257.  
  1258.     SET NOCOUNT ON
  1259.  
  1260.     /*
  1261.     ** Declarations.
  1262.     */
  1263.  
  1264.     DECLARE @pubid int
  1265.     DECLARE @retcode int
  1266.     DECLARE @subscriber_bit smallint
  1267.  
  1268.     /*
  1269.     ** Initializations.
  1270.     */
  1271.  
  1272.     SELECT @subscriber_bit = 4
  1273.  
  1274.     IF @publication IS NOT NULL
  1275.         SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  1276.  
  1277.     /*
  1278.     ** Create a temporary table to hold all information.
  1279.     */
  1280.  
  1281.     CREATE TABLE #tab1 (
  1282.         artid           int,
  1283.         columns         varbinary(32),
  1284.         creation_script varchar(127) NULL,
  1285.         del_cmd         varchar(255) NULL,
  1286.         description     varchar(255) NULL,
  1287.         dest_table      varchar(30)  NULL,
  1288.         old_filter      int          NULL,
  1289.         ins_cmd         varchar(255) NULL,
  1290.         name            varchar(30),
  1291.         objid           int,
  1292.         pubid           int,
  1293.         status          tinyint,
  1294.         sync_objid      int,
  1295.         type            tinyint,
  1296.         upd_cmd         varchar(255) NULL,
  1297.         source_table    varchar(61)  NULL,      /* converted from objid */
  1298.         filter          varchar(61)  NULL,      /* converted from old_filter */
  1299.         sync_object     varchar(61)  NULL,      /* converted from sync_objid */
  1300.         vpartition      bit          NOT NULL,   /* computed */
  1301.     pre_creation_cmd tinyint,
  1302.     filter_clause   text         NULL
  1303.     )
  1304.  
  1305.     CREATE UNIQUE INDEX idx1 ON #tab1 (name, pubid)
  1306.  
  1307.     /*
  1308.     ** Parameter Check:  @publication.
  1309.     ** Check to make sure that there are some articles
  1310.     ** to display.
  1311.     */
  1312.  
  1313.     IF @publication IS NULL
  1314.         BEGIN
  1315.             RAISERROR (14043, 16, -1, 'The publication')
  1316.             RETURN (1)
  1317.         END
  1318.  
  1319.     EXECUTE @retcode = sp_validname @publication
  1320.  
  1321.     IF @retcode <> 0
  1322.     RETURN (1)
  1323.  
  1324.     IF NOT EXISTS (SELECT * FROM syspublications WHERE name = @publication)
  1325.         BEGIN
  1326.             RAISERROR (15001, 11, -1, @publication)
  1327.             RETURN (1)
  1328.         END
  1329.  
  1330.     /*
  1331.     ** Parameter Check:  @article.
  1332.     ** Check to make sure that the article exists, that it conforms
  1333.     ** to the rules for identifiers, and that it isn't NULL.
  1334.     */
  1335.  
  1336.     IF @article IS NULL
  1337.         BEGIN
  1338.             RAISERROR (14043, 16, -1, 'The article')
  1339.             RETURN (1)
  1340.         END
  1341.  
  1342.     IF @article <> '%'
  1343.         BEGIN
  1344.  
  1345.             EXECUTE @retcode = sp_validname @article
  1346.  
  1347.             IF @retcode <> 0
  1348.         RETURN (1)
  1349.  
  1350.             IF NOT EXISTS (SELECT *
  1351.                              FROM sysarticles
  1352.                             WHERE name = @article
  1353.                               AND pubid IN (SELECT pubid
  1354.                                               FROM syspublications
  1355.                                              WHERE name = @publication))
  1356.                 BEGIN
  1357.                     RAISERROR (15001, 11, -1, @article)
  1358.                     RETURN (1)
  1359.                 END
  1360.  
  1361.         END
  1362.  
  1363.     /*
  1364.     ** If local user show all articles.
  1365.     */
  1366.     IF @@REMSERVER IS NULL
  1367.         BEGIN
  1368.         IF @returnfilter = 1
  1369.         BEGIN
  1370.             INSERT INTO #tab1 (artid, columns, creation_script, del_cmd,
  1371.                                description, dest_table, old_filter,
  1372.                                ins_cmd, name, objid, pubid, status,
  1373.                                sync_objid, type, upd_cmd, source_table,
  1374.                                filter, vpartition, pre_creation_cmd,
  1375.                    filter_clause)
  1376.              (SELECT artid, columns, creation_script, del_cmd, a.description,
  1377.                      dest_table, filter, ins_cmd, a.name, objid, a.pubid,
  1378.                      a.status, sync_objid, type, upd_cmd, NULL, NULL, 0,
  1379.              a.pre_creation_cmd, a.filter_clause
  1380.                 FROM sysarticles a, syspublications b
  1381.                WHERE a.name LIKE @article
  1382.                  AND a.pubid = b.pubid
  1383.                  AND b.name = @publication)
  1384.         END
  1385.         ELSE
  1386.         BEGIN
  1387.             INSERT INTO #tab1 (artid, columns, creation_script, del_cmd,
  1388.                                description, dest_table, old_filter,
  1389.                                ins_cmd, name, objid, pubid, status,
  1390.                                sync_objid, type, upd_cmd, source_table,
  1391.                                filter, vpartition, pre_creation_cmd,
  1392.                    filter_clause)
  1393.              (SELECT artid, columns, creation_script, del_cmd, a.description,
  1394.                      dest_table, filter, ins_cmd, a.name, objid, a.pubid,
  1395.                      a.status, sync_objid, type, upd_cmd, NULL, NULL, 0,
  1396.              a.pre_creation_cmd, NULL
  1397.                 FROM sysarticles a, syspublications b
  1398.                WHERE a.name LIKE @article
  1399.                  AND a.pubid = b.pubid
  1400.                  AND b.name = @publication)
  1401.         END
  1402.         END
  1403.  
  1404.     ELSE
  1405.         BEGIN
  1406.  
  1407.             /*
  1408.             ** Check if remote server is defined as a subscription server.
  1409.             */
  1410.  
  1411.             IF NOT EXISTS (SELECT *
  1412.                              FROM sysservers
  1413.                             WHERE srvname = @@REMSERVER
  1414.                               AND (srvstatus & @subscriber_bit) <> 0)
  1415.                 BEGIN
  1416.                     RAISERROR (14010, 16, -1)
  1417.                     RETURN (1)
  1418.                 END
  1419.  
  1420.             /*
  1421.             ** If the publication is public, we can display it.
  1422.             */
  1423.  
  1424.             IF NOT EXISTS (SELECT *
  1425.                              FROM syspublications
  1426.                             WHERE name = @publication
  1427.                               AND restricted = 0)
  1428.  
  1429.                 /*
  1430.                 ** The publication wasn't public, so let's check to see
  1431.                 ** if there's a restricted publication on which I have
  1432.                 ** permission.
  1433.                 */
  1434.  
  1435.                 IF NOT EXISTS (SELECT *
  1436.                                  FROM syssubscriptions a,
  1437.                                       sysarticles b,
  1438.                                       syspublications c
  1439.                                 WHERE c.name = @publication
  1440.                                   AND c.restricted = 1
  1441.                                   AND c.pubid = b.pubid
  1442.                                   AND b.name LIKE @article
  1443.                                   AND b.artid = a.artid)
  1444.  
  1445.                     BEGIN
  1446.                         RAISERROR (14011, 16, -1)
  1447.                         RETURN (1)
  1448.                     END
  1449.  
  1450.             /*
  1451.             ** Fetch the information into the temporary table.  First, put
  1452.             ** in the information about public publications if this publi-
  1453.             ** cation is public.  Next, if the publication is restricted,
  1454.             ** put in only those articles on which you have been granted
  1455.             ** access (sp_addsubscription).
  1456.             */
  1457.  
  1458.         IF @returnfilter = 1
  1459.         BEGIN
  1460.             INSERT INTO #tab1 (artid, columns, creation_script, del_cmd,
  1461.                                description, dest_table, old_filter,
  1462.                    ins_cmd, name, objid, pubid, status,
  1463.                                sync_objid, type, upd_cmd, source_table,
  1464.                                filter, vpartition, pre_creation_cmd,
  1465.                    filter_clause)
  1466.              (SELECT a.artid, columns, creation_script, del_cmd, a.description,
  1467.                      dest_table, filter, ins_cmd, a.name, objid, a.pubid,
  1468.                      a.status, sync_objid, type, upd_cmd, NULL, NULL, 0,
  1469.              a.pre_creation_cmd, a.filter_clause
  1470.                 FROM sysarticles a,
  1471.                      syspublications b
  1472.                WHERE a.name LIKE @article
  1473.                  AND a.pubid = b.pubid
  1474.                  AND b.name = @publication
  1475.                  AND b.restricted = 0)
  1476.  
  1477.             INSERT INTO #tab1 (artid, columns, creation_script, del_cmd,
  1478.                                description, dest_table, old_filter,
  1479.                                ins_cmd, name, objid, pubid, status,
  1480.                                sync_objid, type, upd_cmd, source_table,
  1481.                                filter, vpartition, pre_creation_cmd,
  1482.                    filter_clause)
  1483.              (SELECT a.artid, columns, creation_script, del_cmd, a.description,
  1484.                      dest_table, filter, ins_cmd, a.name, objid, a.pubid,
  1485.                      a.status, sync_objid, type, upd_cmd, NULL, NULL, 0,
  1486.              a.pre_creation_cmd, a.filter_clause
  1487.                 FROM sysarticles a,
  1488.                      syspublications b,
  1489.                      syssubscriptions c,
  1490.                      master..sysservers d
  1491.                WHERE a.name LIKE @article
  1492.                  AND a.pubid = b.pubid
  1493.                  AND b.name = @publication
  1494.                  AND b.restricted = 1
  1495.                  AND a.artid = c.artid
  1496.                  AND c.srvid = d.srvid
  1497.                  AND d.srvname = @@REMSERVER)
  1498.         END
  1499.         ELSE
  1500.                BEGIN
  1501.             INSERT INTO #tab1 (artid, columns, creation_script, del_cmd,
  1502.                                description, dest_table, old_filter,
  1503.                    ins_cmd, name, objid, pubid, status,
  1504.                                sync_objid, type, upd_cmd, source_table,
  1505.                                filter, vpartition, pre_creation_cmd,
  1506.                    filter_clause)
  1507.              (SELECT a.artid, columns, creation_script, del_cmd, a.description,
  1508.                      dest_table, filter, ins_cmd, a.name, objid, a.pubid,
  1509.                      a.status, sync_objid, type, upd_cmd, NULL, NULL, 0,
  1510.              a.pre_creation_cmd, NULL
  1511.                 FROM sysarticles a,
  1512.                      syspublications b
  1513.                WHERE a.name LIKE @article
  1514.                  AND a.pubid = b.pubid
  1515.                  AND b.name = @publication
  1516.                  AND b.restricted = 0)
  1517.  
  1518.             INSERT INTO #tab1 (artid, columns, creation_script, del_cmd,
  1519.                                description, dest_table, old_filter,
  1520.                                ins_cmd, name, objid, pubid, status,
  1521.                                sync_objid, type, upd_cmd, source_table,
  1522.                                filter, vpartition, pre_creation_cmd,
  1523.                    filter_clause)
  1524.              (SELECT a.artid, columns, creation_script, del_cmd, a.description,
  1525.                      dest_table, filter, ins_cmd, a.name, objid, a.pubid,
  1526.                      a.status, sync_objid, type, upd_cmd, NULL, NULL, 0,
  1527.              a.pre_creation_cmd, NULL
  1528.                 FROM sysarticles a,
  1529.                      syspublications b,
  1530.                      syssubscriptions c,
  1531.                      master..sysservers d
  1532.                WHERE a.name LIKE @article
  1533.                  AND a.pubid = b.pubid
  1534.                  AND b.name = @publication
  1535.                  AND b.restricted = 1
  1536.                  AND a.artid = c.artid
  1537.                  AND c.srvid = d.srvid
  1538.                  AND d.srvname = @@REMSERVER)
  1539.         END
  1540.         END
  1541.  
  1542.     UPDATE #tab1
  1543.        SET source_table = u.name + '.' + o.name
  1544.       FROM #tab1, sysobjects o, sysusers u
  1545.      WHERE o.id = #tab1.objid
  1546.        AND o.uid = u.uid
  1547.  
  1548.     UPDATE #tab1
  1549.        SET sync_object = sysusers.name + '.' + sysobjects.name
  1550.       FROM sysobjects, sysusers
  1551.      WHERE sysobjects.id = sync_objid
  1552.        AND sysobjects.uid = sysusers.uid
  1553.  
  1554.     UPDATE #tab1 SET filter = (SELECT sysusers.name + '.' + sysobjects.name
  1555.                                  FROM sysobjects, sysusers
  1556.                                 WHERE sysobjects.id = #tab1.old_filter
  1557.                                   AND sysobjects.uid = sysusers.uid)
  1558.       FROM #tab1
  1559.  
  1560.     EXECUTE ('DECLARE hC SCROLL CURSOR FOR SELECT name, pubid FROM #tab1')
  1561.     OPEN hC
  1562.     FETCH hC INTO @article, @pubid
  1563.     WHILE (@@fetch_status <> -1)
  1564.         BEGIN
  1565.             IF EXISTS (SELECT *
  1566.                          FROM sysarticles a, syscolumns b
  1567.                         WHERE (CONVERT(bit, SUBSTRING(a.columns, CONVERT(tinyint, 32 - FLOOR((colid-1)/8)), 1) & POWER(2, ((colid-1)%8))) = 0
  1568.                            OR CONVERT(bit, SUBSTRING(a.columns, CONVERT(tinyint, 32 - FLOOR((colid-1)/8)), 1) & POWER(2, ((colid-1)%8))) IS NULL)
  1569.                           AND a.objid = b.id
  1570.                           AND a.name = @article
  1571.                           AND a.pubid = @pubid)
  1572.  
  1573.                 UPDATE #tab1
  1574.                    SET vpartition = 1
  1575.                  WHERE name = @article
  1576.                    AND pubid = @pubid
  1577.  
  1578.             FETCH hC INTO @article, @pubid
  1579.         END
  1580.     CLOSE hC
  1581.     DEALLOCATE hC
  1582.  
  1583.     IF @returnfilter = 1
  1584.         SELECT 'article id'                = artid,
  1585.            'article name'              = name,
  1586.            'base table'                = source_table,
  1587.            'destination table'         = dest_table,
  1588.            'synchronization object'    = sync_object,
  1589.            'type'                      = type,
  1590.            'status'                    = status,
  1591.            'filter'                    = filter,
  1592.            'description'               = description,
  1593.            'insert_command'            = ins_cmd,
  1594.            'update_command'            = upd_cmd,
  1595.            'delete_command'            = del_cmd,
  1596.            'creation script path'      = creation_script,
  1597.            'vertical partition'        = vpartition,
  1598.            'pre_creation_cmd'       = pre_creation_cmd,
  1599.            'filter_clause'           = filter_clause
  1600.           FROM #tab1
  1601.          ORDER BY 2
  1602.     ELSE
  1603.         SELECT 'article id'                = artid,
  1604.            'article name'              = name,
  1605.            'base table'                = source_table,
  1606.            'destination table'         = dest_table,
  1607.            'synchronization object'    = sync_object,
  1608.            'type'                      = type,
  1609.            'status'                    = status,
  1610.            'filter'                    = filter,
  1611.            'description'               = description,
  1612.            'insert_command'            = ins_cmd,
  1613.            'update_command'            = upd_cmd,
  1614.            'delete_command'            = del_cmd,
  1615.            'creation script path'      = creation_script,
  1616.            'vertical partition'        = vpartition,
  1617.            'pre_creation_cmd'       = pre_creation_cmd
  1618.           FROM #tab1
  1619.          ORDER BY 2
  1620.     RETURN (0)
  1621. go
  1622.  
  1623. dump tran master with no_log
  1624. go
  1625.  
  1626. print ''
  1627. print 'Creating procedure sp_articlecolumn.'
  1628. go
  1629. CREATE PROCEDURE sp_articlecolumn (
  1630.         @publication varchar(30),           /* The publication name */
  1631.         @article varchar(30),               /* The article name */
  1632.         @column varchar(30) = NULL,         /* The column name */
  1633.         @operation varchar(4) = 'add'      /* Add or delete a column */
  1634.         ) AS
  1635.  
  1636.     /*
  1637.     ** Declarations.
  1638.     */
  1639.  
  1640.     DECLARE @bit tinyint                /* Bit offset */
  1641.     DECLARE @byte tinyint               /* Byte offset */
  1642.     DECLARE @cnt tinyint, @idx tinyint  /* Loop counter, index */
  1643.     DECLARE @columns binary(32)         /* Temporary storage for the converted column */
  1644.     DECLARE @mask smallint              /* Bit mask to set the bit on */
  1645.     DECLARE @newbyte binary(1)          /* New byte to replace old byte with */
  1646.     DECLARE @oldbyte binary(1)          /* Temporary storage for original byte */
  1647.     DECLARE @pubid int                  /* Publication identification number */
  1648.     DECLARE @retcode int                /* Return code for stored procedures */
  1649.     DECLARE @zero binary(32)            /* Constant:  0 */
  1650.     DECLARE @artid int
  1651.     DECLARE @inactive tinyint
  1652.     DECLARE @objid int            /* Article base table id */    
  1653.  
  1654.     select @inactive = 0
  1655.  
  1656.     /*
  1657.     ** Security Check
  1658.     ** Only the System Administratr (SA) or the Database Owner (dbo) can
  1659.     ** perform this procedure.
  1660.     */
  1661.  
  1662.     IF suser_id() <> 1 AND user_id() <> 1
  1663.         BEGIN
  1664.             RAISERROR (15000, 14, -1)
  1665.             RETURN (1)
  1666.         END
  1667.  
  1668.     /*
  1669.     ** Check to see if the database has been activated for publication.
  1670.     */
  1671.  
  1672.     IF (SELECT category & 1
  1673.           FROM master..sysdatabases
  1674.          WHERE name = DB_NAME()) = 0
  1675.  
  1676.     BEGIN
  1677.             RAISERROR (14013, 16, -1)
  1678.         RETURN (1)
  1679.     END
  1680.  
  1681.     /*
  1682.     ** Parameter Check:  @publication.
  1683.     ** Make sure that the publication exists and that it conforms to the
  1684.     ** rules for identifiers.
  1685.     */
  1686.  
  1687.     IF @publication IS NULL
  1688.         BEGIN
  1689.             RAISERROR (14043, 16, -1, 'The publication')
  1690.             RETURN (1)
  1691.         END
  1692.  
  1693.     EXECUTE @retcode = sp_validname @publication
  1694.  
  1695.     IF @retcode <> 0
  1696.             RETURN (1)
  1697.  
  1698.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  1699.  
  1700.     IF @pubid IS NULL
  1701.         BEGIN
  1702.             RAISERROR (15001, 11, -1, @publication)
  1703.             RETURN (1)
  1704.         END
  1705.     ELSE
  1706.  
  1707.     /*
  1708.     ** Parameter Check:  @article.
  1709.     ** Check to make sure that the article exists in the publication.
  1710.     */
  1711.  
  1712.     IF @article IS NULL
  1713.         BEGIN
  1714.             RAISERROR (14043, 16, -1, 'The article')
  1715.             RETURN (1)
  1716.         END
  1717.  
  1718.     EXECUTE @retcode = sp_validname @article
  1719.  
  1720.     IF @@ERROR <> 0 OR @retcode <> 0
  1721.     RETURN (1)
  1722.  
  1723.  
  1724.     /*
  1725.     ** Make sure the article exists.
  1726.     */
  1727.     SELECT @artid = artid FROM sysarticles
  1728.        WHERE pubid = @pubid AND name = @article
  1729.     IF @artid IS NULL
  1730.         BEGIN
  1731.             RAISERROR (15001, 11, -1, @article)
  1732.             RETURN (1)
  1733.         END
  1734.  
  1735.     /*
  1736.     ** Only unsubscribed articles may be modified.
  1737.     */
  1738.     IF EXISTS (SELECT * FROM syssubscriptions WHERE artid = @artid
  1739.        AND status <> @inactive)
  1740.         BEGIN
  1741.             RAISERROR (14092, 11, -1)
  1742.             RETURN (1)
  1743.         END
  1744.  
  1745.     /*
  1746.     ** Parameter Check:  @column.
  1747.     ** Check to make sure that the column exists and conforms to the rules
  1748.     ** for identifiers.
  1749.     */
  1750.  
  1751.     IF @column IS NOT NULL
  1752.         BEGIN
  1753.             EXECUTE @retcode = sp_validname @column
  1754.             IF @@ERROR <> 0 OR @retcode <> 0
  1755.         RETURN (1)
  1756.         END
  1757.  
  1758.     /*
  1759.     ** Parameter Check:  @operation.
  1760.     ** The operation can be either 'add' or 'drop'.
  1761.     */
  1762.  
  1763.     IF LOWER(@operation) NOT IN ('add', 'drop')
  1764.         BEGIN
  1765.             RAISERROR (14019, 16, -1)
  1766.             RETURN (1)
  1767.         END
  1768.  
  1769.     BEGIN TRANSACTION articlecolumn
  1770.  
  1771.     /*
  1772.     ** Make sure that the columns column is not NULL.
  1773.     */
  1774.  
  1775.     SELECT @zero = 0x00
  1776.  
  1777.     SELECT @columns = columns
  1778.       FROM sysarticles
  1779.      WHERE artid = @artid
  1780.  
  1781.     IF @columns IS NULL
  1782.         UPDATE sysarticles
  1783.            SET columns = @zero
  1784.          WHERE artid = @artid
  1785.  
  1786.     SELECT @objid = (SELECT objid FROM sysarticles WHERE artid = @artid)
  1787.  
  1788.     /*
  1789.     ** If no columns are specified, or if NULL is specified, set all
  1790.     ** the bits in the 'columns' column so all columns will be included.
  1791.     */
  1792.  
  1793.     IF @column IS NULL
  1794.  
  1795.         BEGIN
  1796.  
  1797.             /*
  1798.             ** Fetch the number of columns affected.
  1799.             */
  1800.  
  1801.             SELECT @cnt = COUNT(*), @idx = 1
  1802.               FROM syscolumns
  1803.              WHERE id = @objid
  1804.  
  1805.             SELECT @columns = @zero
  1806.  
  1807.             WHILE @idx <= @cnt
  1808.                 BEGIN
  1809.  
  1810.                     SELECT @byte = CONVERT(tinyint, 32 - FLOOR((@idx-1)/8))
  1811.                     SELECT @bit = (@idx-1) % 8
  1812.  
  1813.                     IF LOWER(@operation) = 'add'
  1814.                         SELECT @mask = POWER(2, @bit)
  1815.                     ELSE
  1816.                         SELECT @mask = ~POWER(2, @bit)
  1817.  
  1818.                     SELECT @oldbyte = SUBSTRING(@columns, @byte, 1)
  1819.                     IF @oldbyte IS NULL SELECT @oldbyte = 0x00
  1820.  
  1821.                     IF LOWER(@operation) = 'add'
  1822.                         SELECT @newbyte = CONVERT(binary(1), ASCII(@oldbyte) | @mask)
  1823.                     ELSE
  1824.                         SELECT @newbyte = CONVERT(binary(1), ASCII(@oldbyte) & @mask)
  1825.  
  1826.                     SELECT @columns = CONVERT(binary(32), STUFF(@columns, @byte, 1, @newbyte))
  1827.                     SELECT @idx = @idx + 1
  1828.  
  1829.  
  1830.                 END
  1831.  
  1832.             IF LOWER(@operation) = 'drop'
  1833.            BEGIN
  1834.                /* Update Text\Image column status as not published */
  1835.               EXECUTE @retcode = sp_articletextcol @artid, NULL,
  1836.                  'publish', @operation
  1837.               IF (@@error <> 0 OR @retcode <> 0)
  1838.               BEGIN
  1839.                   ROLLBACK TRANSACTION articlecolumn
  1840.                   RAISERROR (14020, 16, -1)
  1841.                   RETURN (1)
  1842.               END
  1843.            END
  1844.  
  1845.             UPDATE sysarticles
  1846.                SET columns = @columns
  1847.              WHERE name = @article
  1848.                AND pubid = @pubid
  1849.  
  1850.             IF LOWER(@operation) = 'add'
  1851.            BEGIN
  1852.                /* Update Text\Image column status as published */
  1853.               EXECUTE @retcode = sp_articletextcol @artid, NULL,
  1854.                  'publish', @operation
  1855.               IF (@@error <> 0 OR @retcode <> 0)
  1856.               BEGIN
  1857.                   ROLLBACK TRANSACTION articlecolumn
  1858.                   RAISERROR (14020, 16, -1)
  1859.                   RETURN (1)
  1860.               END
  1861.            END
  1862.         END
  1863.  
  1864.     ELSE
  1865.  
  1866.         BEGIN
  1867.                 IF EXISTS (SELECT *
  1868.                              FROM sysarticles
  1869.                             WHERE name = @article
  1870.                               AND pubid = @pubid
  1871.                               AND columns IS NULL)
  1872.  
  1873.                         UPDATE sysarticles
  1874.                           SET columns = @zero
  1875.                         WHERE name = @article
  1876.                           AND pubid = @pubid
  1877.  
  1878.                 DECLARE @columnid tinyint   /* Columnid-1 = bit to set */
  1879.  
  1880.                 /*
  1881.                 ** Get the column id for this column.  We'll use the column id
  1882.                 ** to determine the bit in the 'columns' column.  The bit we want
  1883.                 ** is equal to the columnid - 1.
  1884.                 */
  1885.  
  1886.                 SELECT @columnid = colid
  1887.                   FROM syscolumns
  1888.                  WHERE id = @objid AND name = @column
  1889.  
  1890.                 IF ((@@error <> 0) OR (@columnid IS NULL))
  1891.                     BEGIN
  1892.                         ROLLBACK TRANSACTION articlecolumn
  1893.                         RAISERROR (14020, 16, -1)
  1894.                         RETURN (1)
  1895.                     END
  1896.  
  1897.                 /*
  1898.                 ** Obtain the byte offset and the bit offset, then set the
  1899.                 ** mask column for the bit we want to turn on.
  1900.                 */
  1901.  
  1902.                 SELECT @byte = CONVERT(tinyint, 32 - FLOOR((@columnid-1)/8.0))
  1903.                 SELECT @bit = (@columnid-1) % 8
  1904.  
  1905.                 IF LOWER(@operation) = 'add'
  1906.                     SELECT @mask = POWER(2, @bit)
  1907.                 ELSE
  1908.                     SELECT @mask = ~POWER(2, @bit)
  1909.  
  1910.                 /*
  1911.                 ** Save the columns column in a temporary local variable so we
  1912.                 ** can twiddle the bit and then put it back into the table.
  1913.                 */
  1914.  
  1915.                 SELECT @columns = columns
  1916.                   FROM sysarticles
  1917.                  WHERE name = @article
  1918.                    AND pubid = @pubid
  1919.  
  1920.                 /*
  1921.                 ** Fish out the byte we're interested in and save it in a
  1922.                 ** a temporary local variable.  If it's NULL, just set it
  1923.                 ** to 0.  Then apply the bitwise operator OR to twiddle the
  1924.                 ** bit in the old byte and save it in another temporary
  1925.                 ** local variable @newbyte.
  1926.                 */
  1927.  
  1928.                 SELECT @oldbyte = SUBSTRING(@columns, @byte, 1)
  1929.                 IF @oldbyte IS NULL SELECT @oldbyte = 0x00
  1930.  
  1931.                 IF LOWER(@operation) = 'add'
  1932.                     SELECT @newbyte = CONVERT(binary(1), ASCII(@oldbyte) | @mask)
  1933.                 ELSE
  1934.                     SELECT @newbyte = CONVERT(binary(1), ASCII(@oldbyte) & @mask)
  1935.  
  1936.                 /*
  1937.                 ** Stuff the new byte into the varbinary column to replace the
  1938.                 ** old byte.
  1939.                 */
  1940.  
  1941.                 SELECT @columns = CONVERT(varbinary(32), STUFF(@columns+@zero, @byte, 1, @newbyte))
  1942.  
  1943.                 IF LOWER(@operation) = 'drop'
  1944.                BEGIN
  1945.                    /* Update Text\Image column status as not published */
  1946.                   EXECUTE @retcode = sp_articletextcol @artid, @columnid,
  1947.                      'publish', @operation
  1948.                   IF (@@error <> 0 OR @retcode <> 0)
  1949.                   BEGIN
  1950.                      ROLLBACK TRANSACTION articlecolumn
  1951.                      RAISERROR (14021, 16, -1)
  1952.                      RETURN (1)
  1953.                   END
  1954.                END
  1955.  
  1956.                 /*
  1957.                 ** Update the sysarticles table.  Set the bit to 1 for the
  1958.                 ** selected column.
  1959.                 */
  1960.  
  1961.                 UPDATE sysarticles
  1962.                    SET columns = @columns
  1963.                  WHERE name = @article
  1964.                    AND pubid = @pubid
  1965.  
  1966.                 IF @@error <> 0
  1967.                     BEGIN
  1968.                         ROLLBACK TRANSACTION articlecolumn
  1969.                         RAISERROR (14021, 16, -1)
  1970.                         RETURN (1)
  1971.                     END
  1972.  
  1973.                 IF LOWER(@operation) = 'add'
  1974.                BEGIN
  1975.                    /* Update Text\Image column status as not published */
  1976.                   EXECUTE @retcode = sp_articletextcol @artid, @columnid,
  1977.                      'publish', @operation
  1978.                   IF (@@error <> 0 OR @retcode <> 0)
  1979.                   BEGIN
  1980.                      ROLLBACK TRANSACTION articlecolumn
  1981.                      RAISERROR (14021, 16, -1)
  1982.                      RETURN (1)
  1983.                   END
  1984.                END
  1985.         END
  1986.     /*
  1987.     ** Force the article cache to be refreshed with the new definition.
  1988.     */
  1989.     EXECUTE sp_replflush
  1990.  
  1991.     COMMIT TRANSACTION articlecolumn
  1992. go
  1993.  
  1994. print ''
  1995. print 'Creating procedure sp_helparticlecolumns.'
  1996. go
  1997. CREATE PROCEDURE sp_helparticlecolumns (
  1998.     @publication varchar(30),            /* The publication name */
  1999.     @article    varchar(30)              /* The article name */
  2000.     ) AS
  2001.  
  2002.     /*
  2003.     ** Declarations.
  2004.     */
  2005.  
  2006.     DECLARE @columns binary(32)
  2007.     DECLARE @pubid int
  2008.     DECLARE @retcode int
  2009.  
  2010.     /*
  2011.     ** Parameter Check: @article.
  2012.     ** The @article name must conform to the rules for identifiers.
  2013.     */
  2014.  
  2015.     IF @article IS NULL
  2016.         BEGIN
  2017.             RAISERROR (14043, 16, -1, 'The article')
  2018.             RETURN (1)
  2019.         END
  2020.  
  2021.     EXECUTE @retcode = sp_validname @article
  2022.  
  2023.     IF @retcode <> 0
  2024.     RETURN (1)
  2025.  
  2026.     /*
  2027.     ** Parameter Check: @publication.
  2028.     ** The @publication name must conform to the rules for identifiers.
  2029.     */
  2030.  
  2031.     IF @publication IS NULL
  2032.         BEGIN
  2033.             RAISERROR (14043, 16, -1, 'The publication')
  2034.             RETURN (1)
  2035.         END
  2036.  
  2037.     EXECUTE @retcode = sp_validname @publication
  2038.  
  2039.     IF @retcode <> 0
  2040.     RETURN (1)
  2041.  
  2042.     /*
  2043.     ** Get the pubid.
  2044.     */
  2045.  
  2046.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  2047.  
  2048.     IF @pubid IS NULL
  2049.         BEGIN
  2050.             RAISERROR (14027, 11, -1, 'The publication')
  2051.             RETURN (1)
  2052.         END
  2053.  
  2054.     /*
  2055.     ** Parameter Check:  @article, @publication.
  2056.     ** Check to make sure that the article exists in this publication.
  2057.     */
  2058.  
  2059.     IF NOT EXISTS (SELECT *
  2060.                      FROM sysarticles
  2061.                     WHERE pubid = @pubid
  2062.                       AND name = @article)
  2063.         BEGIN
  2064.             RAISERROR (15001, 11, -1, 'The article')
  2065.             RETURN (1)
  2066.         END
  2067.  
  2068.     IF @@REMSERVER IS NOT NULL
  2069.  
  2070.         /*
  2071.         ** Is the publication/article restricted?
  2072.         */
  2073.  
  2074.         IF EXISTS (SELECT *
  2075.                      FROM syspublications
  2076.                     WHERE pubid = @pubid
  2077.                       AND restricted = 1)
  2078.  
  2079.             /*
  2080.             ** We have a restricted publication.  Does the subscriber
  2081.             ** have access to it?
  2082.             */
  2083.  
  2084.             IF NOT EXISTS (SELECT *
  2085.                              FROM sysarticles a,
  2086.                                   syssubscriptions b,
  2087.                                   master..sysservers c
  2088.                             WHERE c.srvname = @@REMSERVER
  2089.                               AND c.srvid = b.srvid
  2090.                               AND b.artid = a.artid
  2091.                               AND a.name = @article
  2092.                               AND a.pubid = @pubid)
  2093.                 BEGIN
  2094.                     RAISERROR (14011, 16, -1)
  2095.                     RETURN (1)
  2096.                 END
  2097.  
  2098.     SELECT @columns = columns
  2099.       FROM sysarticles
  2100.      WHERE name = @article
  2101.        AND pubid = @pubid
  2102.  
  2103.     SELECT 'column id' = colid,
  2104.            'column'    = name,
  2105.        'published' = CONVERT(bit, SUBSTRING(@columns, CONVERT(tinyint, 32 - FLOOR((colid-1)/8)), 1) & POWER(2, ((colid-1)%8)))
  2106.       FROM syscolumns
  2107.      WHERE id = (SELECT objid
  2108.                    FROM sysarticles
  2109.                   WHERE name = @article
  2110.                     AND pubid = @pubid)
  2111. go
  2112.  
  2113. print ''
  2114. print 'Creating procedure sp_helppublication.'
  2115. go
  2116.  
  2117. CREATE PROCEDURE sp_helppublication (
  2118.         @publication varchar(30) = '%'     /* The publication name */
  2119.         ) AS
  2120.  
  2121.     SET NOCOUNT ON
  2122.  
  2123.     /*
  2124.     ** Declarations.
  2125.     */
  2126.  
  2127.     DECLARE @retcode int
  2128.     DECLARE @subscriber_bit smallint
  2129.  
  2130.     /*
  2131.     ** Initializations.
  2132.     */
  2133.  
  2134.     SELECT @subscriber_bit = 4
  2135.  
  2136.     /*
  2137.     ** If local user show all publications.
  2138.     */
  2139.     IF @@REMSERVER IS NULL
  2140.         BEGIN
  2141.  
  2142.             /*
  2143.             ** Parameter Check:  @publication.
  2144.             ** Check to make sure that there are some publications
  2145.             ** to display.
  2146.             */
  2147.  
  2148.             IF @publication IS NULL
  2149.                 BEGIN
  2150.                     RAISERROR (14043, 16, -1, 'The publication')
  2151.                     RETURN (1)
  2152.                 END
  2153.  
  2154.             IF @publication <> '%'
  2155.                 BEGIN
  2156.  
  2157.                     EXECUTE @retcode = sp_validname @publication
  2158.  
  2159.                     IF @retcode <> 0
  2160.             RETURN (1)
  2161.                 END
  2162.  
  2163.             IF @publication <> '%' AND NOT EXISTS (SELECT *
  2164.                                                      FROM syspublications
  2165.                                                     WHERE name = @publication)
  2166.                 BEGIN
  2167.                     RAISERROR (15001, 11, -1, @publication)
  2168.                 RETURN (1)
  2169.             END
  2170.  
  2171.             SELECT 'pubid'                  = pubid,
  2172.                    'name'                   = name,
  2173.                    'restricted'             = restricted,
  2174.                    'status'                 = status,
  2175.                    'task'                   = taskid,
  2176.                    'replication frequency'  = repl_freq,
  2177.                    'synchronization method' = sync_method,
  2178.                    'description'            = description
  2179.               FROM syspublications
  2180.              WHERE name LIKE @publication
  2181.              ORDER BY name
  2182.  
  2183.             IF @@ERROR <> 0 RETURN (1)
  2184.  
  2185.         END
  2186.  
  2187.     ELSE
  2188.         BEGIN
  2189.  
  2190.             /*
  2191.             ** Check if remote server is defined as a subscription server.
  2192.             */
  2193.  
  2194.             IF NOT EXISTS (SELECT *
  2195.                              FROM sysservers
  2196.                             WHERE srvname = @@REMSERVER
  2197.                               AND (srvstatus & @subscriber_bit) <> 0)
  2198.                 BEGIN
  2199.                     RAISERROR (14010, 16, -1)
  2200.                     RETURN (1)
  2201.                 END
  2202.  
  2203.             /*
  2204.             ** Parameter Check:  @publication.
  2205.             ** Check to make sure that there are some publications
  2206.             ** to display.
  2207.             */
  2208.  
  2209.             IF @publication IS NULL
  2210.                 BEGIN
  2211.                     RAISERROR (14043, 16, -1, 'The publication')
  2212.                     RETURN (1)
  2213.                 END
  2214.  
  2215.             IF @publication <> '%'
  2216.                 BEGIN
  2217.  
  2218.                     EXECUTE @retcode = sp_validname @publication
  2219.  
  2220.                     IF @retcode <> 0
  2221.             RETURN (1)
  2222.                 END
  2223.  
  2224.             IF @publication <> '%'
  2225.                 AND NOT EXISTS (SELECT *
  2226.                                   FROM syspublications
  2227.                              WHERE restricted = 0
  2228.                                    AND name = @publication)
  2229.                 AND NOT EXISTS (SELECT *
  2230.                               FROM syspublications a,
  2231.                                        syssubscriptions b,
  2232.                                        sysarticles c,
  2233.                                        master..sysservers d
  2234.                          WHERE a.restricted = 1
  2235.                                    AND a.name = @publication
  2236.                                AND a.pubid = c.pubid
  2237.                                    AND c.artid = b.artid
  2238.                            AND b.srvid = d.srvid
  2239.                            AND d.srvname =  @@REMSERVER)
  2240.                 BEGIN
  2241.                     RAISERROR (14011, 16, -1)
  2242.                     RETURN (1)
  2243.                 END
  2244.  
  2245.             /*
  2246.             ** Display all public publications and all restricted publications
  2247.             ** allowed for the server.
  2248.             */
  2249.  
  2250.             SELECT 'pubid'                  = pubid,
  2251.                    'name'                   = name,
  2252.                    'restricted'             = restricted,
  2253.                    'status'                 = status,
  2254.                    'task'                   = taskid,
  2255.                    'replication frequency'  = repl_freq,
  2256.                    'synchronization method' = sync_method,
  2257.                    'description'            = description
  2258.               FROM syspublications
  2259.              WHERE restricted = 0
  2260.                AND name LIKE @publication
  2261.              UNION
  2262.             SELECT a.pubid, a.name, a.restricted, a.status, a.taskid, a.repl_freq, a.sync_method, a.description
  2263.               FROM syspublications a,
  2264.                    syssubscriptions b,
  2265.                    sysarticles c,
  2266.                    master..sysservers d
  2267.              WHERE a.restricted = 1
  2268.                AND a.name LIKE @publication
  2269.                AND a.pubid = c.pubid
  2270.                AND c.artid = b.artid
  2271.                AND b.srvid = d.srvid
  2272.                AND d.srvname =  @@REMSERVER
  2273.              ORDER BY name
  2274.  
  2275.             IF @@ERROR <> 0 RETURN (1)
  2276.         END
  2277.  
  2278.     RETURN (0)
  2279. go
  2280.  
  2281. print ''
  2282. print 'Creating procedure sp_helppublicationsync.'
  2283. go
  2284.  
  2285. CREATE PROCEDURE sp_helppublicationsync (
  2286.         @publication varchar(30)     /* The publication name */
  2287.         ) AS
  2288.  
  2289.     SET NOCOUNT ON
  2290.  
  2291.     /*
  2292.     ** Declarations.
  2293.     */
  2294.  
  2295.     DECLARE @retcode int
  2296.     DECLARE @subscriber_bit smallint
  2297.     DECLARE @taskid int
  2298.     DECLARE @distributor varchar(30)
  2299.     DECLARE @distproc varchar (255)
  2300.  
  2301.     /*
  2302.     ** Initializations.
  2303.     */
  2304.  
  2305.     SELECT @subscriber_bit = 4
  2306.  
  2307.     /*
  2308.     ** If local user show all publications.
  2309.     */
  2310.     IF @@REMSERVER IS NULL
  2311.         BEGIN
  2312.  
  2313.             /*
  2314.             ** Parameter Check:  @publication.
  2315.             ** Check to make sure that there are some publications
  2316.             ** to display.
  2317.             */
  2318.  
  2319.             IF @publication IS NULL
  2320.                 BEGIN
  2321.                     RAISERROR (14043, 16, -1, 'The publication')
  2322.                     RETURN (1)
  2323.                 END
  2324.  
  2325.             IF @publication = '%'
  2326.                 BEGIN
  2327.                     RAISERROR (14003, 16, -1, 'The publication')
  2328.                     RETURN (1)
  2329.                 END
  2330.  
  2331.             EXECUTE @retcode = sp_validname @publication
  2332.             IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1)
  2333.  
  2334.             IF NOT EXISTS (SELECT * FROM syspublications
  2335.                WHERE name = @publication)
  2336.                BEGIN
  2337.                     RAISERROR (15001, 11, -1, @publication)
  2338.                 RETURN (1)
  2339.            END
  2340.  
  2341.         END
  2342.  
  2343.     ELSE
  2344.         BEGIN
  2345.  
  2346.             /*
  2347.             ** Check if remote server is defined as a subscription server.
  2348.             */
  2349.  
  2350.             IF NOT EXISTS (SELECT *
  2351.                              FROM sysservers
  2352.                             WHERE srvname = @@REMSERVER
  2353.                               AND (srvstatus & @subscriber_bit) <> 0)
  2354.                 BEGIN
  2355.                     RAISERROR (14010, 16, -1)
  2356.                     RETURN (1)
  2357.                 END
  2358.  
  2359.             /*
  2360.             ** Parameter Check:  @publication.
  2361.             ** Check to make sure that there are some publications
  2362.             ** to display.
  2363.             */
  2364.  
  2365.             IF @publication IS NULL
  2366.                 BEGIN
  2367.                     RAISERROR (14043, 16, -1, 'The publication')
  2368.                     RETURN (1)
  2369.                 END
  2370.  
  2371.             IF @publication = '%'
  2372.                 BEGIN
  2373.                     RAISERROR (14003, 16, -1, 'The publication')
  2374.                     RETURN (1)
  2375.                 END
  2376.  
  2377.             IF  NOT EXISTS (SELECT *
  2378.                                   FROM syspublications
  2379.                              WHERE restricted = 0
  2380.                                    AND name = @publication)
  2381.                 AND NOT EXISTS (SELECT *
  2382.                               FROM syspublications a,
  2383.                                        syssubscriptions b,
  2384.                                        sysarticles c,
  2385.                                        master..sysservers d
  2386.                          WHERE a.restricted = 1
  2387.                                    AND a.name = @publication
  2388.                                AND a.pubid = c.pubid
  2389.                                    AND c.artid = b.artid
  2390.                            AND b.srvid = d.srvid
  2391.                            AND d.srvname =  @@REMSERVER)
  2392.                 BEGIN
  2393.                     RAISERROR (14011, 16, -1)
  2394.                     RETURN (1)
  2395.                 END
  2396.  
  2397.         END
  2398.  
  2399.     /*
  2400.     ** Get the publication sync task id
  2401.     */
  2402.     SELECT @taskid = taskid FROM syspublications WHERE name LIKE @publication
  2403.     IF @@ERROR <> 0 RETURN (1)
  2404.  
  2405.     /*
  2406.     ** Get distribution server information for remote RPC
  2407.     ** task verification.
  2408.     */
  2409.     EXEC @retcode = sp_helpdistributor @distributor = @distributor OUTPUT
  2410.     IF @@error <> 0 OR @retcode <> 0
  2411.         BEGIN
  2412.         RAISERROR (14071, 16, -1)
  2413.             RETURN (1)
  2414.     END
  2415.  
  2416.     /*
  2417.     ** The @taskid must exists in the systasks table.
  2418.     */
  2419.     SELECT @distproc = RTRIM(@distributor) + '.msdb..sp_verifytaskid'
  2420.     EXECUTE @retcode = @distproc @taskid = @taskid, @subsystem = 'Sync'
  2421.     IF @@ERROR <> 0 or @retcode <> 0
  2422.         BEGIN
  2423.             RAISERROR (14002, 16, -1, @taskid)
  2424.             RETURN (1)
  2425.         END
  2426.  
  2427.     /*
  2428.     ** Return sync task information
  2429.     */
  2430.     SELECT @distproc = RTRIM(@distributor) + '.msdb..sp_helptask'
  2431.     EXECUTE @retcode = @distproc @taskid = @taskid, @mode = 'full'
  2432.     IF @@ERROR <> 0 or @retcode <> 0
  2433.        RETURN (1)
  2434. go
  2435.  
  2436. print ''
  2437. print 'Creating procedure sp_helpreplicationdb.'
  2438. go
  2439.  
  2440. CREATE PROCEDURE sp_helpreplicationdb
  2441.         @dbname varchar (30) = '%', @type varchar(30) = 'pub'
  2442.     AS
  2443.  
  2444.     SET NOCOUNT ON
  2445.  
  2446.     /*
  2447.     ** Declarations.
  2448.     */
  2449.  
  2450.     DECLARE @retcode int, @typebit int
  2451.  
  2452.     if (lower(@type) like 'pub%')
  2453.        select @typebit = 1
  2454.     else if (lower(@type) like 'sub%')
  2455.        select @typebit = 2
  2456.     else
  2457.     begin
  2458.        raiserror(14091,-1,-1)
  2459.        return 1
  2460.     end
  2461.  
  2462.     /*
  2463.     ** Parameter Check:  @dbname.
  2464.     ** Check to make sure that the database name conforms to the rules
  2465.     ** for identifiers.
  2466.     */
  2467.  
  2468.  
  2469.     IF @dbname <> '%'
  2470.        BEGIN
  2471.           EXECUTE @retcode = sp_validname @dbname
  2472.  
  2473.           IF @@ERROR <> 0 OR @retcode <> 0
  2474.         RETURN (1)
  2475.        END
  2476.  
  2477.     /*
  2478.     ** Show databases with this option enabled.
  2479.     */
  2480.  
  2481.     SELECT name
  2482.       FROM sysdatabases
  2483.      WHERE name LIKE @dbname
  2484.        AND (category & @typebit) <> 0
  2485. go
  2486.  
  2487.  
  2488. print ''
  2489. print 'Creating procedure sp_enumdsn.'
  2490. go
  2491. CREATE PROCEDURE sp_enumdsn
  2492.     AS
  2493.  
  2494.     SET NOCOUNT ON
  2495.  
  2496.     DECLARE @distributor varchar(30)
  2497.     DECLARE @distproc varchar (255)
  2498.     DECLARE @retcode int
  2499.  
  2500.     /*
  2501.     ** Get distribution server information for remote RPC
  2502.     ** subscription calls.
  2503.     */
  2504.  
  2505.     EXEC @retcode = sp_helpdistributor @distributor = @distributor OUTPUT
  2506.     IF @@error <> 0 OR @retcode <> 0
  2507.         BEGIN
  2508.         RAISERROR (14071, 16, -1)
  2509.             RETURN (1)
  2510.     END
  2511.  
  2512.     /*
  2513.     ** Call xp_enumdsn
  2514.     */
  2515.     SELECT @distproc = RTRIM(@distributor) + '.master..xp_enumdsn'
  2516.     EXEC @retcode = @distproc
  2517.     IF @@error <> 0
  2518.         BEGIN
  2519.         RAISERROR (14071, 16, -1)
  2520.         RETURN (1)
  2521.     END
  2522.  
  2523. go
  2524.  
  2525. print ''
  2526. print 'Creating procedure sp_enumfullsubscribers.'
  2527. go
  2528.  
  2529. CREATE PROCEDURE sp_enumfullsubscribers (
  2530.         @publication varchar(30) = '%'      /* The publication name */
  2531.     ) AS
  2532.  
  2533.     /*
  2534.     ** Declarations.
  2535.     */
  2536.  
  2537.     DECLARE @retcode int
  2538.  
  2539.     /*
  2540.     ** Parameter Check: @publication.
  2541.     ** Check to make sure that the publication exists and that it conforms
  2542.     ** to the rules for identifiers.
  2543.     */
  2544.  
  2545.     IF @publication IS NOT NULL
  2546.         BEGIN
  2547.  
  2548.             IF @publication <> '%'
  2549.                 BEGIN
  2550.  
  2551.                     EXECUTE @retcode = sp_validname @publication
  2552.  
  2553.                     IF @retcode <> 0
  2554.             RETURN (1)
  2555.                 END
  2556.  
  2557.             IF NOT EXISTS (SELECT * FROM syspublications WHERE name LIKE @publication)
  2558.                 BEGIN
  2559.                     RAISERROR (15001, 11, -1, @publication)
  2560.                     RETURN (1)
  2561.                 END
  2562.  
  2563.         END
  2564.  
  2565.     ELSE
  2566.         BEGIN
  2567.             RAISERROR (14043, 16, -1, 'The publication')
  2568.             RETURN (1)
  2569.         END
  2570.  
  2571.     /*
  2572.     ** Select all subscribers who subscribe to all articles in the desired
  2573.     ** publication.
  2574.     */
  2575.  
  2576.     SELECT DISTINCT 'subscriber' = sv.srvname
  2577.       FROM syspublications p,
  2578.            sysarticles s,
  2579.            syssubscriptions ss,
  2580.            master..sysservers sv
  2581.      WHERE p.name LIKE @publication
  2582.        AND p.pubid = s.pubid
  2583.        AND s.artid = ss.artid
  2584.        AND ss.srvid = sv.srvid
  2585.        AND NOT EXISTS (SELECT *
  2586.                          FROM sysarticles s2
  2587.                         WHERE s2.pubid = p.pubid
  2588.                           AND NOT EXISTS (SELECT *
  2589.                                             FROM syssubscriptions ss2,
  2590.                                                  master..sysservers sv2
  2591.                                            WHERE s2.artid = ss2.artid
  2592.                                              AND ss2.srvid = sv2.srvid
  2593.                                              AND sv2.srvid = sv.srvid))
  2594. go
  2595.  
  2596. print ''
  2597. print 'Creating procedure sp_helpsubscriberinfo'
  2598. go
  2599.  
  2600. CREATE PROCEDURE sp_helpsubscriberinfo
  2601.         @subscriber varchar (30)
  2602.     AS
  2603.  
  2604.     SET NOCOUNT ON
  2605.  
  2606.     DECLARE @distributor varchar(30)
  2607.     DECLARE @distribdb varchar(30)
  2608.     DECLARE @distproc varchar (255)
  2609.     DECLARE @retcode int
  2610.  
  2611.     /*
  2612.     ** Check if subscriber is valid
  2613.     */
  2614.  
  2615.     IF @subscriber IS NULL
  2616.         BEGIN
  2617.             RAISERROR (14043, 16, -1, 'The subscriber')
  2618.             RETURN (1)
  2619.         END
  2620.  
  2621.     EXECUTE @retcode = sp_validname @subscriber
  2622.  
  2623.     IF @retcode <> 0
  2624.     RETURN (1)
  2625.  
  2626.     IF NOT EXISTS (SELECT *
  2627.                      FROM master..sysservers
  2628.                     WHERE srvname = @subscriber)
  2629.  
  2630.         BEGIN
  2631.         RAISERROR (14209, 16, -1, @subscriber)
  2632.             RETURN (1)
  2633.         END
  2634.  
  2635.     /*
  2636.     ** Get distribution server information for remote RPC
  2637.     ** subscription calls.
  2638.     */
  2639.  
  2640.     EXEC @retcode = sp_helpdistributor @distributor = @distributor OUTPUT,
  2641.                                        @distribdb   = @distribdb OUTPUT
  2642.  
  2643.     IF @@error <> 0 OR @retcode <> 0 OR @distribdb IS NULL OR @distributor IS NULL
  2644.         BEGIN
  2645.         RAISERROR (14071, 16, -1)
  2646.             RETURN (1)
  2647.     END
  2648.  
  2649.     /*
  2650.     ** Retrieve MSsubscriber_info
  2651.     */
  2652.  
  2653.     SELECT @distproc = RTRIM(@distributor) + '.' +
  2654.         RTRIM(@distribdb) + '..sp_MShelp_subscriber_info '
  2655.  
  2656.     EXEC @retcode = @distproc @@SERVERNAME, @subscriber
  2657.  
  2658.     IF @@error <> 0
  2659.         BEGIN
  2660.         RAISERROR (14071, 16, -1)
  2661.         RETURN (1)
  2662.     END
  2663.  
  2664.     IF @retcode <> 0
  2665.         BEGIN
  2666.         RAISERROR (14085, 16, -1)
  2667.         RETURN (1)
  2668.     END
  2669.  
  2670. go
  2671.  
  2672. print ''
  2673. print 'Creating procedure sp_helpsubscription.'
  2674. go
  2675.  
  2676. CREATE PROCEDURE sp_helpsubscription
  2677.     @publication varchar (30) = '%',    /* The publication name */
  2678.     @article varchar (30) = '%',        /* The article name */
  2679.     @subscriber varchar (30) = '%'      /* The subscriber name */
  2680.     AS
  2681.  
  2682.     SET NOCOUNT ON
  2683.  
  2684.     /*
  2685.     ** Declarations.
  2686.     */
  2687.  
  2688.     DECLARE @retcode int
  2689.     DECLARE @subscriber_bit smallint
  2690.  
  2691.  
  2692.     /*
  2693.     ** Initializations.
  2694.     */
  2695.     SELECT @subscriber_bit = 4
  2696.  
  2697.     /*
  2698.     ** Parameter Check:  @subscriber.
  2699.     ** If remote server, limit the view to the remote server's subscriptions.
  2700.     ** Make sure that the name isn't NULL.
  2701.     */
  2702.  
  2703.     IF @@REMSERVER IS NOT NULL SELECT @subscriber = @@REMSERVER
  2704.  
  2705.     IF @subscriber IS NULL
  2706.         BEGIN
  2707.             RAISERROR (14043, 16, -1, 'The subscriber')
  2708.             RETURN (1)
  2709.         END
  2710.  
  2711.     /*
  2712.     ** Parameter Check:  @subscriber.
  2713.     ** Check if remote server is defined as a subscription server, and
  2714.     ** that the name conforms to the rules for identifiers.
  2715.     */
  2716.  
  2717.     IF @subscriber <> '%'
  2718.         BEGIN
  2719.  
  2720.             EXECUTE @retcode = sp_validname @subscriber
  2721.  
  2722.             IF @retcode <> 0
  2723.         RETURN (1)
  2724.  
  2725.             IF NOT EXISTS (SELECT *
  2726.                              FROM sysservers
  2727.                             WHERE srvname = @subscriber
  2728.                               AND (srvstatus & @subscriber_bit) <> 0)
  2729.                 BEGIN
  2730.                     RAISERROR (14010, 16, -1)
  2731.                     RETURN (1)
  2732.                 END
  2733.         END
  2734.  
  2735.     /*
  2736.     ** Parameter Check:  @publication.
  2737.     ** If the publication name is specified, check to make sure that it
  2738.     ** conforms to the rules for identifiers and that the publication
  2739.     ** actually exists.  Disallow NULL.
  2740.     */
  2741.  
  2742.     IF @publication IS NULL
  2743.         BEGIN
  2744.             RAISERROR (14043, 16, -1, 'The publication')
  2745.             RETURN (1)
  2746.         END
  2747.  
  2748.     IF @publication <> '%'
  2749.         BEGIN
  2750.  
  2751.             EXECUTE @retcode = sp_validname @publication
  2752.  
  2753.             IF @retcode <> 0
  2754.         RETURN (1)
  2755.  
  2756.             IF NOT EXISTS (SELECT * FROM syspublications WHERE name LIKE @publication)
  2757.                 BEGIN
  2758.                    IF @publication = '%'
  2759.                        RAISERROR (14008, 11, -1)
  2760.                    ELSE
  2761.                        RAISERROR (15001, 11, -1, @publication)
  2762.                    RETURN (1)
  2763.                 END
  2764.  
  2765.         END
  2766.  
  2767.     /*
  2768.     ** Parameter Check:  @article.
  2769.     ** If the article name is specified, check to make sure that it
  2770.     ** conforms to the rules for identifiers and that the article
  2771.     ** actually exists.  Disallow NULL.
  2772.     */
  2773.  
  2774.     IF @article IS NULL
  2775.         BEGIN
  2776.             RAISERROR (14043, 16, -1, 'The article')
  2777.             RETURN (1)
  2778.         END
  2779.  
  2780.     IF @article <> '%'
  2781.         BEGIN
  2782.  
  2783.             EXECUTE @retcode = sp_validname @article
  2784.  
  2785.             IF @retcode <> 0
  2786.         RETURN (1)
  2787.  
  2788.             IF NOT EXISTS (SELECT *
  2789.                              FROM sysarticles
  2790.                             WHERE name = @article
  2791.                               AND pubid IN (SELECT pubid
  2792.                                               FROM syspublications
  2793.                                              WHERE name LIKE @publication))
  2794.                 BEGIN
  2795.                     RAISERROR (15001, 11, -1, @article)
  2796.                     RETURN (1)
  2797.                 END
  2798.  
  2799.         END
  2800.  
  2801.     /*
  2802.     ** Get subscriptions
  2803.     */
  2804.  
  2805.     SELECT 'subscriber'           = ss.srvname,
  2806.            'publication'          = pub.name,
  2807.            'article'              = art.name,
  2808.            'destination database' = sub.dest_db,
  2809.            'subscription status'  = sub.status,
  2810.            'synchronization type' = sub.sync_type
  2811.       FROM syssubscriptions sub,
  2812.            sysservers ss,
  2813.            syspublications pub,
  2814.            sysarticles art
  2815.      WHERE ss.srvname LIKE @subscriber
  2816.        AND sub.srvid = ss.srvid
  2817.        AND pub.name LIKE @publication
  2818.        AND art.name LIKE @article
  2819.        AND art.pubid = pub.pubid
  2820.        AND sub.artid = art.artid
  2821.      ORDER BY subscriber, publication, article
  2822. go
  2823.  
  2824. print ''
  2825. print 'Creating procedure sp_replica.'
  2826. go
  2827.  
  2828. CREATE PROCEDURE sp_replica (
  2829.         @tabname varchar(92),     /* The table being replicated */
  2830.         @replicated varchar(5)    /* True or false */
  2831.         ) AS
  2832.  
  2833.     /*
  2834.     ** Declarations.
  2835.     */
  2836.  
  2837.     DECLARE @db varchar(30)
  2838.     DECLARE @id int
  2839.     DECLARE @object varchar(30)
  2840.     DECLARE @owner varchar(30)
  2841.     DECLARE @replica_bit int
  2842.     DECLARE @retcode int
  2843.     DECLARE @site varchar(30)
  2844.  
  2845.     /*
  2846.     ** Initializations.
  2847.     */
  2848.  
  2849.     SELECT @replica_bit = 256
  2850.  
  2851.     /*
  2852.     ** Parameter Check: @tabname.
  2853.     ** Check to make sure that the table exists and that it conforms to the
  2854.     ** rules for identifiers.
  2855.     */
  2856.  
  2857.     IF @tabname IS NULL
  2858.         BEGIN
  2859.             RAISERROR (14043, 16, -1, 'The table')
  2860.             RETURN (1)
  2861.         END
  2862.  
  2863.     EXECUTE sp_namecrack @tabname,
  2864.                          @site OUTPUT,
  2865.                          @db OUTPUT,
  2866.                          @owner OUTPUT,
  2867.                          @object OUTPUT
  2868.  
  2869.     EXECUTE @retcode = sp_validname @object
  2870.  
  2871.     IF @@ERROR <> 0 OR @retcode <> 0
  2872.     return(1)
  2873.  
  2874.     IF @owner IS NOT NULL
  2875.         BEGIN
  2876.  
  2877.             EXECUTE @retcode = sp_validname @owner
  2878.  
  2879.             IF @@ERROR <> 0 OR @retcode <> 0
  2880.         RETURN (1)
  2881.         END
  2882.  
  2883.     IF @db IS NOT NULL
  2884.         BEGIN
  2885.  
  2886.             EXECUTE @retcode = sp_validname @db
  2887.  
  2888.             IF @@ERROR <> 0 OR @retcode <> 0
  2889.         RETURN (1)
  2890.  
  2891.             IF @db <> DB_NAME()
  2892.                 BEGIN
  2893.                     RAISERROR (14004, 16, -1, @object)
  2894.                     RETURN (1)
  2895.                 END
  2896.  
  2897.         END
  2898.  
  2899.     SELECT @id = OBJECT_ID (@tabname)
  2900.     IF @id IS NULL
  2901.         BEGIN
  2902.             RAISERROR (15001, 11, -1, @tabname)
  2903.             RETURN (1)
  2904.         END
  2905.  
  2906.     IF NOT EXISTS (SELECT * FROM sysobjects WHERE id = @id AND type = 'U')
  2907.         BEGIN
  2908.             RAISERROR (14028, 11, -1)
  2909.             RETURN (1)
  2910.         END
  2911.  
  2912.     /*
  2913. ** Parameter Check: @replicated.
  2914.     ** Check to make sure that the value is {true | false}.
  2915.     */
  2916.  
  2917.     IF LOWER(@replicated) NOT IN ('true', 'false')
  2918.         BEGIN
  2919.             RAISERROR (14081, 16, -1)
  2920.             RETURN (1)
  2921.         END
  2922.  
  2923.     /*
  2924.     ** Set the category bit on or off depending upon @replicated.
  2925.     */
  2926.  
  2927.     IF LOWER(@replicated) IN ('true')    /* Turn on bit */
  2928.     UPDATE sysobjects
  2929.            SET category = category | @replica_bit
  2930.          WHERE id = @id
  2931.            AND type = 'U'
  2932.     ELSE                /* Turn off bit */
  2933.      UPDATE sysobjects
  2934.            SET category = category & ~@replica_bit
  2935.          WHERE id = @id
  2936.            AND type = 'U'
  2937.  
  2938.     IF @@ERROR <> 0
  2939.         BEGIN
  2940.             RAISERROR (14083, 16, -1)
  2941.             RETURN (1)
  2942.         END
  2943.  
  2944.     IF LOWER(@replicated) IN ('true')
  2945.         PRINT 'The object was successfully marked as a replicated object.'
  2946.     ELSE
  2947.         PRINT 'The object was successfully unmarked as a replicated object.'
  2948.  
  2949.     RETURN (0)
  2950. go
  2951.  
  2952. print ''
  2953. print 'Creating procedure sp_articlefilter.'
  2954. go
  2955. create procedure sp_articlefilter
  2956.     @publication varchar(30),           /* publication name */
  2957.     @article varchar(30),             /* article name */
  2958.     @filter_name varchar (92) = NULL,     /* name of filter procedure*/
  2959.     @filter_clause text = ''               /* article's filter clause */
  2960.         
  2961. as
  2962.     
  2963.     declare @pubid smallint
  2964.     declare @table_name varchar (30)
  2965.     declare @user_name varchar (30)
  2966.     declare @qualified_table_name varchar (61)
  2967.     declare @filter_id int
  2968.     declare @type tinyint        
  2969.     declare @previous_proc varchar (30)
  2970.     declare @retcode int
  2971.     declare @site varchar(30)
  2972.     declare @db varchar(30)
  2973.     declare @owner varchar(30)
  2974.     declare @object varchar(30)
  2975.     declare @artid int
  2976.     declare @inactive tinyint
  2977.  
  2978.  
  2979.     select @inactive = 0
  2980.  
  2981.     /*
  2982.     ** Security Check.
  2983.     ** Only the System Administrator (SA) or the Database Owner (dbo) can
  2984.     ** add an article view.
  2985.     */
  2986.     if suser_id() <> 1 and user_id() <> 1
  2987.        begin
  2988.               RAISERROR (15000, 14, -1)
  2989.           return (1)
  2990.            end
  2991.  
  2992.     /*
  2993.     ** Parameter Check:  @publication.
  2994.     ** Make sure that the publication exists and that it conforms to the
  2995.     ** rules for identifiers.
  2996.     */
  2997.     if @publication is null
  2998.            begin
  2999.               RAISERROR (14043, 16, -1, 'The publication')
  3000.               return (1)
  3001.            END
  3002.  
  3003.     execute @retcode = sp_validname @publication
  3004.     if @retcode <> 0
  3005.             RETURN (1)
  3006.  
  3007.     select @pubid = pubid from syspublications where name = @publication
  3008.  
  3009.         if @pubid is null
  3010.            begin
  3011.             RAISERROR (15001, 11, -1, @publication)
  3012.             return (1)
  3013.            end
  3014.  
  3015.     /*
  3016.     ** Parameter Check:  @article.
  3017.     ** Check to make sure that the article exists in the publication.
  3018.     */
  3019.  
  3020.     if @article is null
  3021.        begin
  3022.               RAISERROR (14043, 16, -1, 'The article')
  3023.               return (1)
  3024.            end
  3025.  
  3026.         execute @retcode = sp_validname @article
  3027.         if @retcode <> 0
  3028.        return (1)
  3029.  
  3030.     /*
  3031.     ** Get the article information.
  3032.     */
  3033.     select @artid = art.artid, @table_name = so.name, @type = art.type,
  3034.        @filter_id = art.filter, @user_name = USER_NAME(so.uid)
  3035.        from sysarticles art, sysobjects so
  3036.        where art.pubid = @pubid
  3037.        and art.name = @article
  3038.        and art.objid = so.id
  3039.  
  3040.     /*
  3041.     ** Fail if there is no article information.
  3042.     */
  3043.     if @artid is null
  3044.        begin
  3045.               RAISERROR (15001, 11, -1, @article)
  3046.               return (1)
  3047.        end
  3048.  
  3049.         /*
  3050.         ** Only unsubscribed articles may be modified.
  3051.         */
  3052.         if exists (select * from syssubscriptions where artid = @artid
  3053.           and status <> @inactive)
  3054.           begin
  3055.          RAISERROR (14092, 11, -1)
  3056.              RETURN (1)
  3057.           end
  3058.  
  3059.     /*
  3060.     ** Make sure a valid @filter_name was provided and it is
  3061.     ** a valid name.
  3062.     */
  3063.     if datalength(@filter_clause) > 1
  3064.        begin
  3065.              /*
  3066.         ** Make sure a valid @filter_name was provided and it is
  3067.         ** a valid name.
  3068.         */
  3069.         if @filter_name is null
  3070.            begin
  3071.               RAISERROR (14043, 16, -1, 'The filter_name')
  3072.               return (1)
  3073.            end
  3074.  
  3075.         execute sp_namecrack @filter_name,
  3076.            @site OUTPUT,
  3077.            @db OUTPUT,
  3078.            @owner OUTPUT,
  3079.            @object OUTPUT
  3080.  
  3081.         execute @retcode = sp_validname @object
  3082.         if @retcode <> 0
  3083.            return (1)
  3084.        end
  3085.  
  3086.     /*
  3087.     ** If the article has a generated filter (not manually created), then
  3088.     ** drop the current filter before creating the new one.
  3089.     */
  3090.     if ((@type & 0x3) <> 0x3) and @filter_id <> 0
  3091.        begin
  3092.            select @previous_proc = object_name (@filter_id)
  3093.           if @previous_proc is not null and
  3094.              exists (select * from sysobjects where name = @previous_proc
  3095.                 and type = 'RF')
  3096.          begin
  3097.                 exec ('drop procedure ' + @previous_proc)
  3098.             if @@error <> 0
  3099.                return (1)
  3100.          end
  3101.  
  3102.        end
  3103.  
  3104.     /*
  3105.     ** make an owner qualified table name for these operations name
  3106.     */
  3107.  
  3108.     select @qualified_table_name = @user_name + '.' + @table_name
  3109.  
  3110.     /*
  3111.     ** If there is a @filter_clause, create the new filter and
  3112.     ** update the article filter id and filter_clause.
  3113.     **/
  3114.     if datalength(@filter_clause) > 1
  3115.        begin
  3116.         exec ('create procedure ' + @object +
  3117.             ' for replication as ' +
  3118.             'if exists (select * from ' + @qualified_table_name +
  3119.             ' where ' + @filter_clause +
  3120.             ') return 1 else return 0')
  3121.         if @@error <> 0
  3122.            return (1)
  3123.  
  3124.         select @filter_id = id  from sysobjects where name = @object
  3125.             and type = 'RF'
  3126.         if @filter_id is null or @filter_id = 0
  3127.            begin
  3128.               RAISERROR (15001, 11, -1, @object)
  3129.               return (1)
  3130.            end
  3131.  
  3132.         /*
  3133.         ** Update article
  3134.         */
  3135.         update sysarticles set filter = @filter_id,
  3136.            filter_clause = @filter_clause
  3137.            where pubid = @pubid
  3138.               and name = @article
  3139.        end
  3140.     else
  3141.         /*
  3142.         ** Clear the filter id and filter_clause.
  3143.         */
  3144.         update sysarticles set filter = 0,
  3145.            filter_clause = NULL
  3146.            where pubid = @pubid
  3147.               and name = @article
  3148.  
  3149.         /*
  3150.         ** Force the article cache to be refreshed with the new definition.
  3151.         */
  3152.         EXECUTE sp_replflush
  3153. go
  3154.  
  3155. print ''
  3156. print 'Creating procedure sp_articletextcol.'
  3157. go
  3158. CREATE PROCEDURE sp_articletextcol (
  3159.     @artid int,
  3160.     @colid tinyint = NULL,
  3161.     @type varchar(10),      /* 'publish', 'nonsqlsub' */
  3162.     @operation varchar(5))  /* 'add', 'drop' */
  3163.     AS
  3164.  
  3165.     /*
  3166.     ** Declarations.
  3167.     */
  3168.     DECLARE @cmd char(255)
  3169.     DECLARE @cmd1 char(255)
  3170.     DECLARE @columns binary(32)    /* Temporary storage for the converted column */
  3171.     DECLARE @tabid int        /* Article base table id */
  3172.     DECLARE @retcode int
  3173.     DECLARE @status bit
  3174.     DECLARE @image tinyint        /* Constant: 0x22 */
  3175.     DECLARE @text tinyint        /* Constant: 0x23 */
  3176.     DECLARE @publish tinyint        /* Constant: 0x10 */
  3177.     DECLARE @nonsqlsub tinyint        /* Constant: 0x20 */
  3178.  
  3179.     /* Constants */
  3180.     SELECT @image = 0x22
  3181.     SELECT @text = 0x23
  3182.     SELECT @publish = 0x10
  3183.     SELECT @nonsqlsub = 0x20
  3184.  
  3185.     /*
  3186.     ** Security Check
  3187.     ** Only the System Administratr (SA) or the Database Owner (dbo)
  3188.     ** can execute this procedure.
  3189.     */
  3190.     IF suser_id() <> 1 AND user_id() <> 1
  3191.         BEGIN
  3192.             RAISERROR (14093, 14, -1)
  3193.             RETURN (1)
  3194.         END
  3195.  
  3196.     SELECT @tabid = objid FROM sysarticles WHERE artid = @artid
  3197.  
  3198.     SELECT @cmd = @cmd + 'DECLARE hCarttextcol CURSOR FOR'
  3199.  
  3200.     IF @colid IS NULL
  3201.        BEGIN
  3202.        SELECT @cmd = @cmd + ' SELECT colid FROM syscolumns, sysarticles'
  3203.        SELECT @cmd = @cmd + ' WHERE artid = ' + CONVERT(varchar(10), @artid)
  3204.        SELECT @cmd = @cmd + ' AND id = ' + CONVERT(varchar(10), @tabid)
  3205.        SELECT @cmd = @cmd + ' AND (syscolumns.type = 0x22 OR syscolumns.type = 0x23)'
  3206.        SELECT @cmd1 = @cmd1 + ' AND CONVERT(bit, SUBSTRING(columns,'
  3207.        SELECT @cmd1 = @cmd1 + ' CONVERT(tinyint, 32 - FLOOR((colid-1)/8)),'
  3208.        SELECT @cmd1 = @cmd1 + ' 1) & POWER(2, ((colid-1)%8))) = 1'
  3209.        EXECUTE (@cmd + @cmd1)
  3210.        END
  3211.     ELSE
  3212.        BEGIN
  3213.        SELECT @cmd = @cmd + ' SELECT colid FROM syscolumns WHERE id ='
  3214.        SELECT @cmd = @cmd + ' ' + CONVERT(varchar(10), @tabid)
  3215.        SELECT @cmd = @cmd + ' AND colid =' + CONVERT(varchar(10), @colid)
  3216.        SELECT @cmd = @cmd + ' AND (type = 0x22 OR type = 0x23)'
  3217.        EXECUTE (@cmd)
  3218.        END
  3219.  
  3220.  
  3221.     /* Process each Text\Image column in the article */
  3222.     OPEN hCarttextcol
  3223.     FETCH hCarttextcol INTO @colid
  3224.     WHILE (@@fetch_status <> -1)
  3225.     BEGIN
  3226.  
  3227.        IF LOWER(@operation) = 'add'
  3228.           BEGIN
  3229.           IF LOWER(@type) = 'publish'
  3230.              UPDATE syscolumns
  3231.                 SET status = status | @publish
  3232.             WHERE id = @tabid
  3233.                   AND colid = @colid
  3234.       ELSE
  3235.          UPDATE syscolumns
  3236.                 SET status = status | @nonsqlsub
  3237.             WHERE id = @tabid
  3238.                   AND colid = @colid
  3239.       END
  3240.        ELSE /* drop */
  3241.           BEGIN
  3242.       /*
  3243.       ** Is there another non-sql server subscription on the column?
  3244.       ** Or another article publishing the column?
  3245.       */
  3246.       EXEC @retcode = sp_textcolstatus @artid, @tabid, @colid,
  3247.          @type, @status OUTPUT
  3248.  
  3249.       IF @@error <> 0 OR @retcode <> 0
  3250.          BEGIN
  3251.             CLOSE hCarttextcol
  3252.         DEALLOCATE hCarttextcol
  3253.         RETURN (1)
  3254.          END
  3255.  
  3256.       IF (@status = 0)
  3257.          BEGIN
  3258.          IF LOWER(@type) = 'publish'
  3259.             /* Clear 'publish' bit */
  3260.                 UPDATE syscolumns
  3261.                    SET status = status & ~@publish
  3262.                WHERE id = @tabid
  3263.                      AND colid = @colid
  3264.           ELSE
  3265.             /* Clear 'non-sql server subscription' bit */
  3266.                 UPDATE syscolumns
  3267.                    SET status = status & ~@nonsqlsub
  3268.                WHERE id = @tabid
  3269.                      AND colid = @colid
  3270.              END
  3271.           END
  3272.        FETCH hCarttextcol INTO @colid
  3273.     END
  3274.  
  3275.     CLOSE hCarttextcol
  3276.     DEALLOCATE hCarttextcol
  3277.  
  3278. GO
  3279.  
  3280. print ''
  3281. print 'Creating procedure sp_textcolstatus.'
  3282. go
  3283. CREATE PROCEDURE sp_textcolstatus (
  3284.     @artid int,
  3285.     @tabid int,
  3286.     @colid int,
  3287.     @type varchar (10),      /* 'publish', 'nonsqlsub' */
  3288.     @status bit OUTPUT)
  3289.     AS
  3290.  
  3291.     /*
  3292.     ** Declarations.
  3293.     */
  3294.     DECLARE @cmd char(255)
  3295.     DECLARE @artid2 int
  3296.     DECLARE @columns binary(32)
  3297.     DECLARE @replicate tinyint        /* Constant: 0x10 */
  3298.     DECLARE @nonsqlsub tinyint        /* Constant: 0x20 */
  3299.     DECLARE @image tinyint        /* Constant: 0x22 */
  3300.     DECLARE @text tinyint        /* Constant: 0x23 */
  3301.  
  3302.     /* Constants */
  3303.     SELECT @image = 0x22
  3304.     SELECT @text = 0x23
  3305.  
  3306.     SELECT @status = 0
  3307.  
  3308.     /*
  3309.     ** Security Check
  3310.     ** Only the System Administratr (SA) or the Database Owner (dbo)
  3311.     ** can execute this procedure.
  3312.     */
  3313.     IF suser_id() <> 1 AND user_id() <> 1
  3314.         BEGIN
  3315.             RAISERROR (14093, 14, -1)
  3316.             RETURN (1)
  3317.         END
  3318.  
  3319.     IF LOWER(@type) = 'nonsqlsub'
  3320.     BEGIN
  3321.     /*
  3322.     ** Check all active or subscribed articles for the TEXT/IMAGE column.
  3323.     */    
  3324.     SELECT @cmd = @cmd + 'DECLARE hC4 CURSOR FOR '
  3325.     SELECT @cmd = @cmd + ' SELECT sub.artid FROM sysarticles art, syssubscriptions sub'
  3326.     SELECT @cmd = @cmd + '  WHERE art.objid = ' + CONVERT(varchar(10), @tabid)
  3327.     SELECT @cmd = @cmd + '  AND art.artid <> ' + CONVERT(varchar(10), @artid)
  3328.     SELECT @cmd = @cmd + '  AND sub.artid = art.artid'
  3329.     SELECT @cmd = @cmd + '  AND sub.status = 1 OR sub.status = 2'
  3330.     END
  3331.     ELSE
  3332.     BEGIN
  3333.     /*
  3334.     ** Check all articles for the TEXT/IMAGE column.
  3335.     */    
  3336.     SELECT @cmd = @cmd + 'DECLARE hC4 CURSOR FOR '
  3337.     SELECT @cmd = @cmd + ' SELECT artid FROM sysarticles '
  3338.     SELECT @cmd = @cmd + '  WHERE objid = ' + CONVERT(varchar(10), @tabid)
  3339.     SELECT @cmd = @cmd + '  AND artid <> ' + CONVERT(varchar(10), @artid)
  3340.     END
  3341.  
  3342.     EXECUTE (@cmd)
  3343.     OPEN hC4
  3344.     FETCH hC4 INTO @artid2
  3345.     WHILE (@@fetch_status <> -1)
  3346.     BEGIN
  3347.        SELECT @columns = columns FROM sysarticles WHERE artid = @artid2
  3348.  
  3349.        IF EXISTS (SELECT * FROM syscolumns
  3350.           WHERE id = @tabid
  3351.           AND colid = @colid
  3352.       AND CONVERT(bit, SUBSTRING(@columns, CONVERT(tinyint,
  3353.          32 - FLOOR((colid-1)/8)), 1) & POWER(2, ((colid-1)%8))) = 1
  3354.       AND (type = @image OR type = @text))
  3355.           BEGIN
  3356.          SELECT @status = 1    
  3357.          GOTO CLEANUP
  3358.           END
  3359.  
  3360.        FETCH hC4 INTO @artid2
  3361.     END
  3362.  
  3363. CLEANUP:
  3364.     CLOSE hC4
  3365.     DEALLOCATE hC4
  3366.  
  3367.     RETURN (0)
  3368. GO
  3369.  
  3370. print ''
  3371. print 'Creating procedure sp_articleview.'
  3372. go
  3373. create procedure sp_articleview
  3374.     @publication varchar(30),        /* Publication name */
  3375.     @article varchar(30),          /* Article name */
  3376.     @view_name varchar (92) = NULL,  /* View name */
  3377.     @filter_clause text = ''            /* Article's filter clause */
  3378.         
  3379. as
  3380.     declare @pubid smallint
  3381.     declare @table_name varchar (30)
  3382.     declare @user_id int
  3383.     declare @user_name varchar (30)
  3384.     declare @qualified_table_name varchar (61)
  3385.     declare @columns varbinary (32)
  3386.     declare @name varchar (30)
  3387.     declare @col_clause1 varchar (255)
  3388.     declare @col_clause2 varchar (255)
  3389.     declare @retcode int
  3390.     declare @view_id int
  3391.     declare @type tinyint
  3392.     declare @table_id int
  3393.     declare @previous_view varchar (30)
  3394.     declare @colid int
  3395.     declare @site varchar(30)
  3396.     declare @db varchar(30)
  3397.     declare @owner varchar(30)
  3398.     declare @object varchar(30)
  3399.     declare @artid int
  3400.     declare @inactive tinyint
  3401.  
  3402.  
  3403.     select @inactive = 0
  3404.  
  3405.     /*
  3406.     ** Security Check.
  3407.     ** Only the System Administrator (SA) or the Database Owner (dbo) can
  3408.     ** add an article view.
  3409.     */
  3410.     if suser_id() <> 1 and user_id() <> 1
  3411.        begin
  3412.               RAISERROR (15000, 14, -1)
  3413.           return (1)
  3414.            end
  3415.  
  3416.     /*
  3417.     ** Parameter Check:  @publication.
  3418.     ** Make sure that the publication exists and that it conforms to the
  3419.     ** rules for identifiers.
  3420.     */
  3421.     if @publication is null
  3422.            begin
  3423.               RAISERROR (14043, 16, -1, 'The publication')
  3424.               return (1)
  3425.            END
  3426.  
  3427.     execute @retcode = sp_validname @publication
  3428.     if @retcode <> 0
  3429.             RETURN (1)
  3430.  
  3431.     select @pubid = pubid from syspublications where name = @publication
  3432.         if @pubid is null
  3433.            begin
  3434.             RAISERROR (15001, 11, -1, @publication)
  3435.             return (1)
  3436.            end
  3437.  
  3438.     /*
  3439.     ** Parameter Check:  @article.
  3440.     ** Check to make sure that the article exists in the publication.
  3441.     */
  3442.  
  3443.     if @article is null
  3444.        begin
  3445.               RAISERROR (14043, 16, -1, 'The article')
  3446.               return (1)
  3447.            end
  3448.  
  3449.         execute @retcode = sp_validname @article
  3450.         if @retcode <> 0
  3451.        return (1)
  3452.  
  3453.     /*
  3454.     ** Get the article information.
  3455.     */
  3456.     select @artid = art.artid, @table_name = so.name,
  3457.        @user_id = uid, @user_name = USER_NAME(so.uid),
  3458.        @columns = art.columns, @type = art.type,
  3459.        @view_id = art.sync_objid, @table_id = art.objid
  3460.        from sysarticles art, sysobjects so
  3461.        where art.pubid = @pubid
  3462.        and art.name = @article
  3463.        and art.objid = so.id
  3464.  
  3465.     /*
  3466.     ** Fail if there is no article information.
  3467.     */
  3468.     if @artid is null
  3469.        begin
  3470.               RAISERROR (15001, 11, -1, @article)
  3471.               return (1)
  3472.        end
  3473.  
  3474.         /*
  3475.         ** Only unsubscribed articles may be modified.
  3476.         */
  3477.         if exists (select * from syssubscriptions where artid = @artid
  3478.           and status <> @inactive)
  3479.           begin
  3480.          RAISERROR (14092, 11, -1)
  3481.              RETURN (1)
  3482.           end
  3483.  
  3484.     
  3485.     /*
  3486.     ** Create a table of all the articles columns.
  3487.     */
  3488.     create table #tmp (colid int, name varchar(30), published bit)
  3489.     if @@error <> 0
  3490.        return (1)
  3491.  
  3492.     create unique index ind1 on #tmp (colid)
  3493.     if @@error <> 0
  3494.        begin
  3495.         drop table #tmp
  3496.         return (1)
  3497.        end
  3498.  
  3499.     insert into #tmp select colid, name,
  3500.         convert(bit, substring(@columns, convert(tinyint,
  3501.             32 - floor((colid-1)/8)), 1) & POWER(2, ((colid-1)%8)))
  3502.         from syscolumns
  3503.         where id = (select id from sysobjects where name = @table_name and
  3504.            uid = @user_id and type = 'U')
  3505.  
  3506.     /* Break out the specified view name and get the non-ownerqual'd name, then validate that. */
  3507.     execute sp_namecrack @view_name, @site OUTPUT, @db OUTPUT, @owner OUTPUT, @object OUTPUT
  3508.     execute @retcode = sp_validname @object
  3509.     if @retcode <> 0
  3510.         return (1)
  3511.  
  3512.     /* If no non-published columns, we'll select all and avoid the 510-byte limit on column strings. */
  3513.     if not exists (select * from #tmp where published = 0) begin
  3514.         select @col_clause1 = null
  3515.         select @col_clause2 = null
  3516.         goto CreateView
  3517.     end
  3518.  
  3519.     /*
  3520.     ** Construct the column list based on all published columns in the
  3521.     ** article.
  3522.     */
  3523.     execute ('declare hC scroll cursor for select colid, name from #tmp
  3524.         where published = 1')
  3525.     open hC
  3526.     fetch hC into @colid, @name
  3527.     while (@@fetch_status <> -1)
  3528.         begin
  3529.  
  3530.         if @col_clause1 is null or
  3531.         ((datalength(@name) + datalength(@col_clause1) + 2) < 255)
  3532.         if @col_clause1 is null
  3533.             select @col_clause1 = @name
  3534.         else
  3535.             select @col_clause1 = @col_clause1 + ', ' + @name
  3536.         
  3537.         else if @col_clause2 is null or
  3538.         ((datalength(@name) + datalength(@col_clause2) + 2) < 255)
  3539.         begin
  3540.             if @col_clause2 is null
  3541.                 select @col_clause2 = ','+ @name
  3542.             else
  3543.                 select @col_clause2 = @col_clause2 + ', ' +
  3544.                     @name
  3545.         end
  3546.         else
  3547.             /*
  3548.         ** The procedure only support ~510 bytes for the column list
  3549.         */
  3550.         begin
  3551.             RAISERROR (14039, 16, -1)
  3552.             close hC
  3553.             deallocate hC
  3554.             drop table #tmp
  3555.             return (1)
  3556.         end
  3557.         fetch hC into @colid, @name
  3558.         end            
  3559.  
  3560.     close hC
  3561.     deallocate hC
  3562.  
  3563. CreateView:
  3564.     /*
  3565.     ** If the article has a generated view (not manually created), then
  3566.     ** drop the current view before creating the new one.
  3567.     */
  3568.     if ((@type & 0x5) <> 0x5) and @view_id <> 0
  3569.        and @view_id <> @table_id
  3570.        begin
  3571.            select @previous_view = object_name (@view_id)
  3572.           if @previous_view is not null and
  3573.                  exists (select * from sysobjects where name = @previous_view
  3574.                 and type = 'V')
  3575.              exec ('drop view ' + @previous_view)
  3576.        end
  3577.  
  3578.     /*
  3579.     ** If a view is going to be created. Make sure a valid @view_name
  3580.     ** was provided.
  3581.     */
  3582.     if @col_clause1 is not null or @col_clause2 is not null
  3583.        begin
  3584.           if @view_name is null
  3585.              begin
  3586.                 RAISERROR (14043, 16, -1, 'The view_name')
  3587.                 return (1)
  3588.              end
  3589.         end
  3590.  
  3591.     /*
  3592.     ** make an owner qualified table name for these operations name
  3593.     */
  3594.  
  3595.     select @qualified_table_name = @user_name + '.' + @table_name
  3596.  
  3597.     /*
  3598.     ** Construct and execute the view creation command.
  3599.     */
  3600.     if @col_clause2 is not null
  3601.        begin
  3602.         if datalength(@filter_clause) > 1
  3603.             exec ('create view ' + @object + ' as select ' +
  3604.                 @col_clause1 + @col_clause2 + ' from ' +
  3605.                 @qualified_table_name + ' where ' + @filter_clause)
  3606.         else
  3607.             exec ('create view ' + @object + ' as select ' +
  3608.                 @col_clause1 + @col_clause2 + ' from ' +
  3609.                 @qualified_table_name)
  3610.         if @@error <> 0
  3611.            return (1)
  3612.        end
  3613.     else if @col_clause1 is not null
  3614.       begin
  3615.  
  3616.         if datalength(@filter_clause) > 1
  3617.             exec ('create view ' + @object + ' as select ' +
  3618.                 @col_clause1 + ' from ' +  @qualified_table_name +
  3619.                 ' where ' + @filter_clause)
  3620.         else
  3621.             exec ('create view ' + @object + ' as select ' +
  3622.                 @col_clause1 + ' from ' +  @qualified_table_name)
  3623.         if @@error <> 0
  3624.            return (1)
  3625.        end
  3626.     else
  3627.         begin
  3628.             if datalength(@filter_clause) > 1
  3629.                 exec ('create view ' + @object + ' as select * from ' +
  3630.                     @qualified_table_name + ' where ' + @filter_clause)
  3631.             if @@error <> 0
  3632.                return (1)
  3633.  
  3634.         end
  3635.     /*
  3636.     ** Update the article's sync_objid with the new view or the base
  3637.     ** table id.
  3638.     */
  3639.     if @col_clause1 is null and datalength(@filter_clause) = 1
  3640.        select @view_id = object_id(@qualified_table_name)
  3641.     else
  3642.        begin
  3643.           select @view_id = id from sysobjects where name = @object and
  3644.              type = 'V'
  3645.           if @view_id is null or @view_id = 0
  3646.              begin
  3647.                 RAISERROR (15001, 11, -1, @object)
  3648.                 return (1)    
  3649.              end
  3650.        end
  3651.  
  3652.     /* Update article definition */
  3653.     update sysarticles set sync_objid = @view_id where
  3654.        pubid = @pubid and
  3655.        name = @article
  3656.  
  3657.     /*
  3658.     ** Set new sync_objid and @filter_clause value
  3659.     */
  3660.     if datalength(@filter_clause) > 1
  3661.        update sysarticles set sync_objid = @view_id,
  3662.           filter_clause = @filter_clause
  3663.           where pubid = @pubid
  3664.           and name = @article
  3665.     else
  3666.        update sysarticles set sync_objid = @view_id,
  3667.           filter_clause = NULL
  3668.           where pubid = @pubid
  3669.           and name = @article
  3670.  
  3671.        drop table #tmp
  3672.  
  3673.        /*
  3674.        ** Force the article cache to be refreshed with the new definition.
  3675.        */
  3676.        EXECUTE sp_replflush
  3677. go
  3678.  
  3679. dump tran master with no_log
  3680. go
  3681.  
  3682. print ''
  3683. print 'Creating procedure sp_addarticle.'
  3684. go
  3685. CREATE PROCEDURE sp_addarticle
  3686.     @publication varchar(30),               /* publication name */
  3687.     @article varchar(30),             /* article name */
  3688.     @source_table varchar (92),         /* table name */
  3689.     @destination_table varchar (30) = NULL, /* destination table name */
  3690.     @vertical_partition char(5) = 'false',  /* vertical partition */
  3691.     @type varchar (30) = 'logbased',        /* article type */
  3692.     @filter varchar (92) = NULL,        /* stored procedure used to filter table */
  3693.     @sync_object varchar (92) = NULL,        /* view or table used for synchronization */
  3694.     @ins_cmd varchar (255) = 'SQL',        /* insert format string */
  3695.     @del_cmd varchar (255) = 'SQL',        /* delete format string */
  3696.     @upd_cmd varchar (255) = 'SQL',        /* update format string */
  3697.     @creation_script varchar (127) = NULL,  /* article schema script */
  3698.     @description varchar (255) = NULL,        /* article description */
  3699.     @pre_creation_cmd varchar(10) = 'drop', /* 'none', 'drop', 'delete', 'truncate' */
  3700.     @filter_clause text    = ''            /* where clause */
  3701.     AS
  3702.  
  3703.     SET NOCOUNT ON
  3704.  
  3705.     /*
  3706.     ** Declarations.
  3707.     */
  3708.  
  3709.     DECLARE @accessid smallint
  3710.     DECLARE @db varchar(30)
  3711.     DECLARE @filterid int
  3712.     DECLARE @object varchar(30)
  3713.     DECLARE @owner varchar(30)
  3714.     DECLARE @pubid int
  3715.     DECLARE @publish_bit smallint
  3716.     DECLARE @retcode int
  3717.     DECLARE @site varchar(30)
  3718.     DECLARE @syncid int
  3719.     DECLARE @tabid int
  3720.     DECLARE @typeid smallint
  3721.     DECLARE @pkkey varchar (30)
  3722.     DECLARE @i int
  3723.     DECLARE @indid int
  3724.     DECLARE @precmdid int
  3725.  
  3726.     SELECT @publish_bit = 32
  3727.  
  3728.     /*
  3729.     ** Security Check.
  3730.     ** Only the System Administrator (SA) or the Database Owner (dbo) can
  3731.     ** add an article to a publication.
  3732.     */
  3733.     IF suser_id() <> 1 AND user_id() <> 1
  3734.     BEGIN
  3735.             RAISERROR (15000, 14, -1)
  3736.         RETURN (1)
  3737.         END
  3738.  
  3739.     /*
  3740.     ** Parameter Check: @article.
  3741.     ** The @article name cannot be NULL and must conform to the rules
  3742.     ** for identifiers.
  3743.     */
  3744.  
  3745.     IF @article IS NULL
  3746.         BEGIN
  3747.             RAISERROR (14043, 16, -1, 'The article')
  3748.             RETURN (1)
  3749.         END
  3750.  
  3751.     EXECUTE @retcode = sp_validname @article
  3752.  
  3753.     IF @retcode <> 0
  3754.     return(1)
  3755.  
  3756.     if LOWER(@article) = 'all'
  3757.         BEGIN
  3758.             RAISERROR (14032, 16, -1, @article)
  3759.             RETURN (1)
  3760.         END
  3761.  
  3762.     /*
  3763.     ** Parameter Check: @publication.
  3764.     ** The @publication name cannot be NULL and must conform to the rules
  3765.     ** for identifiers.
  3766.     */
  3767.  
  3768.     IF @publication IS NULL
  3769.         BEGIN
  3770.             RAISERROR (14043, 16, -1, 'The publication')
  3771.             RETURN (1)
  3772.         END
  3773.  
  3774.     EXECUTE @retcode = sp_validname @publication
  3775.  
  3776.     IF @retcode <> 0
  3777.     RETURN (1)
  3778.  
  3779.     /*
  3780.     ** Parameter Check: @source_table.
  3781.     ** Check to see that the @source_table is local, that it conforms
  3782.     ** to the rules for identifiers, and that it is a table, and not
  3783.     ** a view or another database object.
  3784.     */
  3785.  
  3786.     IF @source_table IS NULL
  3787.         BEGIN
  3788.             RAISERROR (14043, 16, -1, 'The source table')
  3789.             RETURN (1)
  3790.         END
  3791.  
  3792.     EXECUTE sp_namecrack @source_table,
  3793.                          @site OUTPUT,
  3794.                          @db OUTPUT,
  3795.                          @owner OUTPUT,
  3796.                          @object OUTPUT
  3797.  
  3798.     IF @source_table LIKE '%.%.%' AND @db <> DB_NAME()
  3799.        BEGIN
  3800.           RAISERROR (14004, 16, -1, 'The source table')
  3801.       RETURN (1)
  3802.        END
  3803.  
  3804.     EXECUTE @retcode = sp_validname @object
  3805.  
  3806.     IF @retcode <> 0
  3807.     RETURN (1)
  3808.  
  3809.     /*
  3810.     **  Get the id of the @source_table
  3811.     */
  3812.  
  3813.     SELECT @tabid = id FROM sysobjects WHERE id = OBJECT_ID(@source_table)
  3814.  
  3815.     IF @tabid IS NULL
  3816.         BEGIN
  3817.             RAISERROR (14027, 11, -1, 'The source table')
  3818.             RETURN (1)
  3819.         END
  3820.  
  3821.     /*
  3822.     ** Make sure that the table name specified is a table and not a view.
  3823.     */
  3824.  
  3825.     IF NOT EXISTS (SELECT *
  3826.                      FROM sysobjects
  3827.             WHERE id = (SELECT OBJECT_ID(@source_table))
  3828.               AND type = 'U')
  3829.     BEGIN
  3830.             RAISERROR (14028, 16, -1)
  3831.             RETURN (1)
  3832.         END
  3833.  
  3834.     /*
  3835.     ** Parameter Check:  @destination_table.
  3836.     ** If the destination table is not specified, assume it's the same
  3837.     ** as the source table.  Make sure that the table name is not qualified.
  3838.     */
  3839.  
  3840.     IF @destination_table LIKE '%.%.%'
  3841.     BEGIN
  3842.             RAISERROR (14001, 16, -1)
  3843.         RETURN (1)
  3844.     END
  3845.  
  3846.     IF @destination_table LIKE '%.%'
  3847.     BEGIN
  3848.             RAISERROR (14044, 16, -1, 'destination table')
  3849.         RETURN (1)
  3850.     END
  3851.  
  3852.     IF @destination_table IS NULL
  3853.         SELECT @destination_table = @source_table
  3854.  
  3855.     EXECUTE sp_namecrack @destination_table,
  3856.                          @site OUTPUT,
  3857.                          @db OUTPUT,
  3858.                          @owner OUTPUT,
  3859.                          @object OUTPUT
  3860.  
  3861.     EXECUTE @retcode = sp_validname @object
  3862.  
  3863.     IF @retcode <> 0
  3864.     RETURN (1)
  3865.  
  3866.     /*
  3867.     ** Parameter Check: @vertical_partition
  3868.     ** Check to make sure that the vertical partition is either TRUE or FALSE.
  3869.     */
  3870.  
  3871.     SELECT @vertical_partition = LOWER(@vertical_partition)
  3872.     IF @vertical_partition NOT IN ('true', 'false')
  3873.         BEGIN
  3874.             RAISERROR (14029, 16, -1)
  3875.             RETURN (1)
  3876.         END
  3877.  
  3878.     /*
  3879.     ** Parameter Check: @filter
  3880.     ** Make sure that the filter is a valid stored procedure.
  3881.     */
  3882.     IF @filter IS NOT NULL
  3883.         BEGIN
  3884.  
  3885.             EXECUTE sp_namecrack @filter,
  3886.                                  @site OUTPUT,
  3887.                                  @db OUTPUT,
  3888.                                  @owner OUTPUT,
  3889.                                  @object OUTPUT
  3890.  
  3891.         IF @filter LIKE '%.%.%' AND @db <> DB_NAME()
  3892.                BEGIN
  3893.                   RAISERROR (14004, 16, -1, 'The filter')
  3894.           RETURN (1)
  3895.            END
  3896.  
  3897.  
  3898.             EXECUTE @retcode = sp_validname @object
  3899.  
  3900.             IF @retcode <> 0
  3901.         RETURN (1)
  3902.  
  3903.         /*
  3904.         ** Get the id of the @filter
  3905.         */
  3906.             select @filterid = id from sysobjects where
  3907.         id = OBJECT_ID(@filter) and type = 'RF'
  3908.             IF @filterid IS NULL
  3909.             BEGIN
  3910.                     RAISERROR (14027, 11, -1, 'The filter')
  3911.                     RETURN (1)
  3912.                 END
  3913.         END
  3914.     ELSE
  3915.         select @filterid = 0
  3916.  
  3917.     /*
  3918.     ** Get the pubid.
  3919.     */
  3920.  
  3921.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  3922.  
  3923.     IF @pubid IS NULL
  3924.         BEGIN
  3925.             RAISERROR (14027, 11, -1, 'The publication')
  3926.             RETURN (1)
  3927.         END
  3928.  
  3929.     /*
  3930.     ** Parameter Check:  @article, @publication.
  3931.     ** Check if the article already exists in this publication.
  3932.     */
  3933.  
  3934.     IF EXISTS (SELECT *
  3935.                  FROM sysarticles
  3936.                 WHERE pubid = @pubid
  3937.                   AND name = @article)
  3938.         BEGIN
  3939.             RAISERROR (14030, 16, -1, @article, @publication)
  3940.             RETURN (1)
  3941.         END
  3942.  
  3943.     /*
  3944.     ** Set the typeid.  The default type is logbased.  Anything else is
  3945.     ** currently undefined (reserved for future use).
  3946.     **
  3947.     **      @typeid     type
  3948.     **      =======     ========
  3949.     **            1     logbased
  3950.     **          3     logbased manualfilter
  3951.     **          5     logbased manualview
  3952.     **          7     logbased manualboth
  3953.     */
  3954.  
  3955.     IF LOWER(@type) NOT IN ('logbased', 'logbased manualfilter', 'logbased manualview', 'logbased manualboth')
  3956.        BEGIN
  3957.             RAISERROR (14023, 16, -1)
  3958.             RETURN (1)
  3959.        END
  3960.  
  3961.     IF LOWER(@type) = 'logbased'
  3962.        SELECT @typeid = 1
  3963.     ELSE IF LOWER(@type) = 'logbased manualfilter'
  3964.        SELECT @typeid = 3
  3965.     ELSE IF LOWER(@type) = 'logbased manualview'
  3966.        SELECT @typeid = 5
  3967.     ELSE IF LOWER(@type) = 'logbased manualboth'
  3968.        SELECT @typeid = 7
  3969.  
  3970.     /*
  3971.     ** Set the precmdid.  The default type is 'drop'.
  3972.     **
  3973.     **      @precmdid   pre_creation_cmd
  3974.     **      =========   ================
  3975.     **            0     none
  3976.     **          1     drop
  3977.     **          2     delete
  3978.     **          3     truncate
  3979.     */
  3980.     IF LOWER(@pre_creation_cmd) NOT IN ('none', 'drop', 'delete', 'truncate')
  3981.        BEGIN
  3982.           RAISERROR (14061, 16, -1)
  3983.           RETURN (1)
  3984.        END
  3985.  
  3986.     /*
  3987.     ** Determine the integer value for the pre_creation_cmd.
  3988.     */
  3989.     IF LOWER(@pre_creation_cmd) = 'none'
  3990.        SELECT @precmdid = 0
  3991.     ELSE IF LOWER(@pre_creation_cmd) = 'drop'
  3992.        SELECT @precmdid = 1
  3993.     ELSE IF LOWER(@pre_creation_cmd) = 'delete'
  3994.        SELECT @precmdid = 2
  3995.     ELSE IF LOWER(@pre_creation_cmd) = 'truncate'
  3996.        SELECT @precmdid = 3
  3997.  
  3998.     IF @sync_object IS NULL
  3999.         select @syncid = @tabid
  4000.     ELSE
  4001.         BEGIN
  4002.  
  4003.         /*
  4004.             ** Parameter Check: @sync_object.
  4005.         ** Check to see that the sync_object is local and that it
  4006.             ** conforms to the rules for identifiers.
  4007.         */
  4008.  
  4009.             EXECUTE sp_namecrack @sync_object,
  4010.                                  @site OUTPUT,
  4011.                                  @db OUTPUT,
  4012.                                  @owner OUTPUT,
  4013.                                  @object OUTPUT
  4014.  
  4015.         IF @sync_object LIKE '%.%.%' AND @db <> DB_NAME()
  4016.                BEGIN
  4017.                   RAISERROR (14004, 16, -1, 'The synchronization object')
  4018.           RETURN (1)
  4019.            END
  4020.  
  4021.  
  4022.             EXECUTE @retcode = sp_validname @object
  4023.  
  4024.             IF @retcode <> 0
  4025.         RETURN (1)
  4026.  
  4027.         /*
  4028.         **  Get the id of the @sync_object
  4029.         */
  4030.  
  4031.         SELECT @syncid = id FROM sysobjects WHERE id = OBJECT_ID(@sync_object)
  4032.  
  4033.         IF @syncid IS NULL
  4034.         BEGIN
  4035.                     RAISERROR (14027, 11, -1, 'The synchronization object')
  4036.             RETURN (1)
  4037.         END
  4038.  
  4039.         /*
  4040.         ** Make sure the sync object specified is a table or a view.
  4041.         */
  4042.  
  4043.         IF NOT EXISTS (SELECT * FROM sysobjects
  4044.                     WHERE id = (SELECT OBJECT_ID(@sync_object))
  4045.                     AND (type = 'U' or
  4046.                          type = 'V'))
  4047.         BEGIN
  4048.                     RAISERROR (14031, 16, -1)
  4049.             RETURN (1)
  4050.         END
  4051.     END
  4052.  
  4053.     /*
  4054.     ** Make sure there is a primary key on the source table.
  4055.     */
  4056.     IF NOT EXISTS (SELECT * FROM sysconstraints WHERE id = @tabid and
  4057.         (status & 0x1) <> 0)     /* PK status */
  4058.        BEGIN
  4059.           RAISERROR (14088, 16, -1, @source_table)
  4060.       RETURN (1)
  4061.        END
  4062.  
  4063.     /*
  4064.     **  Add article to sysarticles and update sysobjects category bit.
  4065.     */
  4066.     BEGIN TRAN sp_addarticle
  4067.         INSERT sysarticles (columns, creation_script, del_cmd, description,
  4068.                             dest_table, filter, filter_clause, ins_cmd, name,
  4069.                 objid, pre_creation_cmd, pubid,
  4070.                             status, sync_objid, type, upd_cmd)
  4071.         VALUES (0, @creation_script, @del_cmd, @description, @destination_table,
  4072.                 @filterid, @filter_clause, @ins_cmd, @article, @tabid,
  4073.         @precmdid, @pubid, 0, @syncid, @typeid, @upd_cmd)
  4074.  
  4075.         IF @@ERROR <> 0
  4076.             BEGIN
  4077.             ROLLBACK TRAN sp_addarticle
  4078.             RETURN (1)
  4079.             END
  4080.  
  4081.         UPDATE sysobjects
  4082.            SET category = category | @publish_bit
  4083.          WHERE id = (SELECT objid
  4084.                        FROM sysarticles
  4085.                       WHERE name = @article
  4086.                         AND pubid = @pubid)
  4087.  
  4088.         IF @@ERROR <> 0
  4089.             BEGIN
  4090.             ROLLBACK TRAN sp_addarticle
  4091.         RETURN (1)
  4092.         END
  4093.  
  4094.         /*
  4095.         ** Set all bits to '1' in the columns column to include all columns.
  4096.         */
  4097.  
  4098.         IF @vertical_partition = 'false'
  4099.        BEGIN
  4100.           EXECUTE @retcode  = sp_articlecolumn @publication, @article
  4101.           IF @@ERROR <> 0 OR @retcode <> 0
  4102.              BEGIN
  4103.              ROLLBACK TRAN sp_addarticle
  4104.             RETURN (1)
  4105.              END
  4106.        END
  4107.         /*
  4108.     ** Set all bits to '1' for all columns in the primary key.
  4109.     */
  4110.         ELSE
  4111.        BEGIN
  4112.         SELECT @indid = indid FROM sysindexes
  4113.             WHERE id = @tabid
  4114.             AND (status & 2048) <> 0    /* PK index */
  4115.         /*
  4116.         **  First we'll figure out what the keys are.
  4117.         */
  4118.         SELECT @i = 1
  4119.  
  4120.         WHILE (@i <= 16)
  4121.            BEGIN
  4122.               SELECT @pkkey = INDEX_COL(@source_table, @indid, @i)
  4123.               if @pkkey is NULL
  4124.                  goto DONE
  4125.  
  4126.               EXECUTE @retcode  = sp_articlecolumn @publication,
  4127.                 @article, @pkkey, 'add'
  4128.               IF @@ERROR <> 0 OR @retcode <> 0
  4129.                  BEGIN
  4130.                 ROLLBACK TRAN sp_addarticle
  4131.                 RETURN (1)
  4132.              END
  4133.  
  4134.             select @i = @i + 1
  4135.            END
  4136.        END
  4137.  
  4138. DONE:
  4139.     COMMIT TRAN sp_addarticle
  4140. go
  4141.  
  4142. print ''
  4143. print 'Creating procedure sp_addpublisher.'
  4144. go
  4145.  
  4146. CREATE PROCEDURE sp_addpublisher (
  4147.     @publisher varchar (30),      /* publisher server name */
  4148.     @type varchar (5) = NULL      /* NULL or 'dist' */
  4149.         ) AS
  4150.  
  4151.     /*
  4152.     ** Declarations.
  4153.     */
  4154.  
  4155.     DECLARE @distaccount varchar(255)
  4156.     DECLARE @proc varchar (255)
  4157.     DECLARE @retcode int
  4158.     DECLARE @privilege varchar (30)
  4159.  
  4160.     /*
  4161.     ** Parameter Check:  @publisher.
  4162.     ** Check to make sure that the publisher is not NULL and that it
  4163.     ** conforms to the rules for identifiers.
  4164.     */
  4165.  
  4166.     IF @publisher IS NULL
  4167.         BEGIN
  4168.             RAISERROR (14043, 16, -1, 'The publisher')
  4169.             RETURN (1)
  4170.         END
  4171.  
  4172.     EXECUTE @retcode = sp_validname @publisher
  4173.  
  4174.     IF @@ERROR <> 0 OR @retcode <> 0
  4175.     RETURN (1)
  4176.  
  4177.  
  4178.     /*
  4179.     ** Perform special logic if defining a publisher for a distribution
  4180.     ** server.
  4181.     */
  4182.     IF LOWER(@type) = 'dist'
  4183.     BEGIN
  4184.         /* Check if publisher is already defined. */
  4185.         IF EXISTS (SELECT *
  4186.              FROM master..sysservers
  4187.             WHERE srvname = @publisher
  4188.             AND srvstatus &  16 <> 0)
  4189.  
  4190.         BEGIN
  4191.             RAISERROR (14074, 16, -1, @publisher)
  4192.             RETURN (1)
  4193.         END
  4194.  
  4195.         IF NOT EXISTS (SELECT *
  4196.                  FROM master..sysservers
  4197.                 WHERE srvname = @publisher)
  4198.  
  4199.         /* Add the server if it does not exist. */
  4200.         BEGIN
  4201.             EXECUTE @retcode = sp_addserver @publisher
  4202.             IF @@error <> 0 OR @retcode <> 0
  4203.             BEGIN
  4204.                 RAISERROR (14075, 16, -1)
  4205.                 RETURN (1)
  4206.             END
  4207.         END
  4208.  
  4209.         /*
  4210.         ** Set the server option to indicate that this is a
  4211.         ** distribution publisher.
  4212.         */
  4213.         EXECUTE @retcode = sp_serveroption @publisher, 'dpub', true
  4214.         IF @@error <> 0 OR @retcode <> 0
  4215.         BEGIN
  4216.             RAISERROR (14075, 16, -1)
  4217.             RETURN (1)
  4218.         END
  4219.  
  4220.         /* Add remotelogin enabling the 'sa' of the publisher to
  4221.         ** RPC for distribution information.
  4222.         */
  4223.         IF EXISTS (SELECT *
  4224.                   FROM sysremotelogins srl,
  4225.                    sysservers ss
  4226.                  WHERE ss.srvname = @publisher
  4227.                AND srl.remoteserverid = ss.srvid
  4228.                AND srl.remoteusername = 'sa'
  4229.            AND suid = 16383)     /* 'repl_subscriber' */
  4230.             BEGIN
  4231.            EXECUTE @retcode = sp_dropremotelogin @publisher, repl_subscriber, sa
  4232.            IF @@error <> 0 OR @retcode <> 0
  4233.            BEGIN
  4234.             RAISERROR (14075, 16, -1)
  4235.             RETURN (1)
  4236.            END
  4237.         END
  4238.  
  4239.         EXECUTE @retcode = sp_addremotelogin @publisher, sa, sa
  4240.         IF @@error <> 0 OR @retcode <> 0
  4241.            BEGIN
  4242.               RAISERROR (14075, 16, -1)
  4243.               RETURN (1)
  4244.            END
  4245.  
  4246.         EXECUTE @retcode = sp_remoteoption @publisher, sa, sa, trusted, true
  4247.         IF @@error <> 0 OR @retcode <> 0
  4248.                BEGIN
  4249.               RAISERROR (14075, 16, -1)
  4250.               RETURN (1)
  4251.            END
  4252.  
  4253.             /* Add remotelogin enabling the 'probe' of the publisher to
  4254.         ** RPC for distribution counter information.
  4255.         */
  4256.         IF NOT EXISTS (SELECT *
  4257.                   FROM sysremotelogins srl,
  4258.                    sysservers ss
  4259.                  WHERE ss.srvname = @publisher
  4260.                AND srl.remoteserverid = ss.srvid
  4261.                AND srl.remoteusername = 'probe'
  4262.            AND srl.suid = 10)    /* 'probe' */
  4263.         BEGIN
  4264.            EXECUTE @retcode = sp_addremotelogin @publisher, probe, probe
  4265.            IF @@error <> 0 OR @retcode <> 0
  4266.            BEGIN
  4267.             RAISERROR (14075, 16, -1)
  4268.             RETURN (1)
  4269.            END
  4270.         END
  4271.  
  4272.                RETURN (0)
  4273.     END
  4274.  
  4275.     /*
  4276.     ** Check to make sure that the publisher doesn't already exist.
  4277.     */
  4278.     IF EXISTS (SELECT * FROM master..sysservers
  4279.               WHERE srvname = @publisher
  4280.                  AND srvstatus & 2 <> 0)
  4281.     BEGIN
  4282.         RAISERROR (14074, 16, -1, @publisher)
  4283.         RETURN (1)
  4284.     END
  4285.  
  4286.     /*
  4287.     ** The server may already be listed in master..sysservers, but might
  4288.     ** not be marked as a publisher yet.  If it's not in
  4289.     ** master..sysservers, let's add it first.
  4290.     */
  4291.  
  4292.     IF NOT EXISTS (SELECT *
  4293.                      FROM master..sysservers
  4294.                     WHERE srvname = @publisher)
  4295.  
  4296.         BEGIN
  4297.             EXECUTE @retcode = sp_addserver @publisher
  4298.             IF @@error <> 0 OR @retcode <> 0
  4299.                 BEGIN
  4300.                     RAISERROR (14075, 16, -1)
  4301.                     RETURN (1)
  4302.                 END
  4303.         END
  4304.  
  4305.     /*
  4306.     ** Fetch the publisher's distributor account.
  4307.     */
  4308.  
  4309.     SELECT @proc = RTRIM(@publisher) + '.master..sp_helpdistributor '
  4310.     EXECUTE @retcode = @proc @account = @distaccount OUTPUT
  4311.     IF @@error <> 0 OR @retcode <> 0 OR @distaccount IS NULL
  4312.         BEGIN
  4313.             RAISERROR (14071, 16, -1)
  4314.             RETURN (1)
  4315.         END
  4316.  
  4317.     /*
  4318.     ** Set the server option to indicate that this is a publisher.
  4319.     */
  4320.     EXECUTE @retcode = sp_serveroption @publisher, 'pub', true
  4321.     IF @@error <> 0 OR @retcode <> 0
  4322.         BEGIN
  4323.             RAISERROR (14075, 16, -1)
  4324.             RETURN (1)
  4325.         END
  4326.  
  4327.     /*
  4328.     ** If @distaccount = 'LocalSystem' assume 'admin' privilege
  4329.     */
  4330.     IF @distaccount = 'LocalSystem'
  4331.        RETURN (0)
  4332.  
  4333.     /*
  4334.     ** Check if @distaccount has admin or repl privilege already.
  4335.     */
  4336.     EXECUTE @retcode = master.dbo.xp_logininfo @distaccount, 'all',
  4337.        @privilege = @privilege output
  4338.     IF @@error <> 0 OR @retcode <> 0
  4339.         BEGIN
  4340.             RAISERROR (14076, 10, -1, @distaccount)
  4341.             RETURN (0)
  4342.         END
  4343.  
  4344.     IF @privilege = 'admin' OR @privilege = 'repl'
  4345.        RETURN  (0)
  4346.  
  4347.     /*
  4348.     ** Grant replication privilege to the distributor NT account.
  4349.     */
  4350.     EXECUTE @retcode = master.dbo.xp_grantlogin @distaccount, repl
  4351.     IF @@error <> 0 OR @retcode <> 0
  4352.         BEGIN
  4353.             RAISERROR (14076, 10, -1, @distaccount)
  4354.             RETURN (0)
  4355.         END
  4356.  
  4357. go
  4358.  
  4359. print ''
  4360. print 'Creating procedure sp_addsubscriber.'
  4361. go
  4362.  
  4363. CREATE PROCEDURE sp_addsubscriber (
  4364.     @subscriber varchar (30),
  4365.     @type tinyint = 0,
  4366.     @login varchar (30) = NULL,
  4367.     @password varchar (30) = NULL,
  4368.     @commit_batch_size int = 100,
  4369.     @status_batch_size int = 100,
  4370.     @flush_frequency int = 0,
  4371.     @frequency_type int = 4,
  4372.     @frequency_interval int = 1,
  4373.     @frequency_relative_interval int = 1,
  4374.     @frequency_recurrence_factor int = 0,
  4375.     @frequency_subday int = 4,
  4376.     @frequency_subday_interval int = 5,
  4377.     @active_start_time_of_day int = 0,
  4378.     @active_end_time_of_day int = 235959,
  4379.     @active_start_date int = 0,
  4380.     @active_end_date int = 99991231,
  4381.     @description varchar (255) = NULL
  4382.         ) AS
  4383.  
  4384.     DECLARE @distributor varchar(30)
  4385.     DECLARE @distribdb varchar(30)
  4386.     DECLARE @distproc varchar (255)
  4387.     DECLARE @retcode int
  4388.     DECLARE @dsn_subscriber tinyint
  4389.  
  4390.     select @dsn_subscriber = 1    /* Const: subscriber type 'dsn' */    
  4391.  
  4392.     /*
  4393.     ** Parameter Check:  @subscriber.
  4394.     ** Check to make sure that the subscriber doesn't already exist, and
  4395.     ** that the name is a valid non-null identifier.
  4396.     */
  4397.  
  4398.     IF @subscriber IS NULL
  4399.         BEGIN
  4400.             RAISERROR (14043, 16, -1, 'The subscriber')
  4401.             RETURN (1)
  4402.         END
  4403.  
  4404.     EXECUTE @retcode = sp_validname @subscriber
  4405.  
  4406.     IF @@ERROR <> 0 OR @retcode <> 0
  4407.     RETURN (1)
  4408.  
  4409.     if LOWER(@subscriber) = 'all'
  4410.         BEGIN
  4411.             RAISERROR (14032, 16, -1, @subscriber)
  4412.             RETURN (1)
  4413.         END
  4414.  
  4415.     IF EXISTS (SELECT *
  4416.                  FROM master..sysservers
  4417.                 WHERE srvname = @subscriber
  4418.                   AND srvstatus & 4 <> 0)
  4419.  
  4420.         BEGIN
  4421.         RAISERROR (14040, 16, -1, @subscriber)
  4422.             RETURN (1)
  4423.         END
  4424.  
  4425.  
  4426.     /*
  4427.     **  If no MSsubscriber_info parameters skip RPC code.
  4428.     */
  4429.  
  4430.     IF @frequency_type = -1
  4431.         GOTO ADDSUB
  4432.  
  4433.     /*
  4434.     ** Get distribution server information for remote RPC
  4435.     ** subscription calls.
  4436.     */
  4437.  
  4438.     EXEC @retcode = sp_helpdistributor @distributor = @distributor OUTPUT,
  4439.                                        @distribdb   = @distribdb   OUTPUT
  4440.  
  4441.     IF @@error <> 0
  4442.         BEGIN
  4443.          RAISERROR (14071, 16, -1)
  4444.              RETURN (1)
  4445.      END
  4446.  
  4447.     IF @retcode <> 0 OR @distribdb IS NULL OR @distributor IS NULL
  4448.         BEGIN
  4449.             RAISERROR (14071, 16, -1)
  4450.             RETURN (1)
  4451.         END
  4452.  
  4453.     /*
  4454.     ** Add subscriber to distribution sysservers, if distribution
  4455.     ** server is remote.
  4456.     */
  4457.  
  4458.     If @distributor <> @@SERVERNAME
  4459.         BEGIN
  4460.  
  4461.         SELECT @distproc = RTRIM(@distributor) + '.master..sp_addserver '
  4462.         EXEC @distproc @server = @subscriber, @duplicate_ok = 'duplicate_ok'
  4463.  
  4464.         /*
  4465.         ** Assume distributor already existed if execute failed. Check
  4466.         ** @@error for non-procedure errors.
  4467.         */
  4468.         IF @@error <> 0
  4469.                 BEGIN
  4470.                 RAISERROR (14042, 16, -1)
  4471.                 RETURN (1)
  4472.             END
  4473.     END
  4474.  
  4475.     /*
  4476.     ** Insert information into MSsubscriber_info
  4477.     */
  4478.     SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '..sp_MSadd_subscriber_info '
  4479.     EXEC @retcode = @distproc
  4480.          @@SERVERNAME,
  4481.          @subscriber,
  4482.      @type,
  4483.      @login,
  4484.      @password,
  4485.      @commit_batch_size,
  4486.      @status_batch_size,
  4487.      @flush_frequency,
  4488.      @frequency_type,
  4489.      @frequency_interval,
  4490.      @frequency_relative_interval,
  4491.      @frequency_recurrence_factor,
  4492.      @frequency_subday,
  4493.      @frequency_subday_interval,
  4494.      @active_start_time_of_day,
  4495.      @active_end_time_of_day,
  4496.      @active_start_date,
  4497.      @active_end_date,
  4498.      @description = @description
  4499.  
  4500.     IF @@error <> 0 OR @retcode <> 0
  4501.         BEGIN
  4502.         RAISERROR (14042, 16, -1)
  4503.         RETURN (1)
  4504.     END
  4505.  
  4506. ADDSUB:
  4507.  
  4508.     /*
  4509.     ** The server may already be listed in master..sysservers, but might
  4510.     ** not be marked as a subscriber yet.  If it's not in
  4511.     ** master..sysservers, let's add it first.
  4512.     */
  4513.  
  4514.     IF NOT EXISTS (SELECT *
  4515.                          FROM master..sysservers
  4516.                         WHERE srvname = @subscriber)
  4517.  
  4518.     EXECUTE @retcode = sp_addserver @subscriber
  4519.  
  4520.         IF @@error <> 0 OR @retcode <> 0
  4521.             BEGIN
  4522.             RAISERROR (14042, 16, -1)
  4523.                 RETURN (1)
  4524.             END
  4525.  
  4526.     /*
  4527.     ** Set the server option to indicate this is a subscriber.
  4528.     */
  4529.  
  4530.     EXECUTE @retcode = sp_serveroption @subscriber, 'sub', true
  4531.  
  4532.     IF @@error <> 0 OR @retcode <> 0
  4533.         BEGIN
  4534.        RAISERROR (14042, 16, -1)
  4535.            RETURN (1)
  4536.         END
  4537.  
  4538.     /*
  4539.     ** Set the server option to indicate this is a DSN subscriber.
  4540.     */
  4541.     if @type = @dsn_subscriber
  4542.        BEGIN
  4543.           EXECUTE @retcode = sp_serveroption @subscriber, 'dsn', true
  4544.           IF @@error <> 0 OR @retcode <> 0
  4545.              BEGIN
  4546.              RAISERROR (14042, 16, -1)
  4547.                  RETURN (1)
  4548.              END
  4549.        END
  4550.  
  4551.      /*
  4552.      ** Setup remotelogin for subscribing server 'sa' account, if
  4553.      ** one does not already exist.
  4554.      **/
  4555.  
  4556.      IF EXISTS (SELECT *
  4557.                   FROM sysremotelogins srl,
  4558.                    sysservers ss
  4559.                  WHERE ss.srvname = @subscriber
  4560.                AND srl.remoteserverid = ss.srvid
  4561.                AND (srl.remoteusername = 'sa'
  4562.                 OR (srl.remoteusername IS NULL AND srl.suid = -1)))
  4563.      BEGIN
  4564.                 RETURN (0)
  4565.      END
  4566.  
  4567.      EXECUTE @retcode = sp_addremotelogin @subscriber, repl_subscriber, sa
  4568.  
  4569.      IF @@error <> 0 OR @retcode <> 0
  4570.         BEGIN
  4571.         RAISERROR (14042, 16, -1)
  4572.         RETURN (1)
  4573.     END
  4574.  
  4575.     EXECUTE @retcode = sp_remoteoption @subscriber, repl_subscriber, sa, trusted, true
  4576.  
  4577.     IF @@error <> 0 OR @retcode <> 0
  4578.         BEGIN
  4579.             RAISERROR (14042, 16, -1)
  4580.             RETURN (1)
  4581.         END
  4582. go
  4583.  
  4584. /*
  4585. ** Create replication stored procedures.
  4586. ** Part 1:  create codependent procedures.
  4587. */
  4588.  
  4589. print ''
  4590. print 'Creating procedure sp_hcchangesubstatus1.'
  4591. go
  4592. CREATE PROCEDURE sp_hcchangesubstatus1
  4593.         @publication varchar(30) = '%',
  4594.         @article varchar(30) = '%',
  4595.         @subscriber varchar(30) = '%'
  4596.         AS
  4597.  
  4598.     DECLARE hCsubstatus CURSOR FOR
  4599.         SELECT sub.artid,
  4600.                art.objid,
  4601.                sub.srvid,
  4602.                ss.srvname,
  4603.                sub.dest_db,
  4604.                sub.status,
  4605.            ss.srvstatus,
  4606.            pub.repl_freq
  4607.           FROM syssubscriptions sub,
  4608.                sysarticles art,
  4609.                syspublications pub,
  4610.                sysservers ss
  4611.          WHERE pub.name LIKE @publication
  4612.            AND art.name LIKE @article
  4613.            AND ss.srvname LIKE @subscriber
  4614.            AND sub.srvid = ss.srvid
  4615.            AND sub.artid = art.artid
  4616.            AND art.pubid = pub.pubid
  4617.      FOR READ ONLY
  4618.  
  4619. go
  4620.  
  4621. print ''
  4622. print 'Creating procedure sp_hcchangesubstatus2.'
  4623. go
  4624. CREATE PROCEDURE sp_hcchangesubstatus2
  4625.         @publication varchar(30) = '%',
  4626.         @article varchar(30) = '%',
  4627.         @subscriber varchar(30) = '%',
  4628.         @previous_status varchar(30),
  4629.         @prevstatid tinyint
  4630.         AS
  4631.  
  4632.     DECLARE hCsubstatus CURSOR FOR
  4633.         SELECT sub.artid,
  4634.                art.objid,
  4635.                sub.srvid,
  4636.                ss.srvname,
  4637.                sub.dest_db,
  4638.                sub.status,
  4639.            ss.srvstatus,
  4640.            pub.repl_freq
  4641.           FROM syssubscriptions sub,
  4642.                sysarticles art,
  4643.                syspublications pub,
  4644.                sysservers ss
  4645.          WHERE pub.name LIKE @publication
  4646.            AND art.name LIKE @article
  4647.            AND ss.srvname LIKE @subscriber
  4648.            AND sub.srvid = ss.srvid
  4649.            AND sub.artid = art.artid
  4650.            AND art.pubid = pub.pubid
  4651.             AND sub.status = @prevstatid
  4652.      FOR READ ONLY
  4653. go
  4654.  
  4655. print ''
  4656. print 'Creating procedure sp_changesubstatus.'
  4657. go
  4658.  
  4659. CREATE PROCEDURE sp_changesubstatus (
  4660.     @publication varchar (30) = '%',    /* publication name */
  4661.     @article varchar (30) = '%',        /* article name */
  4662.     @subscriber varchar(30) = '%',      /* subscriber name */
  4663.     @status varchar(30),                /* subscription status */
  4664.     @previous_status varchar(30)=NULL   /* previous subscription status */
  4665.     ) AS
  4666.  
  4667.     SET NOCOUNT ON
  4668.  
  4669.     DECLARE @inactive tinyint
  4670.     DECLARE @subscribed tinyint
  4671.     DECLARE @active tinyint
  4672.     DECLARE @public tinyint
  4673.     DECLARE @replicate_bit smallint
  4674.     DECLARE @subscriber_bit smallint
  4675.     DECLARE @msg varchar(255)
  4676.     DECLARE @prevstatid tinyint
  4677.     DECLARE @artid int
  4678.     DECLARE @tabid int
  4679.     DECLARE @srvid smallint
  4680.     DECLARE @statusid tinyint
  4681.     DECLARE @distributor varchar(30)
  4682.     DECLARE @distribdb varchar(30)
  4683.     DECLARE @distproc varchar (255)
  4684.     DECLARE @pub_db varchar(30)
  4685.     DECLARE @dest_db varchar (30)
  4686.     DECLARE @sub_name varchar (30)
  4687.     DECLARE @sub_status tinyint
  4688.     DECLARE @sub_ts binary (8)
  4689.     DECLARE @sub_type smallint
  4690.     DECLARE @cmd0 varchar (255)
  4691.     DECLARE @cmd1 varchar (255)
  4692.     DECLARE @cmd2 varchar (255)
  4693.     DECLARE @cmd3 varchar (255)
  4694.     DECLARE @retcode int
  4695.     DECLARE @dsn_bit smallint
  4696.     DECLARE @repl_freq tinyint
  4697.  
  4698.     /*
  4699.     ** Initializations.
  4700.     */
  4701.  
  4702.     SELECT @inactive = 0        /* Const: subscription status 'inactive' */
  4703.     SELECT @subscribed = 1      /* Const: subscription status 'subscribed' */
  4704.     SELECT @active = 2          /* Const: subscription status 'active' */
  4705.     SELECT @public = 0          /* Const: publication status 'public' */
  4706.     SELECT @replicate_bit = 64  /* Const: replication bit in sysobjects=0x40 */
  4707.     SELECT @subscriber_bit = 4  /* Const: subscription server status */
  4708.     SELECT @pub_db = DB_NAME()
  4709.     SELECT @dsn_bit = 32
  4710.  
  4711.     /*
  4712.     ** Parameter Check:  @publication
  4713.     ** Check to make sure that the publication exists, that it's not NULL,
  4714.     ** and that it conforms to the rules for identifiers.
  4715.     */
  4716.  
  4717.     IF @publication IS NULL
  4718.         BEGIN
  4719.             RAISERROR (14043, 16, -1, 'The publication')
  4720.             RETURN (1)
  4721.         END
  4722.  
  4723.     IF @publication <> '%'
  4724.         BEGIN
  4725.             EXECUTE @retcode = sp_validname @publication
  4726.             IF @@ERROR <> 0 OR @retcode <> 0
  4727.         RETURN (1)
  4728.         END
  4729.  
  4730.     IF NOT EXISTS (SELECT * FROM syspublications WHERE name LIKE @publication)
  4731.         BEGIN
  4732.         IF @publication = '%'
  4733.                 RAISERROR (14008, 11, -1)
  4734.         ELSE
  4735.                 RAISERROR (15001, 11, -1, @publication)
  4736.         RETURN (1)
  4737.         END
  4738.  
  4739.     /*
  4740.     ** Parameter Check:  @article
  4741.     ** Check to make sure that the article exists, that it's not null,
  4742.     ** and that it conforms to the rules for identifiers.
  4743.     */
  4744.  
  4745.     IF @article IS NULL
  4746.         BEGIN
  4747.             RAISERROR (14043, 16, -1, 'The article')
  4748.             RETURN (1)
  4749.         END
  4750.  
  4751.     IF @article <> '%'
  4752.         BEGIN
  4753.             EXECUTE @retcode = sp_validname @article
  4754.             IF @@ERROR <> 0 OR @retcode <> 0
  4755.         RETURN (1)
  4756.         END
  4757.  
  4758.     IF NOT EXISTS (SELECT *
  4759.                      FROM sysarticles a,
  4760.                           syspublications b
  4761.                 WHERE a.name LIKE @article
  4762.                       AND a.pubid = b.pubid
  4763.                       AND b.name LIKE @publication)
  4764.  
  4765.         BEGIN
  4766.         IF @article = '%'
  4767.                 RAISERROR (14009, 11, -1, @publication)
  4768.         ELSE
  4769.                 RAISERROR (15001, 11, -1, @article)
  4770.         RETURN (1)
  4771.         END
  4772.  
  4773.     /*
  4774.     ** Parameter Check:  @subscriber
  4775.     ** Check to make sure that the subscriber exists, that it is not NULL,
  4776.     ** and that it conforms to the rules for identifiers.
  4777.     */
  4778.  
  4779.     IF @subscriber IS NULL
  4780.         BEGIN
  4781.             RAISERROR (14043, 16, -1, 'The subscriber')
  4782.             RETURN (1)
  4783.         END
  4784.  
  4785.     IF @subscriber <> '%'
  4786.         BEGIN
  4787.             EXECUTE @retcode = sp_validname @subscriber
  4788.             IF @@ERROR <> 0 OR @retcode <> 0
  4789.         RETURN (1)
  4790.         END
  4791.  
  4792.     IF NOT EXISTS (SELECT *
  4793.                      FROM master..sysservers
  4794.                     WHERE srvname LIKE @subscriber
  4795.                       AND (srvstatus & 4) <> 0)
  4796.  
  4797.         BEGIN
  4798.             IF @subscriber ='%'
  4799.                 RAISERROR (14064, 11, -1)
  4800.         ELSE
  4801.                 RAISERROR (14063, 11, -1)
  4802.             RETURN (1)
  4803.         END
  4804.  
  4805.     /*
  4806.     ** Parameter Check: @status.
  4807.     ** Set the @statusid according to the @status value.  Values can be
  4808.     ** any of the following:
  4809.     **
  4810.     **      status      statusid
  4811.     **      =========   ========
  4812.     **      inactive           0
  4813.     **      subscribed         1
  4814.     **      active             2
  4815.     */
  4816.  
  4817.     IF LOWER(@status) NOT IN ('active', 'subscribed', 'inactive')
  4818.         BEGIN
  4819.             RAISERROR (14065, 16, -1)
  4820.         RETURN (1)
  4821.         END
  4822.  
  4823.     IF LOWER(@status) IN ('active')
  4824.         SELECT @statusid = @active
  4825.     ELSE IF LOWER(@status) IN ('subscribed')
  4826.         SELECT @statusid = @subscribed
  4827.     ELSE
  4828.         SELECT @statusid = @inactive
  4829.  
  4830.     /*
  4831.     ** Parameter Check: @previous_status.
  4832.     ** Set the @prevstatid according to the @previous_status value.
  4833.     ** Values can be any of the following:
  4834.     **
  4835.     **      previous_status      prevstatid
  4836.     **      ===============      ==========
  4837.     **      inactive                      0
  4838.     **      subscribed                    1
  4839.     **      active                        2
  4840.     */
  4841.  
  4842.     IF @previous_status IS NOT NULL
  4843.         BEGIN
  4844.             IF LOWER(@previous_status) NOT IN ('active', 'subscribed', 'inactive')
  4845.                 BEGIN
  4846.                     RAISERROR (14066, 16, -1)
  4847.                 RETURN (1)
  4848.                 END
  4849.  
  4850.             IF LOWER(@status) = LOWER(@previous_status)
  4851.                 BEGIN
  4852.                     RAISERROR (14067, 16, -1)
  4853.                 RETURN (1)
  4854.                 END
  4855.  
  4856.             IF LOWER(@previous_status) IN ('active')
  4857.                 SELECT @prevstatid = @active
  4858.             ELSE IF LOWER(@previous_status) IN ('subscribed')
  4859.                 SELECT @prevstatid = @subscribed
  4860.             ELSE
  4861.                SELECT @prevstatid = @inactive
  4862.         END
  4863.  
  4864.     /*
  4865.     ** Get distribution server information for remote RPC
  4866.     ** subscription calls.
  4867.     */
  4868.  
  4869.     EXEC @retcode = sp_helpdistributor @distributor = @distributor OUTPUT,
  4870.                                        @distribdb = @distribdb OUTPUT
  4871.  
  4872.     IF @@ERROR <> 0
  4873.         BEGIN
  4874.             RAISERROR (14071, 16, -1)
  4875.             RETURN (1)
  4876.      END
  4877.  
  4878.     IF @retcode <> 0 OR @distribdb IS NULL OR @distributor IS NULL
  4879.         BEGIN
  4880.             RAISERROR (14071, 16, -1)
  4881.             RETURN (1)
  4882.         END
  4883.  
  4884.     BEGIN TRANSACTION changesubstatus
  4885.  
  4886.         /*
  4887.         ** Declare cursor containing subscriptions to be updated.
  4888.         */
  4889.  
  4890.         IF @previous_status IS NOT NULL
  4891.             EXECUTE sp_hcchangesubstatus2 @publication, @article, @subscriber, @previous_status, @prevstatid
  4892.         ELSE
  4893.             EXECUTE sp_hcchangesubstatus1 @publication, @article, @subscriber
  4894.  
  4895.         OPEN hCsubstatus
  4896.  
  4897.         FETCH hCsubstatus INTO @artid, @tabid, @srvid, @sub_name, @dest_db,
  4898.        @sub_status, @sub_type, @repl_freq
  4899.  
  4900.         WHILE (@@fetch_status <> -1)
  4901.             BEGIN
  4902.             /*
  4903.             ** If current status is same as new status, do nothing.
  4904.             */
  4905.  
  4906.             IF @sub_status = @statusid
  4907.                 BEGIN
  4908.                     FETCH hCsubstatus INTO @artid, @tabid, @srvid, @sub_name,
  4909.                @dest_db, @sub_status, @sub_type, @repl_freq
  4910.                 CONTINUE
  4911.                 END
  4912.  
  4913.         /*
  4914.         ** Update syssubscription status
  4915.         */
  4916.             UPDATE syssubscriptions
  4917.                    SET status = @statusid
  4918.                    FROM syssubscriptions sub,
  4919.                        sysarticles art,
  4920.                        syspublications pub
  4921.                    WHERE pub.name LIKE @publication
  4922.                         AND art.artid = @artid
  4923.                         AND sub.srvid = @srvid
  4924.                         AND sub.artid = @artid
  4925.                         AND art.pubid = pub.pubid
  4926.         if @@ERROR <> 0
  4927.                        BEGIN
  4928.                        CLOSE hCsubstatus
  4929.                        DEALLOCATE hsubstatus
  4930.                        ROLLBACK TRANSACTION changesubstatus
  4931.                         RAISERROR (14053, 16, -1)
  4932.                            RETURN (1)
  4933.                        END
  4934.  
  4935.         /*
  4936.         ** Get timestamp of subscription.
  4937.         */
  4938.         SELECT @sub_ts = timestamp FROM
  4939.                syssubscriptions sub,
  4940.                        sysarticles art,
  4941.                        syspublications pub
  4942.                    WHERE pub.name LIKE @publication
  4943.                         AND art.artid = @artid
  4944.                         AND sub.srvid = @srvid
  4945.                         AND sub.artid = @artid
  4946.                         AND art.pubid = pub.pubid
  4947.         IF @sub_ts IS NULL
  4948.                     BEGIN
  4949.                        CLOSE hCsubstatus
  4950.                        DEALLOCATE hCsubstatus
  4951.                        ROLLBACK TRANSACTION changesubstatus
  4952.                         RAISERROR (14053, 16, -1)
  4953.                            RETURN (1)
  4954.                        END
  4955.  
  4956.             /*
  4957.             ** If activating subscription, update sysarticles, sysobjects and
  4958.             ** MSjob_subscriptions.
  4959.             */
  4960.                 IF @statusid = @active
  4961.                     BEGIN
  4962.  
  4963.                     /*
  4964.                     ** Update status of article to show it has been activated.
  4965.                     */
  4966.                     UPDATE sysarticles SET status = status | 1 WHERE artid = @artid
  4967.                     IF @@ERROR <> 0
  4968.                         BEGIN
  4969.                         CLOSE hCsubstatus
  4970.                         DEALLOCATE hCsubstatus
  4971.                         ROLLBACK TRANSACTION changesubstatus
  4972.                                 RAISERROR (14069, 16, -1)
  4973.                             RETURN (1)
  4974.                         END
  4975.  
  4976.                         /*
  4977.                         ** Turn the replication flag on for this object in the
  4978.                         ** sysobjects table (make it logbased).
  4979.                         */
  4980.  
  4981.                     if @repl_freq = 0
  4982.                       BEGIN
  4983.                         UPDATE sysobjects
  4984.                                SET category = category | @replicate_bit
  4985.                          WHERE id = (SELECT objid
  4986.                                            FROM sysarticles
  4987.                                           WHERE artid = @artid)
  4988.                       END
  4989.  
  4990.                         IF @@ERROR <> 0
  4991.                             BEGIN
  4992.                             CLOSE hCsubstatus
  4993.                             DEALLOCATE hCsubstatus
  4994.                             ROLLBACK TRANSACTION changesubstatus
  4995.                                     RAISERROR (14068, 16, -1)
  4996.                                 RETURN (1)
  4997.                             END
  4998.  
  4999.                     END
  5000.  
  5001.         /*
  5002.         ** Update status of all Text\Image columns if
  5003.         ** subscriber is non-SQL Server.
  5004.         */
  5005.         IF (@sub_type & @dsn_bit) <> 0
  5006.            BEGIN
  5007.                       IF @statusid = @subscribed OR @statusid = @active
  5008.                 BEGIN
  5009.                  EXEC @retcode = sp_articletextcol @artid, NULL,
  5010.                 'nonsqlsub', 'add'
  5011.                          IF @@ERROR <> 0 OR @retcode <> 0
  5012.                             BEGIN
  5013.                            CLOSE hCsubstatus
  5014.                            DEALLOCATE hCsubstatus
  5015.                            ROLLBACK TRANSACTION changesubstatus
  5016.                                    RAISERROR (14068, 16, -1)
  5017.                                RETURN (1)
  5018.                             END
  5019.                 END
  5020.              ELSE IF @statusid = @inactive
  5021.                 BEGIN
  5022.                  EXEC @retcode = sp_articletextcol @artid, NULL,
  5023.                 'nonsqlsub', 'drop'
  5024.                  IF @@ERROR <> 0 OR @retcode <> 0
  5025.                 BEGIN
  5026.                    CLOSE hCsubstatus
  5027.                    DEALLOCATE hCsubstatus
  5028.                    ROLLBACK TRANSACTION changesubstatus
  5029.                    RAISERROR (14068, 16, -1)
  5030.                    RETURN (1)
  5031.                 END
  5032.                 END
  5033.            END
  5034.  
  5035.                    /*
  5036.             ** If deactivating subscription, update sysarticles, sysobjects and
  5037.             ** MSjob_subscriptions.
  5038.             */
  5039.  
  5040.                 IF @statusid <> @active AND @sub_status = @active
  5041.                     BEGIN
  5042.                 /*
  5043.             ** Set the article status to 'inactive' if there are
  5044.             ** no other active subscriptions on it.
  5045.             */
  5046.             IF NOT EXISTS (SELECT * FROM syssubscriptions WHERE
  5047.                artid = @artid AND status = @active)
  5048.                BEGIN
  5049.                               UPDATE sysarticles SET status = status & ~1 WHERE
  5050.                      artid = @artid
  5051.                               IF @@ERROR <> 0
  5052.                                   BEGIN
  5053.                              CLOSE hCsubstatus
  5054.                              DEALLOCATE hCsubstatus
  5055.                              ROLLBACK TRANSACTION changesubstatus
  5056.                                      RAISERROR (14069, 16, -1)
  5057.                                      RETURN (1)
  5058.                               END
  5059.                END
  5060.  
  5061.                 /*
  5062.             ** Set the object replication bits  to 'inactive' if
  5063.             ** there are no other active subscriptions on the
  5064.             ** table.
  5065.             */
  5066.             IF NOT EXISTS (SELECT * FROM syssubscriptions WHERE
  5067.                artid IN (SELECT sa.artid FROM sysarticles sa, syspublications sp WHERE
  5068.                 sa.objid = @tabid and sa.pubid = sp.pubid and sp.repl_freq = 0) AND status = @active)
  5069.                BEGIN
  5070.                           UPDATE sysobjects
  5071.                                  SET category = category & ~@replicate_bit
  5072.                                  WHERE id = (SELECT objid
  5073.                                       FROM sysarticles WHERE artid= @artid)
  5074.                    IF @@ERROR <> 0
  5075.                       BEGIN
  5076.                              CLOSE hCsubstatus
  5077.                              DEALLOCATE hCsubstatus
  5078.                      ROLLBACK TRANSACTION changesubstatus
  5079.                      RAISERROR (14068, 16, -1)
  5080.                      RETURN (1)
  5081.                   END
  5082.                END
  5083.  
  5084.                     END
  5085.  
  5086.                 /*
  5087.                 ** Add the active subscription to the distributor's
  5088.                 ** subscriptions table if changing status from @inactive
  5089.                 */
  5090.                 IF @sub_status = @inactive
  5091.                     BEGIN
  5092.                     SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '..sp_MSadd_subscription '
  5093.                     EXEC @retcode = @distproc @@SERVERNAME, @pub_db, @sub_name, @artid, @dest_db, @statusid, @sub_ts
  5094.                     IF @@ERROR <> 0 OR @retcode <> 0
  5095.                         BEGIN
  5096.                                CLOSE hCsubstatus
  5097.                                DEALLOCATE hCsubstatus
  5098.                         ROLLBACK TRANSACTION changesubstatus
  5099.                                 RAISERROR (14070, 16, -1)
  5100.                         RETURN (1)
  5101.                         END
  5102.                     END
  5103.         ELSE
  5104.             BEGIN
  5105.                /*
  5106.                ** Drop the deactivated subscription from the distributor's
  5107.                ** subscriptions table.
  5108.                */
  5109.                        IF @statusid = @inactive
  5110.                           BEGIN
  5111.                          SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '..sp_MSdrop_subscription '
  5112.                          EXEC @retcode = @distproc @@SERVERNAME, @pub_db, @sub_name,  @artid, @dest_db
  5113.                          IF @@ERROR <> 0 OR @retcode <> 0
  5114.                             BEGIN
  5115.                            CLOSE hCsubstatus
  5116.                                   DEALLOCATE hCsubstatus
  5117.                            ROLLBACK TRANSACTION changesubstatus
  5118.                                    RAISERROR (14070, 16, -1)
  5119.                            RETURN (1)
  5120.                             END
  5121.               END
  5122.                        /*
  5123.                        ** Update subscription status and timestamp in distributor's
  5124.                        ** subscriptions table.
  5125.                        */
  5126.                 ELSE
  5127.                   BEGIN
  5128.                                SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '..sp_MSupdate_subscription '
  5129.                              EXEC @retcode = @distproc @@SERVERNAME, @pub_db, @sub_name, @artid, @statusid, @sub_ts
  5130.                              IF @@ERROR <> 0 OR @retcode <> 0
  5131.                                 BEGIN
  5132.                            CLOSE hCsubstatus
  5133.                            DEALLOCATE hCsubstatus
  5134.                                ROLLBACK TRANSACTION changesubstatus
  5135.                                    RAISERROR (14070, 16, -1)
  5136.                                RETURN (1)
  5137.                                END
  5138.                   END
  5139.             END
  5140.  
  5141.             /*
  5142.         ** Set internal object replication bit  to 'inactive' if
  5143.         ** there are no other active subscriptions on the
  5144.         ** table.
  5145.         */
  5146.         IF @statusid = @inactive AND @sub_status = @active AND
  5147.            NOT EXISTS (SELECT * FROM syssubscriptions WHERE
  5148.               artid IN (SELECT artid FROM sysarticles WHERE
  5149.               objid = @tabid) AND status = @active)
  5150.            BEGIN
  5151.                       /* Turn off object replication */
  5152.                       SELECT @cmd1 = 'exec sp_replstatus ' + CONVERT(varchar(10), @tabid) + ', 0'
  5153.                       EXEC (@cmd1)
  5154.                    END
  5155.  
  5156.                 /* Turn on object replication */
  5157.             IF @statusid = @active
  5158.            BEGIN
  5159.                      SELECT @cmd1 = 'exec sp_replstatus ' + CONVERT(varchar(10), @tabid) + ', 1'
  5160.                      EXEC (@cmd1)
  5161.            END
  5162.  
  5163.                 /*
  5164.                 ** Get next row.
  5165.                 */
  5166.                 FETCH hCsubstatus INTO @artid, @tabid, @srvid, @sub_name, @dest_db,
  5167.            @sub_status, @sub_type, @repl_freq
  5168.  
  5169.             END
  5170.  
  5171.         CLOSE hCsubstatus
  5172.         DEALLOCATE hCsubstatus
  5173.  
  5174.     /*
  5175.     ** Force the article cache to be refreshed.
  5176.     */
  5177.     EXECUTE sp_replflush
  5178.     COMMIT TRANSACTION changesubstatus
  5179. go
  5180.  
  5181. print ''
  5182. print 'Creating procedure sp_addsubscription.'
  5183. go
  5184.  
  5185. CREATE PROCEDURE sp_addsubscription (
  5186.     @publication varchar (30),        /* publication name */
  5187.     @article varchar (30) = 'all',        /* article name */
  5188.     @subscriber varchar(30),        /* subscriber name */
  5189.     @destination_db varchar (30) = NULL,    /* destination database */
  5190.     @sync_type varchar (15) = 'automatic',    /* subscription sync type */
  5191.     @status varchar(30) = NULL              /* subscription status */
  5192.     ) AS
  5193.  
  5194.     SET NOCOUNT ON
  5195.  
  5196.     /*
  5197.     ** Declarations.
  5198.     */
  5199.  
  5200.     DECLARE @artid int
  5201.     DECLARE @pre_creation_cmd tinyint
  5202.     DECLARE @none tinyint
  5203.     DECLARE @automatic tinyint
  5204.     DECLARE @cmd varchar(255)
  5205.     DECLARE @cmd2 varchar(255)
  5206.     DECLARE @inactive tinyint
  5207.     DECLARE @manual tinyint
  5208.     DECLARE @pubid int
  5209.     DECLARE @retcode int
  5210.     DECLARE @srvid smallint
  5211.     DECLARE @srvstatus smallint
  5212.     DECLARE @subscriber_bit smallint
  5213.     DECLARE @sync_typeid tinyint
  5214.     DECLARE @dsn_bit smallint
  5215.     DECLARE @truncate tinyint
  5216.     DECLARE @sync_method tinyint
  5217.     DECLARE @char_bcp tinyint
  5218.  
  5219.     /*
  5220.     ** Initializations.
  5221.     */
  5222.  
  5223.     SELECT @none = 2            /* Const: synchronization type 'none' */
  5224.     SELECT @automatic = 1       /* Const: synchronization type 'automatic' */
  5225.     SELECT @manual = 0          /* Const: synchronization type 'manual' */
  5226.     SELECT @inactive = 0        /* Const: subscription status 'inactive' */
  5227.     SELECT @subscriber_bit = 4  /* Const: subscription server status */
  5228.     SELECT @dsn_bit = 32      /* Const: ODBC DSN server status */
  5229.     SELECT @truncate = 3    /* Const: truncate pre-creation command */
  5230.     SELECT @char_bcp = 1    /* Const: character bcp sync method */
  5231.  
  5232.     /*
  5233.     ** Security Check.
  5234.     ** Only the System Administrator (SA) or the Database Owner (dbo) can
  5235.     ** add an article to a publication.
  5236.     */
  5237.  
  5238.     IF suser_id() <> 1 AND user_id() <> 1
  5239.     BEGIN
  5240.             RAISERROR (15000, 14, -1)
  5241.         RETURN (1)
  5242.         END
  5243.  
  5244.     /*
  5245.     ** Parameter Check: @subscriber.
  5246.     ** Check if the server exists and that it is a subscription server.
  5247.     */
  5248.  
  5249.     IF @subscriber IS NULL
  5250.         BEGIN
  5251.             RAISERROR (14043, 16, -1, 'The subscriber')
  5252.             RETURN (1)
  5253.         END
  5254.  
  5255.     EXECUTE @retcode = sp_validname @subscriber
  5256.  
  5257.     IF @retcode <> 0
  5258.     RETURN (1)
  5259.  
  5260.     SELECT @srvid = srvid, @srvstatus = srvstatus
  5261.       FROM master..sysservers
  5262.      WHERE srvname = @subscriber
  5263.        AND (srvstatus & @subscriber_bit) <> 0
  5264.  
  5265.     IF @srvid IS NULL
  5266.         BEGIN
  5267.             RAISERROR (14010, 16, -1)
  5268.            RETURN (1)
  5269.         END
  5270.  
  5271.     /*
  5272.     ** Parameter Check: @publication.
  5273.     ** Check to make sure that the publication exists and that it conforms
  5274.     ** to the rules for identifiers.
  5275.     */
  5276.  
  5277.     IF @publication IS NOT NULL
  5278.         BEGIN
  5279.  
  5280.             EXECUTE @retcode = sp_validname @publication
  5281.  
  5282.             IF @retcode <> 0
  5283.         RETURN (1)
  5284.  
  5285.             IF NOT EXISTS (SELECT * FROM syspublications WHERE name = @publication)
  5286.                 BEGIN
  5287.                     RAISERROR (15001, 11, -1, @publication)
  5288.                     RETURN (1)
  5289.                 END
  5290.  
  5291.         END
  5292.  
  5293.     SELECT @pubid = pubid, @sync_method = sync_method
  5294.        FROM syspublications WHERE name = @publication
  5295.  
  5296.     IF @pubid IS NULL
  5297.         BEGIN
  5298.             RAISERROR (14043, 16, -1, 'The publication')
  5299.             RETURN (1)
  5300.         END
  5301.  
  5302.     /*
  5303.     ** If the subscriber is an ODBC DSN, only allow subscriptions to
  5304.     ** publications with a character mode bcp sync_method.
  5305.     */
  5306.     IF (@srvstatus & @dsn_bit) <> 0 AND @sync_method <> @char_bcp
  5307.        BEGIN
  5308.             RAISERROR (14095, 16, -1, @publication, @subscriber)
  5309.             RETURN (1)
  5310.         END
  5311.  
  5312.     /*
  5313.     ** Parameter Check:  @article
  5314.     ** Check to make sure that the article exists, is not NULL, and
  5315.     ** conforms to the rules for identifiers.
  5316.     */
  5317.  
  5318.     IF LOWER(@article) = 'all'
  5319.         /*
  5320.     ** Get all articles in the publication that are not subscribed to
  5321.     ** by the @subscriber
  5322.     */
  5323.         BEGIN
  5324.             SELECT @cmd = ''
  5325.             SELECT @cmd = @cmd + 'DECLARE hCx CURSOR FOR '
  5326.             SELECT @cmd = @cmd + ' SELECT DISTINCT a.name '
  5327.             SELECT @cmd = @cmd + '   FROM sysarticles a, syspublications b '
  5328.             SELECT @cmd = @cmd + '  WHERE a.pubid = b.pubid '
  5329.             SELECT @cmd = @cmd + '    AND b.name = ''' + @publication + ''''
  5330.         SELECT @cmd2 = ' AND NOT EXISTS (SELECT * from syssubscriptions s '
  5331.         SELECT @cmd2 = @cmd2 + ' WHERE s.artid = a.artid AND s.status <> 0 AND s.srvid = '
  5332.         SELECT @cmd2 = @cmd2 + CONVERT(varchar(10), @srvid) + ')' + ' FOR READ ONLY'
  5333.             EXECUTE (@cmd + @cmd2)
  5334.             OPEN hCx
  5335.             FETCH hCx INTO @article
  5336.             WHILE (@@fetch_status <> -1)
  5337.                 BEGIN
  5338.                     EXECUTE sp_addsubscription @publication    = @publication,
  5339.                                                @article        = @article,
  5340.                                    @subscriber     = @subscriber,
  5341.                                                @destination_db = @destination_db,
  5342.                                                @sync_type      = @sync_type
  5343.                     FETCH hCx INTO @article
  5344.                 END
  5345.             CLOSE hCx
  5346.             DEALLOCATE hCx
  5347.             RETURN (0)
  5348.         END
  5349.  
  5350.     SELECT @artid = artid, @pre_creation_cmd = pre_creation_cmd
  5351.       FROM sysarticles
  5352.      WHERE name = @article
  5353.        AND pubid = @pubid
  5354.  
  5355.     IF @article IS NOT NULL
  5356.         BEGIN
  5357.             EXECUTE @retcode = sp_validname @article
  5358.             IF @retcode <> 0
  5359.         RETURN (1)
  5360.  
  5361.         IF NOT EXISTS (SELECT *
  5362.                              FROM sysarticles
  5363.                             WHERE artid = @artid
  5364.                               AND pubid = @pubid)
  5365.                 BEGIN
  5366.                     RAISERROR (15001, 11, -1, @article)
  5367.                     RETURN (1)
  5368.                 END
  5369.         END
  5370.  
  5371.     IF @artid IS NULL
  5372.         BEGIN
  5373.             RAISERROR (14043, 16, -1, 'The article')
  5374.             RETURN (1)
  5375.         END
  5376.  
  5377.     /*
  5378.     ** If the subscriber is an ODBC DSN, do not allow subscriptions to
  5379.     ** articles with a "truncate" pre_creation_cmd.
  5380.     */
  5381.     IF (@srvstatus & @dsn_bit) <> 0 AND @pre_creation_cmd = @truncate
  5382.        BEGIN
  5383.             RAISERROR (14094, 16, -1, @article, @subscriber)
  5384.             RETURN (1)
  5385.         END
  5386.  
  5387.    /*
  5388.    ** Parameter Check: @sync_type.
  5389.    ** Set sync_typeid based on the @sync_type specified.
  5390.    **
  5391.    **   sync_typeid     sync_type
  5392.    **   ===========     =========
  5393.    **             0     manual
  5394.    **             1     automatic
  5395.    **             2     none
  5396.    */
  5397.  
  5398.    IF LOWER(@sync_type) NOT IN ('automatic', 'manual', 'none')
  5399.        BEGIN
  5400.            RAISERROR (14052, 16, -1)
  5401.            RETURN (1)
  5402.        END
  5403.  
  5404.    IF LOWER(@sync_type) = 'automatic'
  5405.     SELECT @sync_typeid = @automatic
  5406.    ELSE IF LOWER(@sync_type) =  'manual'
  5407.         SELECT @sync_typeid = @manual
  5408.    ELSE
  5409.         SELECT @sync_typeid = @none
  5410.  
  5411.  
  5412.     /*
  5413.     ** If it's an automatic sync, ensure that none of the articles
  5414.     ** being subscribed to have the 'owner qualified' status bit set
  5415.     */
  5416.  
  5417.     IF @sync_typeid = @automatic
  5418.     BEGIN
  5419.         IF EXISTS ( SELECT * FROM sysarticles
  5420.                     WHERE artid = @artid AND pubid = @pubid AND
  5421.                     4 = (status & 4) )
  5422.         BEGIN
  5423.             RAISERROR( 14098, 16, -1 )
  5424.             RETURN (1)
  5425.         END
  5426.  
  5427.     END
  5428.  
  5429.     /*
  5430.     ** Parameter Check: @destination_db.
  5431.     ** Set @destination_db to current database if not specified.  Make
  5432.     ** sure that the @destination_db conforms to the rules for identifiers.
  5433.     */
  5434.  
  5435.     IF @destination_db IS NULL SELECT @destination_db = DB_NAME()
  5436.  
  5437.     EXECUTE @retcode = sp_validname @destination_db
  5438.  
  5439.     IF @retcode <> 0
  5440.     RETURN (1)
  5441.  
  5442.     /*
  5443.     ** Bug 12850:
  5444.     ** Make sure that the creation_script is specified if pre_creation_cmd is "drop"
  5445.     ** Note that at this point, @article cannot be 'all'.
  5446.     */
  5447.     if exists (select * from sysarticles where
  5448.             name = @article AND
  5449.             pre_creation_cmd = 1 AND
  5450.             creation_script is null)
  5451.         BEGIN
  5452.             RAISERROR (14096, 16, -1)    
  5453.             RETURN (1)
  5454.         END
  5455.  
  5456.  
  5457.     /*
  5458.     ** Add subscription to syssubscriptions
  5459.     */
  5460.     BEGIN TRAN addsubscription
  5461.  
  5462.     /*
  5463.     ** If no subscription exists, add it to syssubscriptions.
  5464.     */
  5465.     IF NOT EXISTS (SELECT *
  5466.                      FROM syssubscriptions
  5467.                     WHERE srvid = @srvid
  5468.                       AND artid = @artid)
  5469.         BEGIN
  5470.        INSERT syssubscriptions (artid,
  5471.                                     srvid,
  5472.                                     dest_db,
  5473.                                     status,
  5474.                                     sync_type,
  5475.                                     timestamp)
  5476.        VALUES (@artid,
  5477.                    @srvid,
  5478.                    @destination_db,
  5479.                    @inactive,
  5480.                    @sync_typeid,
  5481.                    NULL)
  5482.  
  5483.        IF @@ERROR <> 0
  5484.            BEGIN
  5485.                ROLLBACK TRAN  addsubscription
  5486.                    RAISERROR (14057, 16, -1)
  5487.                RETURN (1)
  5488.            END
  5489.         END
  5490.     ELSE
  5491.         BEGIN
  5492.            /*
  5493.        ** If is a 'restricted' publication the subscription may already
  5494.        ** exist.
  5495.        */
  5496.        IF EXISTS (SELECT * FROM syspublications WHERE pubid = @pubid
  5497.                  AND restricted = 0)
  5498.            BEGIN
  5499.               ROLLBACK TRAN  addsubscription
  5500.               RAISERROR (14058, 16, -1)
  5501.               RETURN (1)
  5502.            END
  5503.     END
  5504.  
  5505.     /*
  5506.     ** If the @status was not provided determine the default value.
  5507.     ** If the @sync_type = 'none' then the subscription defaults to 'active'.
  5508.     ** Else the subscription defaults to 'subscribed'.
  5509.     */
  5510.     IF @status IS NULL
  5511.        BEGIN
  5512.           IF @sync_typeid = @none    
  5513.          SELECT @status = 'active'
  5514.       ELSE
  5515.          SELECT @status = 'subscribed'
  5516.     END
  5517.  
  5518.     /*
  5519.     ** Set publication subscription status.
  5520.     */
  5521.     EXEC @retcode = sp_changesubstatus
  5522.     @publication = @publication,
  5523.     @article     = @article,
  5524.     @subscriber  = @subscriber,
  5525.     @status      = @status
  5526.  
  5527.     IF @@error <> 0 OR @retcode <> 0
  5528.     BEGIN
  5529.        ROLLBACK TRAN  addsubscription
  5530.            RAISERROR (14057, 16, -1)
  5531.        RETURN (1)
  5532.     END
  5533.  
  5534.     COMMIT TRAN addsubscription
  5535. go
  5536.  
  5537. print ''
  5538. print 'Creating procedure sp_changearticle.'
  5539. GO
  5540. CREATE PROCEDURE sp_changearticle (
  5541.     @publication varchar(30) = NULL,        /* Publication name */
  5542.     @article varchar(30) = NULL,            /* Article name */
  5543.     @property varchar(20) = NULL,           /* The property to change */
  5544.     @value varchar(255) = NULL              /* The new property value */
  5545.     ) AS
  5546.  
  5547.     SET NOCOUNT ON
  5548.  
  5549.     /*
  5550.     ** Declarations.
  5551.     */
  5552.  
  5553.     DECLARE @artid int
  5554.     DECLARE @cmd1 varchar(255)
  5555.     DECLARE @cmd2 varchar(255)
  5556.     DECLARE @db varchar(30)
  5557.     DECLARE @filter int
  5558.     DECLARE @object varchar(30)
  5559.     DECLARE @owner varchar(30)
  5560.     DECLARE @pubid int
  5561.     DECLARE @retcode int
  5562.     DECLARE @site varchar(30)
  5563.     DECLARE @sync_objid int
  5564.     DECLARE @typeid tinyint
  5565.     DECLARE @precmdid tinyint
  5566.     DECLARE @inactive tinyint
  5567.  
  5568.  
  5569.     select @inactive = 0
  5570.  
  5571.     /*
  5572.     ** Security Check
  5573.     ** Only the System Administrator (SA) or the Database Owner (dbo) can
  5574.     ** perform this procedure.
  5575.     */
  5576.  
  5577.     IF suser_id() <> 1 AND user_id() <> 1
  5578.         BEGIN
  5579.             RAISERROR (15000, 14, -1)
  5580.             RETURN (1)
  5581.         END
  5582.  
  5583.     /*
  5584.     ** Check to see if the database has been activated for publication.
  5585.     */
  5586.  
  5587.     IF (SELECT category & 1
  5588.           FROM master..sysdatabases
  5589.          WHERE name = DB_NAME()) = 0
  5590.  
  5591.     BEGIN
  5592.             RAISERROR (14013, 16, -1)
  5593.         RETURN (1)
  5594.     END
  5595.  
  5596.     /*
  5597.     ** Parameter Check:  @property.
  5598.     ** If the @property parameter is NULL, print the options.
  5599.     */
  5600.  
  5601.     IF @property IS NULL
  5602.         BEGIN
  5603.             CREATE TABLE #tab1 (properties varchar(30))
  5604.             INSERT INTO #tab1 VALUES ('name')
  5605.             INSERT INTO #tab1 VALUES ('description')
  5606.             INSERT INTO #tab1 VALUES ('sync_object')
  5607.             INSERT INTO #tab1 VALUES ('type')
  5608.             INSERT INTO #tab1 VALUES ('ins_cmd')
  5609.             INSERT INTO #tab1 VALUES ('del_cmd')
  5610.             INSERT INTO #tab1 VALUES ('upd_cmd')
  5611.             INSERT INTO #tab1 VALUES ('filter')
  5612.             INSERT INTO #tab1 VALUES ('dest_table')
  5613.             INSERT INTO #tab1 VALUES ('creation_script')
  5614.             INSERT INTO #tab1 VALUES ('pre_creation_cmd')
  5615.             INSERT INTO #tab1 VALUES ('status')
  5616.             PRINT ''
  5617.             SELECT * FROM #tab1
  5618.             RETURN (0)
  5619.         END
  5620.  
  5621.     /*
  5622.     ** Parameter Check:  @property.
  5623.     ** Check to make sure that @property is a valid property in
  5624.     ** sysarticles.
  5625.     */
  5626.     IF @property IS NULL OR LOWER(@property) NOT IN ('name',
  5627.                                                      'description',
  5628.                                                      'sync_object',
  5629.                                                      'type',
  5630.                                                      'ins_cmd',
  5631.                                                      'del_cmd',
  5632.                                                      'upd_cmd',
  5633.                                                      'filter',
  5634.                                                      'dest_table',
  5635.                                                      'creation_script',
  5636.                                                      'pre_creation_cmd',
  5637.                                                      'status')
  5638.         BEGIN
  5639.             RAISERROR (14022, 16, -1)
  5640.             RETURN (1)
  5641.         END
  5642.  
  5643.  
  5644.     /*
  5645.     ** Parameter Check:  @publication.
  5646.     ** Make sure that the publication exists.
  5647.     */
  5648.  
  5649.     IF @publication IS NULL
  5650.         BEGIN
  5651.             RAISERROR (14043, 16, -1, 'The publication')
  5652.             RETURN (1)
  5653.         END
  5654.  
  5655.     EXECUTE @retcode = sp_validname @publication
  5656.  
  5657.     IF @@ERROR <> 0 OR @retcode <> 0
  5658.     RETURN (1)
  5659.  
  5660.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  5661.  
  5662.     IF @pubid IS NULL
  5663.         BEGIN
  5664.             RAISERROR (15001, 11, -1, @publication)
  5665.             RETURN (1)
  5666.         END
  5667.     ELSE
  5668.  
  5669.     /*
  5670.     ** Check to see that the article exists in sysarticles.
  5671.     ** Fetch the article identification number.
  5672.     */
  5673.  
  5674.     IF @article IS NULL
  5675.         BEGIN
  5676.             RAISERROR (14043, 16, -1, 'The article')
  5677.             RETURN (1)
  5678.         END
  5679.  
  5680.     EXECUTE @retcode = sp_validname @article
  5681.  
  5682.     IF @retcode <> 0
  5683.     RETURN (1)
  5684.  
  5685.     SELECT @artid = artid
  5686.       FROM sysarticles
  5687.      WHERE name = @article
  5688.        AND pubid = @pubid
  5689.     IF @artid IS NULL
  5690.         BEGIN
  5691.             RAISERROR (15001, 11, -1, @article)
  5692.             RETURN (1)
  5693.         END
  5694.  
  5695.     /*
  5696.     ** Only unsubscribed articles may be modified.
  5697.     */
  5698.     IF EXISTS (SELECT * FROM syssubscriptions WHERE artid = @artid
  5699.        AND status <> @inactive)
  5700.         BEGIN
  5701.             RAISERROR (14092, 11, -1)
  5702.             RETURN (1)
  5703.         END
  5704.  
  5705.     /*
  5706.     ** Change the property.
  5707.     */
  5708.  
  5709.     IF LOWER(@property) IN ('name', 'description', 'ins_cmd', 'del_cmd', 'upd_cmd', 'dest_table', 'creation_script')
  5710.         BEGIN
  5711.  
  5712.             IF LOWER(@property) = 'name'
  5713.                 BEGIN
  5714.  
  5715.                     IF @value IS NULL
  5716.                         BEGIN
  5717.                             RAISERROR (14043, 16, -1, 'The article')
  5718.                             RETURN (1)
  5719.                         END
  5720.  
  5721.                     EXECUTE @retcode = sp_validname @value
  5722.  
  5723.                     IF @@ERROR <> 0 OR @retcode <> 0
  5724.             RETURN (1)
  5725.  
  5726.                     IF EXISTS (SELECT *
  5727.                                  FROM syspublications a, sysarticles b
  5728.                                 WHERE b.name = @value
  5729.                                   AND a.pubid = b.pubid
  5730.                                   AND a.name = @publication)
  5731.                         BEGIN
  5732.                             RAISERROR (14016, 16, -1, @value)
  5733.                             RETURN (1)
  5734.                         END
  5735.  
  5736.                 END
  5737.  
  5738.             /*
  5739.             ** Check the validity of the destination table.  NULL should
  5740.             ** get converted to the source table name.  Destination table
  5741.             ** names can be owner qualified, but not database qualified.
  5742.             */
  5743.  
  5744.             IF LOWER(@property) = 'dest_table'
  5745.                 BEGIN
  5746.                     IF @value IS NULL
  5747.                         SELECT @value = object_name(objid)
  5748.                           FROM sysarticles
  5749.                          WHERE artid = @artid
  5750.                            AND pubid = @pubid
  5751.                     IF @value LIKE '%.%.%' OR @value LIKE '%.%'
  5752.                         BEGIN
  5753.                             EXECUTE sp_namecrack @value,
  5754.                                                  @site OUTPUT,
  5755.                                                  @db OUTPUT,
  5756.                                                  @owner OUTPUT,
  5757.                                                  @object OUTPUT
  5758.                             IF @db IS NOT NULL
  5759.                                 BEGIN
  5760.                                     RAISERROR (14079, 16, -1)
  5761.                                     RETURN (1)
  5762.                                 END
  5763.                             EXECUTE @retcode = sp_validname @object
  5764.                             IF @@ERROR <> 0 OR @retcode <> 0
  5765.                 RETURN (1)
  5766.                         END
  5767.                     ELSE
  5768.                         BEGIN
  5769.                             EXECUTE @retcode = sp_validname @value
  5770.                             IF @@ERROR <> 0 OR @retcode <> 0
  5771.                 RETURN (1)
  5772.                         END
  5773.                 END
  5774.  
  5775.             SELECT @cmd1 = 'UPDATE sysarticles '
  5776.         IF @value IS NULL
  5777.         BEGIN
  5778.                 SELECT @cmd1 = @cmd1 + '   SET ' + @property + ' = NULL'
  5779.             SELECT @cmd2 = ' WHERE artid = ' + STR(@artid)
  5780.             SELECT @cmd2 = @cmd2 + '   AND pubid = ' + STR(@pubid)
  5781.             EXECUTE (@cmd1 + @cmd2)
  5782.         END
  5783.         ELSE
  5784.         BEGIN
  5785.             SELECT @cmd1 = @cmd1 + '   SET ' + @property + ' = '''
  5786.             SELECT @cmd2 = ''' WHERE artid = ' + STR(@artid)
  5787.             SELECT @cmd2 = @cmd2 + '   AND pubid = ' + STR(@pubid)
  5788.             EXECUTE (@cmd1 + @value + @cmd2)
  5789.         END
  5790.             IF @@ERROR <> 0 RETURN (1)
  5791.         END
  5792.  
  5793.     IF LOWER(@property) = 'sync_object'
  5794.         BEGIN
  5795.  
  5796.             /*
  5797.             ** Check for a valid synchronization object.
  5798.             */
  5799.  
  5800.             IF @value IS NULL
  5801.                 BEGIN
  5802.                     RAISERROR (14043, 16, -1, 'The synchronization object')
  5803.                     RETURN (1)
  5804.                 END
  5805.  
  5806.             IF @value LIKE '%.%.%' OR @value LIKE '%.%'
  5807.                 BEGIN
  5808.                     EXECUTE sp_namecrack @value,
  5809.                                          @site OUTPUT,
  5810.                                          @db OUTPUT,
  5811.                                          @owner OUTPUT,
  5812.                                          @object OUTPUT
  5813.  
  5814.                     EXECUTE @retcode = sp_validname @object
  5815.  
  5816.                     IF @@ERROR <> 0 OR @retcode <> 0
  5817.             RETURN (1)
  5818.  
  5819.                 END
  5820.  
  5821.             ELSE
  5822.                 BEGIN
  5823.  
  5824.                     EXECUTE @retcode = sp_validname @value
  5825.  
  5826.                     IF @@ERROR <> 0 OR @retcode <> 0
  5827.             RETURN (1)
  5828.                 END
  5829.  
  5830.             SELECT @sync_objid = OBJECT_ID(@value)
  5831.             IF @sync_objid IS NULL
  5832.                 BEGIN
  5833.                     RAISERROR (15001, 11, -1, @value)
  5834.                     RETURN (1)
  5835.                 END
  5836.  
  5837.             IF NOT EXISTS (SELECT *
  5838.                              FROM sysobjects
  5839.                             WHERE type IN ('U', 'V')
  5840.                               AND id = @sync_objid)
  5841.  
  5842.                 BEGIN
  5843.                     RAISERROR (14031, 16, -1)
  5844.                     RETURN (1)
  5845.                 END
  5846.  
  5847.             /*
  5848.             ** Update the article with the new synchronization object.
  5849.             */
  5850.  
  5851.             UPDATE sysarticles
  5852.                SET sync_objid = @sync_objid
  5853.              WHERE artid = @artid
  5854.                AND pubid = @pubid
  5855.  
  5856.             IF @@ERROR <> 0 RETURN (1)
  5857.  
  5858.         END
  5859.  
  5860.     IF LOWER(@property) = 'type'
  5861.         BEGIN
  5862.  
  5863.             /*
  5864.             ** Check to make sure that we have a valid type.
  5865.             */
  5866.  
  5867.         IF LOWER(@value) NOT IN ('logbased', 'logbased manualfilter', 'logbased manualview', 'logbased manualboth')
  5868.                 BEGIN
  5869.                     RAISERROR (14023, 16, -1)
  5870.                     RETURN (1)
  5871.                 END
  5872.  
  5873.             /*
  5874.             ** Determine the integer value for the type.
  5875.             */
  5876.         IF LOWER(@value) = 'logbased'
  5877.         SELECT @typeid = 1
  5878.         ELSE IF LOWER(@value) = 'logbased manualfilter'
  5879.         SELECT @typeid = 3
  5880.         ELSE IF LOWER(@value) = 'logbased manualview'
  5881.         SELECT @typeid = 5
  5882.         ELSE IF LOWER(@value) = 'logbased manualboth'
  5883.         SELECT @typeid = 7
  5884.  
  5885.             /*
  5886.             ** Update the article with the new type.
  5887.             */
  5888.  
  5889.             UPDATE sysarticles
  5890.                SET type = @typeid
  5891.              WHERE artid = @artid
  5892.                AND pubid = @pubid
  5893.  
  5894.             IF @@ERROR <> 0 RETURN (1)
  5895.  
  5896.         END
  5897.  
  5898.     IF LOWER(@property) = 'filter'
  5899.         BEGIN
  5900.  
  5901.             /*
  5902.             ** Check for a valid filter value.
  5903.             */
  5904.  
  5905.             IF @value IS NOT NULL
  5906.                 BEGIN
  5907.  
  5908.                     IF @value LIKE '%.%.%' OR @value LIKE '%.%'
  5909.                         BEGIN
  5910.                             EXECUTE sp_namecrack @value,
  5911.                                                  @site OUTPUT,
  5912.                                                  @db OUTPUT,
  5913.                                                  @owner OUTPUT,
  5914.                                                  @object OUTPUT
  5915.  
  5916.                             EXECUTE @retcode = sp_validname @object
  5917.  
  5918.                             IF @@ERROR <> 0 OR @retcode <> 0
  5919.                 RETURN (1)
  5920.  
  5921.                         END
  5922.  
  5923.                     ELSE
  5924.                         BEGIN
  5925.  
  5926.                             EXECUTE @retcode = sp_validname @value
  5927.  
  5928.                             IF @@ERROR <> 0 OR @retcode <> 0
  5929.                 RETURN (1)
  5930.                         END
  5931.                 END
  5932.  
  5933.             SELECT @filter = OBJECT_ID(@value)
  5934.  
  5935.             IF @value IS NOT NULL
  5936.                 BEGIN
  5937.  
  5938.                     IF @filter IS NULL
  5939.                         BEGIN
  5940.                             RAISERROR (15001, 11, -1, @value)
  5941.                             RETURN (1)
  5942.                         END
  5943.  
  5944.                     IF NOT EXISTS (SELECT *
  5945.                                      FROM sysobjects
  5946.                                     WHERE type = 'RF'
  5947.                                       AND id = @filter)
  5948.  
  5949.                         BEGIN
  5950.                             RAISERROR (14049, 16, -1)
  5951.                             RETURN (1)
  5952.                         END
  5953.  
  5954.                 END
  5955.  
  5956.             IF @value IS NULL SELECT @filter = 0
  5957.  
  5958.             /*
  5959.             ** Update the article with the new filter.
  5960.             */
  5961.  
  5962.             UPDATE sysarticles
  5963.                SET filter = @filter
  5964.              WHERE artid = @artid
  5965.                AND pubid = @pubid
  5966.  
  5967.             IF @@ERROR <> 0 RETURN (1)
  5968.  
  5969.         END
  5970.  
  5971.     IF LOWER(@property) = 'pre_creation_cmd'
  5972.         BEGIN
  5973.  
  5974.             /*
  5975.             ** Check to make sure that we have a valid pre_creation_cmd.
  5976.             */
  5977.  
  5978.             IF LOWER(@value) NOT IN ('none', 'drop', 'delete', 'truncate')
  5979.                 BEGIN
  5980.                     RAISERROR (14061, 16, -1)
  5981.                     RETURN (1)
  5982.                 END
  5983.  
  5984.             /*
  5985.             ** Determine the integer value for the type.
  5986.             */
  5987.  
  5988.             IF LOWER(@value) = 'none'
  5989.                 SELECT @precmdid = 0
  5990.             ELSE IF LOWER(@value) = 'drop'
  5991.                 SELECT @precmdid = 1
  5992.             ELSE IF LOWER(@value) = 'delete'
  5993.                 SELECT @precmdid = 2
  5994.             ELSE IF LOWER(@value) = 'truncate'
  5995.                 SELECT @precmdid = 3
  5996.  
  5997.             /*
  5998.             ** Update the article with the new pre_creation_cmd.
  5999.             */
  6000.             UPDATE sysarticles
  6001.                SET pre_creation_cmd = @precmdid
  6002.              WHERE artid = @artid
  6003.                AND pubid = @pubid
  6004.  
  6005.             IF @@ERROR <> 0 RETURN (1)
  6006.  
  6007.         END
  6008.  
  6009.     IF LOWER(@property) = 'status'
  6010.         BEGIN
  6011.             /*
  6012.             ** Check to make sure that we have a valid type.
  6013.             */
  6014.  
  6015.             IF LOWER(@value) NOT IN ('not owner qualified', 'owner qualified', 'no column names', 'include column names' )
  6016.                 BEGIN
  6017.                     RAISERROR (14097, 16, -1)
  6018.                     RETURN (1)
  6019.                 END
  6020.  
  6021.             /*
  6022.             ** Determine the integer value for the type.
  6023.             */
  6024.         IF LOWER(@value) = 'not owner qualified'
  6025.             UPDATE sysarticles 
  6026.             SET status = status & ~4
  6027.             WHERE artid = @artid
  6028.                           AND pubid = @pubid
  6029.  
  6030.         ELSE IF LOWER(@value) = 'owner qualified'
  6031.             UPDATE sysarticles 
  6032.             SET status = status | 4
  6033.             WHERE artid = @artid
  6034.                           AND pubid = @pubid
  6035.              
  6036.         ELSE IF LOWER(@value) = 'no column names'
  6037.             UPDATE sysarticles 
  6038.             SET status = status & ~8
  6039.             WHERE artid = @artid
  6040.                           AND pubid = @pubid
  6041.              
  6042.         ELSE IF LOWER(@value) = 'include column names'
  6043.             UPDATE sysarticles 
  6044.             SET status = status | 8
  6045.             WHERE artid = @artid
  6046.                           AND pubid = @pubid
  6047.              
  6048.         IF @@ERROR <> 0 RETURN (1)
  6049.  
  6050.     END
  6051.  
  6052.     /*
  6053.     ** Force the article cache to be refreshed with the new definition.
  6054.     */
  6055.     EXECUTE sp_replflush
  6056.  
  6057.     /*
  6058.     ** Return succeed.
  6059.     */
  6060.  
  6061.     RAISERROR (14025, 10, -1)
  6062.     RETURN (0)
  6063. go
  6064.  
  6065. print ''
  6066. print 'Creating procedure sp_changesubscriber.'
  6067. go
  6068. CREATE PROCEDURE sp_changesubscriber (
  6069.     @subscriber varchar (30),
  6070.     @type tinyint = 0,
  6071.     @login varchar (30) = NULL,
  6072.     @password varchar (30) = NULL,
  6073.     @commit_batch_size int = NULL,
  6074.     @status_batch_size int = NULL,
  6075.     @flush_frequency int = NULL,
  6076.     @frequency_type int = NULL,
  6077.     @frequency_interval int = NULL,
  6078.     @frequency_relative_interval int = NULL,
  6079.     @frequency_recurrence_factor int = NULL,
  6080.     @frequency_subday int = NULL,
  6081.     @frequency_subday_interval int = NULL,
  6082.     @active_start_time_of_day int = NULL,
  6083.     @active_end_time_of_day int = NULL,
  6084.     @active_start_date int = NULL,
  6085.     @active_end_date int = NULL,
  6086.     @description varchar (255) = NULL
  6087.         ) AS
  6088.  
  6089.     DECLARE @distributor varchar(30)
  6090.     DECLARE @distribdb varchar(30)
  6091.     DECLARE @distproc varchar (255)
  6092.     DECLARE @msg varchar(255)
  6093.     DECLARE @retcode int
  6094.  
  6095.     /*
  6096.     ** Check to make sure that the subscriber doesn't already exist.
  6097.     */
  6098.     IF NOT EXISTS (SELECT *
  6099.                  FROM master..sysservers
  6100.                 WHERE srvname = @subscriber)
  6101.         BEGIN
  6102.             SELECT @msg = 'The server ''' + @subscriber +
  6103.         ''' is not a valid subscriber.'
  6104.             PRINT @msg
  6105.             RETURN (0)
  6106.         END
  6107.  
  6108.     /*
  6109.     ** Get distribution server information for remote RPC
  6110.     ** subscription calls.
  6111.     */
  6112.     EXEC @retcode = sp_helpdistributor @distributor = @distributor OUTPUT,
  6113.         @distribdb = @distribdb OUTPUT
  6114.     IF @@ERROR <> 0 OR @retcode <> 0
  6115.         BEGIN
  6116.              PRINT 'Unable to update distribution database MSsubscriberinfo table.'
  6117.              RETURN (1)
  6118.      END
  6119.  
  6120.     /*
  6121.     ** Update MSsubscriber_info
  6122.     */
  6123.     SELECT @distproc = RTRIM(@distributor) + '.' +
  6124.         RTRIM(@distribdb) + '..sp_MSupdate_subscriber_info '
  6125.     EXEC @retcode = @distproc
  6126.         @@SERVERNAME,
  6127.         @subscriber,
  6128.     @type,
  6129.     @login,
  6130.     @password,
  6131.     @commit_batch_size,
  6132.     @status_batch_size,
  6133.     @flush_frequency,
  6134.     @frequency_type,
  6135.     @frequency_interval,
  6136.     @frequency_relative_interval,
  6137.     @frequency_recurrence_factor,
  6138.     @frequency_subday,
  6139.     @frequency_subday_interval,
  6140.     @active_start_time_of_day,
  6141.     @active_end_time_of_day,
  6142.     @active_start_date,
  6143.     @active_end_date,
  6144.     @description = @description
  6145.     IF @@ERROR <> 0 OR @retcode <> 0
  6146.         BEGIN
  6147.             SELECT @msg = 'The server ''' + @subscriber +
  6148.         ''' is not a valid subscriber.'
  6149.             PRINT @msg
  6150.         RETURN (1)
  6151.     END
  6152. go
  6153.  
  6154. print ''
  6155. print 'Creating procedure sp_distcounters'
  6156. go
  6157. CREATE PROCEDURE sp_distcounters
  6158.     AS
  6159.  
  6160.     SET NOCOUNT ON
  6161.  
  6162.     /*
  6163.     ** Declarations.
  6164.     */
  6165.     DECLARE @distributor varchar(30)
  6166.     DECLARE @distribdb varchar(30)
  6167.     DECLARE @distproc varchar (255)
  6168.     DECLARE @retcode int
  6169.  
  6170.     /*
  6171.     ** Get distribution server information for remote RPC
  6172.     ** subscription calls.  If no distribution information, assume
  6173.     ** replication is not being used.
  6174.     */
  6175.     EXEC @retcode = sp_helpdistributor @distributor = @distributor OUTPUT,
  6176.                                        @distribdb = @distribdb OUTPUT
  6177.     IF @@error <> 0 OR @retcode <> 0 OR @distributor IS NULL OR
  6178.        @distribdb IS NULL
  6179.     RETURN (1)
  6180.  
  6181.     /*
  6182.     ** Request counters from Distribution Server
  6183.     */
  6184.     SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) +
  6185.     '..sp_MSdistribution_counters '
  6186.     EXEC @retcode = @distproc @@SERVERNAME
  6187. go
  6188.  
  6189. print ''
  6190. print 'Creating procedure sp_droparticle.'
  6191. go
  6192.  
  6193. CREATE PROCEDURE sp_droparticle(
  6194.         @publication varchar(30),     /* The publication name */
  6195.         @article varchar(30)          /* The article name */
  6196.  
  6197.         ) AS
  6198.  
  6199.     /*
  6200.     ** Declarations.
  6201.     */
  6202.  
  6203.     DECLARE @cmd varchar(255)
  6204.     DECLARE @objid int
  6205.     DECLARE @pubid int
  6206.     DECLARE @publish_bit smallint
  6207.     DECLARE @retcode int
  6208.     DECLARE @filter_name varchar (30)
  6209.     DECLARE @view_name varchar (30)
  6210.     DECLARE @type tinyint
  6211.  
  6212.     /*
  6213.     ** Initializations.
  6214.     */
  6215.  
  6216.     SELECT @publish_bit = 32    /* Const: publishing server bit */
  6217.  
  6218.     /*
  6219.     ** Security Check.
  6220.     ** Only the System Administrator (SA) or the Database Owner (dbo) can
  6221.     ** drop an article from a publication.
  6222.     */
  6223.     IF suser_id() <> 1 AND user_id() <> 1
  6224.     BEGIN
  6225.             RAISERROR (15000, 14, -1)
  6226.         RETURN (1)
  6227.         END
  6228.  
  6229.     /*
  6230.     ** Get the @pubid.
  6231.     */
  6232.  
  6233.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  6234.  
  6235.     /*
  6236.     ** Parameter Check:  @article.
  6237.     ** If the @article is 'all', drop all articles for the specified
  6238.     ** publication (@publication).
  6239.     */
  6240.  
  6241.     IF LOWER(@article) = 'all'
  6242.         BEGIN
  6243.             SELECT @cmd = ''
  6244.             SELECT @cmd = @cmd + 'DECLARE hC SCROLL CURSOR FOR '
  6245.             SELECT @cmd = @cmd + ' SELECT DISTINCT name '
  6246.             SELECT @cmd = @cmd + '   FROM sysarticles '
  6247.             SELECT @cmd = @cmd + '  WHERE pubid = ' + CONVERT(varchar(10), @pubid)
  6248.             EXECUTE (@cmd)
  6249.             OPEN hC
  6250.             FETCH hC INTO @article
  6251.             WHILE (@@fetch_status <> -1)
  6252.                 BEGIN
  6253.                     EXECUTE sp_droparticle @publication, @article
  6254.                     FETCH hC INTO @article
  6255.                 END
  6256.             CLOSE hC
  6257.             DEALLOCATE hC
  6258.             RETURN (0)
  6259.         END
  6260.  
  6261.     /*
  6262.     ** Parameter Check: @article.
  6263.     ** The @article name must conform to the rules for identifiers.
  6264.     */
  6265.  
  6266.     IF @article IS NULL
  6267.         BEGIN
  6268.             RAISERROR (14043, 16, -1, 'The article')
  6269.             RETURN (1)
  6270.         END
  6271.  
  6272.     EXECUTE @retcode = sp_validname @article
  6273.  
  6274.     IF @retcode <> 0
  6275.     RETURN (1)
  6276.  
  6277.     /*
  6278.     ** Parameter Check: @publication.
  6279.     ** The @publication name must conform to the rules for identifiers.
  6280.     */
  6281.  
  6282.     IF @publication IS NULL
  6283.         BEGIN
  6284.             RAISERROR (14043, 16, -1, 'The publication')
  6285.             RETURN (1)
  6286.         END
  6287.  
  6288.     EXECUTE @retcode = sp_validname @publication
  6289.  
  6290.     IF @retcode <> 0
  6291.     RETURN (1)
  6292.  
  6293.     IF NOT EXISTS (SELECT * FROM syspublications WHERE name = @publication)
  6294.         BEGIN
  6295.             RAISERROR (15001, 11, -1, @publication)
  6296.             RETURN (1)
  6297.         END
  6298.  
  6299.     /*
  6300.     ** Ascertain the existence of the article.
  6301.     */
  6302.  
  6303.     IF NOT EXISTS (SELECT *
  6304.                      FROM sysarticles
  6305.                     WHERE name = @article
  6306.                       AND pubid = @pubid)
  6307.         BEGIN
  6308.             RAISERROR (15001, 11, -1, @article)
  6309.         RETURN (1)
  6310.         END
  6311.  
  6312.     /*
  6313.     ** Check to make sure that there are no subscriptions on the article.
  6314.     */
  6315.  
  6316.     IF EXISTS (SELECT *
  6317.                  FROM syssubscriptions, sysarticles
  6318.                 WHERE sysarticles.name = @article
  6319.                   AND sysarticles.pubid = @pubid
  6320.                   AND sysarticles.artid = syssubscriptions.artid)
  6321.         BEGIN
  6322.             RAISERROR (14046, 16, -1)
  6323.             RETURN (1)
  6324.         END
  6325.  
  6326.     /*
  6327.     **  Delete article from sysarticles and clear publish bit in
  6328.     **  sysobjects.
  6329.     */
  6330.  
  6331.     BEGIN TRAN droparticle
  6332.  
  6333.         /*
  6334.         ** Retrieve the object id of the underlying table.
  6335.         */
  6336.  
  6337.         SELECT @objid = objid, @type = type
  6338.           FROM sysarticles
  6339.          WHERE name = @article
  6340.            AND pubid = @pubid
  6341.  
  6342.         /*
  6343.         ** If this article is the only one that references this object,
  6344.         ** then we can safely turn off the publish bit in sysobjects.
  6345.         */
  6346.  
  6347.         IF NOT EXISTS (SELECT *
  6348.                          FROM sysarticles
  6349.                         WHERE objid = @objid
  6350.                           AND NOT (name = @article AND pubid = @pubid))
  6351.             BEGIN
  6352.                 UPDATE sysobjects SET category = category & ~@publish_bit
  6353.              WHERE id = (SELECT objid
  6354.                        FROM sysarticles
  6355.                               WHERE name = @article
  6356.                                 AND pubid = @pubid)
  6357.  
  6358.             IF @@ERROR <> 0
  6359.                 BEGIN
  6360.                 ROLLBACK TRAN
  6361.                         RAISERROR (14047, 16, -1, 'the article')
  6362.                 RETURN (1)
  6363.                 END
  6364.             END
  6365.  
  6366.         /*
  6367.         ** Drop article view if not logbased manualview (type = 5)
  6368.         */
  6369.     IF (@type & 5) = 1
  6370.        BEGIN    
  6371.         SELECT @view_name = sysobjects.name
  6372.             FROM sysarticles, sysobjects
  6373.          WHERE sysarticles.name = @article
  6374.            AND pubid = @pubid
  6375.            AND sync_objid = sysobjects.id
  6376.            AND sysobjects.type = 'V'
  6377.        END
  6378.  
  6379.         /*
  6380.         ** Drop article filter if not logbased manualfilter (type = 3)
  6381.         */
  6382.     IF (@type & 3) = 1
  6383.        BEGIN    
  6384.         SELECT @filter_name = sysobjects.name
  6385.             FROM sysarticles, sysobjects
  6386.          WHERE sysarticles.name = @article
  6387.            AND pubid = @pubid
  6388.            AND filter = sysobjects.id
  6389.            AND sysobjects.type = 'RF'
  6390.  
  6391.        END
  6392.  
  6393.     /*
  6394.     ** Drop all article columns.  This is done to force all Text\Image
  6395.     ** column status to be updated.
  6396.     */
  6397.     EXECUTE @retcode  = sp_articlecolumn @publication, @article,
  6398.        @operation = 'drop'
  6399.         IF @@ERROR <> 0 OR @retcode <> 0
  6400.        BEGIN
  6401.           ROLLBACK TRAN droparticle
  6402.           RETURN (1)
  6403.        END
  6404.  
  6405.         /*
  6406.         ** Remove the row from sysarticles.
  6407.         */
  6408.         DELETE
  6409.           FROM sysarticles
  6410.          WHERE name = @article
  6411.            AND pubid = @pubid
  6412.  
  6413.     IF @@ERROR <> 0
  6414.         BEGIN
  6415.           ROLLBACK TRAN
  6416.                 RAISERROR (14047, 16, -1, 'the article')
  6417.         RETURN (1)
  6418.         END
  6419.  
  6420.     COMMIT TRAN droparticle
  6421.  
  6422.     IF @view_name IS NOT NULL
  6423.        exec ('drop view ' + @view_name)
  6424.  
  6425.     IF @filter_name IS NOT NULL
  6426.        exec ('drop procedure ' + @filter_name)
  6427.  
  6428.     /*
  6429.     ** Force the article cache to be refreshed.
  6430.     */
  6431.     EXECUTE sp_replflush
  6432. go
  6433.  
  6434. print ''
  6435. print 'Creating procedure sp_droppublication.'
  6436. go
  6437. CREATE PROCEDURE sp_droppublication(
  6438.         @publication varchar(30)       /* The publication name */
  6439.         ) AS
  6440.  
  6441.     /*
  6442.     ** Declarations.
  6443.     */
  6444.  
  6445.     DECLARE @article varchar(30)
  6446.     DECLARE @cmd varchar(255)
  6447.     DECLARE @retcode int
  6448.     DECLARE @taskid int
  6449.     DECLARE @distributor varchar(30)
  6450.     DECLARE @distribdb varchar(30)
  6451.     DECLARE @distproc varchar (255)
  6452.  
  6453.     /*
  6454.     ** Only the System Administrator (SA) or the Database Owner (dbo) can drop
  6455.     ** a publication.
  6456.     */
  6457.  
  6458.     IF suser_id() <> 1 AND user_id() <> 1
  6459.     BEGIN
  6460.             RAISERROR (15000, 14, -1)
  6461.         RETURN (1)
  6462.         END
  6463.  
  6464.     /*
  6465.     ** Parameter Check:  @publication.
  6466.     ** If the @publication is 'all', drop all publications.  Otherwise,
  6467.     ** make sure the @publication is a valid non-null identifier.
  6468.     */
  6469.  
  6470.     IF LOWER(@publication) = 'all'
  6471.         BEGIN
  6472.             SELECT @cmd = ''
  6473.             SELECT @cmd = @cmd + 'DECLARE hC1 SCROLL CURSOR FOR '
  6474.             SELECT @cmd = @cmd + ' SELECT DISTINCT name '
  6475.             SELECT @cmd = @cmd + '   FROM syspublications '
  6476.             SELECT @cmd = @cmd + '  WHERE pubid NOT IN '
  6477.             SELECT @cmd = @cmd + '(SELECT pubid FROM sysarticles WHERE artid IN '
  6478.             SELECT @cmd = @cmd + '(SELECT artid FROM syssubscriptions))'
  6479.             EXECUTE (@cmd)
  6480.             OPEN hC1
  6481.             FETCH hC1 INTO @publication
  6482.             WHILE (@@fetch_status <> -1)
  6483.                 BEGIN
  6484.                     EXECUTE sp_droppublication @publication
  6485.                     FETCH hC1 INTO @publication
  6486.                 END
  6487.             CLOSE hC1
  6488.             DEALLOCATE hC1
  6489.             RETURN (0)
  6490.         END
  6491.  
  6492.     IF @publication IS NULL
  6493.         BEGIN
  6494.             RAISERROR (14003, 16, -1)
  6495.             RETURN (1)
  6496.         END
  6497.  
  6498.     EXECUTE @retcode = sp_validname @publication
  6499.  
  6500.     IF @retcode <> 0
  6501.     RETURN (1)
  6502.  
  6503.     /*
  6504.     ** Ascertain the existence of the publication and get the taskid.
  6505.     */
  6506.     SELECT @taskid = taskid
  6507.                      FROM syspublications
  6508.                     WHERE name = @publication
  6509.     IF @taskid IS NULL
  6510.         BEGIN
  6511.             RAISERROR (15001, 11, -1, @publication)
  6512.         RETURN (1)
  6513.         END
  6514.  
  6515.     /*
  6516.     ** Check to make sure that there are no subscriptions on the publication.
  6517.     */
  6518.  
  6519.     IF EXISTS (SELECT *
  6520.                  FROM syssubscriptions a, sysarticles b, syspublications c
  6521.                 WHERE c.name = @publication
  6522.                   AND c.pubid = b.pubid
  6523.                   AND b.artid = a.artid)
  6524.         BEGIN
  6525.             RAISERROR (14005, 16, -1)
  6526.             RETURN (1)
  6527.         END
  6528.  
  6529.     /*
  6530.     ** Delete all articles from the publication.
  6531.     */
  6532.  
  6533.     SELECT @cmd = ''
  6534.     SELECT @cmd = @cmd + 'DECLARE hC2 SCROLL CURSOR FOR '
  6535.     SELECT @cmd = @cmd + ' SELECT DISTINCT name '
  6536.     SELECT @cmd = @cmd + '   FROM sysarticles '
  6537.     SELECT @cmd = @cmd + '  WHERE pubid = (SELECT pubid '
  6538.     SELECT @cmd = @cmd + '   FROM syspublications '
  6539.     SELECT @cmd = @cmd + '  WHERE name = ''' + @publication + ''')'
  6540.     EXECUTE (@cmd)
  6541.     OPEN hC2
  6542.     FETCH hC2 INTO @article
  6543.     WHILE (@@fetch_status <> -1)
  6544.         BEGIN
  6545.             EXECUTE sp_droparticle @publication, @article
  6546.             FETCH hC2 INTO @article
  6547.         END
  6548.     CLOSE hC2
  6549.     DEALLOCATE hC2
  6550.  
  6551.     /*
  6552.     ** Delete publication from syspublications.
  6553.     */
  6554.  
  6555.     DELETE
  6556.       FROM syspublications
  6557.      WHERE name = @publication
  6558.  
  6559.     IF @@ERROR <> 0
  6560.         BEGIN
  6561.             RAISERROR (14006, 16, -1)
  6562.         RETURN (1)
  6563.         END
  6564.  
  6565.     /*
  6566.     ** Get distribution server information for remote RPC call.
  6567.     */
  6568.     EXEC @retcode = sp_helpdistributor @distributor = @distributor OUTPUT,
  6569.                                        @distribdb = @distribdb OUTPUT
  6570.  
  6571.     IF @@ERROR <> 0 OR  @retcode <> 0
  6572.         BEGIN
  6573.             RAISERROR (14071, 16, -1)
  6574.             RETURN (1)
  6575.         END
  6576.  
  6577.     /*
  6578.     ** Delete sync task of Publication.
  6579.     */
  6580.     SELECT @distproc = RTRIM(@distributor) + '.msdb..sp_droptask'
  6581.     EXECUTE @distproc @id = @taskid
  6582. go
  6583.  
  6584.  
  6585. print ''
  6586. print 'Creating procedure sp_droppublisher.'
  6587. go
  6588. CREATE PROCEDURE sp_droppublisher (
  6589.     @publisher varchar (30),         /* publisher server name */
  6590.     @type varchar (5) = NULL      /* NULL or 'dist' */
  6591.         ) AS
  6592.  
  6593.     DECLARE @distaccount varchar(127)
  6594.     DECLARE @proc varchar (255)
  6595.     DECLARE @retcode int
  6596.     DECLARE @privilege varchar (30)
  6597.  
  6598.     /*
  6599.     ** Parameter Check:  @publisher.
  6600.     ** Check to make sure that the publisher exists, that the name isn't
  6601.     ** NULL, and that the name conforms to the rules for identifiers.
  6602.     */
  6603.  
  6604.     IF @publisher IS NULL
  6605.         BEGIN
  6606.             RAISERROR (14043, 16, -1, 'The publisher')
  6607.             RETURN (1)
  6608.         END
  6609.  
  6610.     EXECUTE @retcode = sp_validname @publisher
  6611.  
  6612.     IF @retcode <> 0
  6613.     RETURN (1)
  6614.  
  6615.     /*
  6616.     ** Perform special logic if dropping a publisher for a distribution
  6617.     ** server.
  6618.     */
  6619.     IF LOWER(@type) = 'dist'
  6620.         BEGIN
  6621.         IF NOT EXISTS (SELECT *
  6622.         FROM master..sysservers
  6623.                 WHERE srvname = @publisher
  6624.                 AND srvstatus & 16 <> 0)
  6625.  
  6626.         BEGIN
  6627.         RAISERROR (14080, 11, -1)
  6628.             RETURN (1)
  6629.         END
  6630.  
  6631.         EXECUTE @retcode = sp_serveroption @publisher, 'dpub', false
  6632.         IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1)
  6633.  
  6634.             IF EXISTS (SELECT * FROM master..sysremotelogins
  6635.            WHERE remoteserverid = (SELECT srvid FROM master..sysservers
  6636.            WHERE srvname = @publisher)
  6637.            AND remoteusername = 'sa'
  6638.            AND suid = 1)     /* 'sa' */
  6639.         BEGIN
  6640.            EXECUTE @retcode = sp_dropremotelogin @publisher, sa, sa
  6641.            IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1)
  6642.         END
  6643.  
  6644.             IF EXISTS (SELECT * FROM master..sysremotelogins
  6645.            WHERE remoteserverid = (SELECT srvid FROM master..sysservers
  6646.            WHERE srvname = @publisher)
  6647.            AND remoteusername = 'probe'
  6648.            AND suid = 10)     /* 'probe' */
  6649.         BEGIN
  6650.            EXECUTE @retcode = sp_dropremotelogin @publisher, probe, probe
  6651.            IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1)
  6652.         END
  6653.  
  6654.         RETURN (0)
  6655.     END
  6656.  
  6657.     /*
  6658.     ** Make sure the server is defined as a 'publisher'.
  6659.     */
  6660.     IF NOT EXISTS (SELECT *
  6661.                      FROM master..sysservers
  6662.                     WHERE srvname = @publisher
  6663.                       AND srvstatus & 2 <> 0)
  6664.  
  6665.         BEGIN
  6666.             RAISERROR (14080, 11, -1)
  6667.             RETURN (1)
  6668.         END
  6669.  
  6670.     /*
  6671.     ** Turn off the server option to indicate that this is a publisher.
  6672.     */
  6673.     EXECUTE @retcode = sp_serveroption @publisher, 'pub', false
  6674.     IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1)
  6675.  
  6676.     /*
  6677.     ** Fetch the publisher's distributor account.
  6678.     */
  6679.  
  6680.     SELECT @proc = RTRIM(@publisher) + '.master..sp_helpdistributor '
  6681.     EXEC @retcode = @proc @account = @distaccount OUTPUT
  6682.     IF @@ERROR <> 0 OR @retcode <> 0
  6683.         BEGIN
  6684.             RAISERROR (14071, 16, -1)
  6685.             RETURN (1)
  6686.         END
  6687.  
  6688.     /*
  6689.     ** If @distaccount = 'LocalSystem' assume 'admin' privilege
  6690.     */
  6691.     IF @distaccount = 'LocalSystem'
  6692.        RETURN (0)
  6693.  
  6694.     /*
  6695.     ** If @distaccount has 'admin' privilege, do not revoke
  6696.     */
  6697.     EXECUTE @retcode = master.dbo.xp_logininfo @distaccount, 'all',
  6698.        @privilege = @privilege output
  6699.     IF @@error <> 0 OR @retcode <> 0 RETURN (1)
  6700.  
  6701.     IF @privilege = 'admin'
  6702.        RETURN  (0)
  6703.  
  6704.     /*
  6705.     ** Revoke replication privilege to the distributor NT account.
  6706.     */
  6707.     EXEC @retcode = master.dbo.xp_revokelogin @distaccount
  6708.     IF @@ERROR <> 0 OR @retcode <> 0 RETURN (1)
  6709. go
  6710.  
  6711. print ''
  6712. print 'Creating procedure sp_dropsubscriber.'
  6713. go
  6714. CREATE PROCEDURE sp_dropsubscriber (
  6715.     @subscriber varchar (30)        /* The name of the subscriber */
  6716.         ) AS
  6717.  
  6718.     SET NOCOUNT ON
  6719.  
  6720.     /*
  6721.     ** Declarations.
  6722.     */
  6723.  
  6724.     DECLARE @retcode int
  6725.  
  6726.     /*
  6727.     ** Security Check.
  6728.     ** Only the System Administrator (SA) or the Database Owner (dbo) can
  6729.     ** drop a subscriber
  6730.     */
  6731.     IF suser_id() <> 1 AND user_id() <> 1
  6732.     BEGIN
  6733.             RAISERROR (15000, 14, -1)
  6734.         RETURN (1)
  6735.         END
  6736.  
  6737.     /*
  6738.     ** Parameter Check:  @subscriber.
  6739.     ** Check to make sure that the subscriber exists.
  6740.     */
  6741.  
  6742.     IF @subscriber IS NULL
  6743.         BEGIN
  6744.             RAISERROR (14043, 16, -1, 'The subscriber')
  6745.             RETURN (1)
  6746.         END
  6747.  
  6748.     EXECUTE @retcode = sp_validname @subscriber
  6749.  
  6750.     IF @retcode <> 0
  6751.     RETURN (1)
  6752.  
  6753.     IF NOT EXISTS (SELECT *
  6754.                      FROM master..sysservers
  6755.                     WHERE srvname = @subscriber
  6756.                       AND srvstatus & 4 <> 0)
  6757.  
  6758.         BEGIN
  6759.             RAISERROR (14048, 16, -1, @subscriber)
  6760.             RETURN (1)
  6761.         END
  6762.  
  6763.     /*
  6764.     ** Drop the remote logins associated with this server.
  6765.     */
  6766.  
  6767.     IF EXISTS (SELECT * FROM master..sysremotelogins
  6768.     WHERE remoteserverid = (SELECT srvid FROM master..sysservers
  6769.            WHERE srvname = @subscriber)
  6770.        AND remoteusername = 'sa'
  6771.        AND suid = 16383)     /* 'repl_subscriber' */
  6772.     BEGIN
  6773.         EXECUTE @retcode = sp_dropremotelogin @subscriber,
  6774.         'repl_subscriber', 'sa'
  6775.         IF @@ERROR <> 0
  6776.                BEGIN
  6777.            ROLLBACK TRANSACTION
  6778.                    RAISERROR (14047, 16, -1, @subscriber)
  6779.                    RETURN (1)
  6780.                END
  6781.  
  6782.         IF @retcode <> 0
  6783.         BEGIN
  6784.            ROLLBACK TRANSACTION
  6785.            RETURN (1)
  6786.         END
  6787.     END
  6788.  
  6789.     /*
  6790.     ** Turn off the subscriber server option.
  6791.     */
  6792.     EXECUTE @retcode = sp_serveroption @subscriber, 'sub', false
  6793.     IF @@ERROR <> 0
  6794.         BEGIN
  6795.            ROLLBACK TRANSACTION
  6796.            RAISERROR (14047, 16, -1, @subscriber)
  6797.            RETURN (1)
  6798.         END
  6799.  
  6800.     IF @retcode <> 0
  6801.         BEGIN
  6802.            ROLLBACK TRANSACTION
  6803.            RETURN (@retcode)
  6804.         END
  6805.  
  6806.     RAISERROR (14062, 10, -1)
  6807. go
  6808.  
  6809. print ''
  6810. print 'Creating procedure sp_dropsubscription.'
  6811. go
  6812. CREATE PROCEDURE sp_dropsubscription (
  6813.     @publication varchar (30) = NULL,   /* The publication name */
  6814.     @article varchar (30) = NULL,       /* The article name */
  6815.     @subscriber varchar (30)            /* The subscriber name */
  6816.     ) AS
  6817.  
  6818.     /*
  6819.     ** Declarations.
  6820.     */
  6821.  
  6822.     DECLARE @subscriber_bit smallint
  6823.     DECLARE @cmd varchar(255)
  6824.     DECLARE @srvid smallint
  6825.     DECLARE @artid int
  6826.     DECLARE @retcode int
  6827.     DECLARE @active tinyint
  6828.  
  6829.     /*
  6830.     ** Initializations.
  6831.     */
  6832.     SET NOCOUNT ON
  6833.     SELECT @subscriber_bit = 4  /* Const: subscription server status */
  6834.     SELECT @active = 2          /* Const: subscription status 'active' */
  6835.  
  6836.     /*
  6837.     ** Security Check.
  6838.     ** Only the System Administrator (SA) or the Database Owner (dbo) can
  6839.     ** add an article to a publication.
  6840.     */
  6841.  
  6842.     IF suser_id() <> 1 AND user_id() <> 1
  6843.     BEGIN
  6844.             RAISERROR (15000, 14, -1)
  6845.         RETURN (1)
  6846.         END
  6847.  
  6848.     /*
  6849.     ** If the @subscriber is 'all', the user wants to cancel all subscriptions
  6850.     ** to the specified article(s).
  6851.     */
  6852.  
  6853.     IF LOWER(@subscriber) = 'all'
  6854.         BEGIN
  6855.             SELECT @cmd = ''
  6856.             SELECT @cmd = @cmd + 'DECLARE hC1 SCROLL CURSOR FOR '
  6857.             SELECT @cmd = @cmd + ' SELECT DISTINCT srvname '
  6858.             SELECT @cmd = @cmd + '   FROM master..sysservers a, syssubscriptions b '
  6859.             SELECT @cmd = @cmd + '  WHERE srvstatus & ' + CONVERT(char(1), @subscriber_bit) + ' <> 0 '
  6860.             SELECT @cmd = @cmd + '    AND a.srvid = b.srvid '
  6861.             EXECUTE (@cmd)
  6862.             OPEN hC1
  6863.             FETCH hC1 INTO @subscriber
  6864.             WHILE (@@fetch_status <> -1)
  6865.                 BEGIN
  6866.                     EXECUTE sp_dropsubscription @publication = 'all',
  6867.                                     @subscriber  = @subscriber
  6868.                     FETCH hC1 INTO @subscriber
  6869.                 END
  6870.             CLOSE hC1
  6871.             DEALLOCATE hC1
  6872.             RETURN (0)
  6873.         END
  6874.  
  6875.     /*
  6876.     ** Parameter Check: @subscriber.
  6877.     ** Check if the server exists and that it is a subscription server.
  6878.     */
  6879.  
  6880.     IF @subscriber IS NULL
  6881.         BEGIN
  6882.             RAISERROR (14043, 16, -1, 'The subscriber')
  6883.             RETURN (1)
  6884.         END
  6885.  
  6886.     EXECUTE @retcode = sp_validname @subscriber
  6887.  
  6888.     IF @retcode <> 0
  6889.     RETURN (1)
  6890.  
  6891.     SELECT @srvid = srvid
  6892.       FROM sysservers
  6893.      WHERE srvname = @subscriber
  6894.        AND (srvstatus & @subscriber_bit) <> 0
  6895.  
  6896.     IF @srvid IS NULL
  6897.         BEGIN
  6898.             RAISERROR (14010, 16, -1)
  6899.             RETURN (1)
  6900.         END
  6901.  
  6902.     /*
  6903.     ** If the @publication is 'all', the user wants to cancel all subscriptions
  6904.     ** for all publications associated with the specified @subscriber.
  6905.     */
  6906.  
  6907.     IF LOWER(@publication) = 'all'
  6908.         BEGIN
  6909.             SELECT @cmd = ''
  6910.             SELECT @cmd = @cmd + 'DECLARE hC2 SCROLL CURSOR FOR '
  6911.             SELECT @cmd = @cmd + ' SELECT DISTINCT a.name '
  6912.             SELECT @cmd = @cmd + '   FROM syspublications a, '
  6913.             SELECT @cmd = @cmd + '        sysarticles b, '
  6914.             SELECT @cmd = @cmd + '        syssubscriptions c '
  6915.             SELECT @cmd = @cmd + '  WHERE c.srvid = ' + CONVERT(char(10), @srvid)
  6916.             SELECT @cmd = @cmd + '    AND a.pubid = b.pubid '
  6917.             SELECT @cmd = @cmd + '    AND b.artid = c.artid '
  6918.             EXECUTE (@cmd)
  6919.             OPEN hC2
  6920.             FETCH hC2 INTO @publication
  6921.             WHILE (@@fetch_status <> -1)
  6922.                 BEGIN
  6923.                     EXECUTE sp_dropsubscription @publication = @publication,
  6924.                                                 @article     = 'all',
  6925.                                     @subscriber  = @subscriber
  6926.                     FETCH hC2 INTO @publication
  6927.                 END
  6928.             CLOSE hC2
  6929.             DEALLOCATE hC2
  6930.             RETURN (0)
  6931.         END
  6932.  
  6933.     /*
  6934.     ** Parameter Check: @publication.
  6935.     ** Check to make sure that the publication exists and that it conforms
  6936.     ** to the rules for identifiers.
  6937.     */
  6938.  
  6939.     IF @publication IS NULL
  6940.         BEGIN
  6941.             RAISERROR (14043, 16, -1, 'The publication')
  6942.             RETURN (1)
  6943.         END
  6944.  
  6945.     EXECUTE @retcode = sp_validname @publication
  6946.  
  6947.     IF @retcode <> 0
  6948.     RETURN (1)
  6949.  
  6950.     IF NOT EXISTS (SELECT * FROM syspublications WHERE name = @publication)
  6951.         BEGIN
  6952.             RAISERROR (15001, 11, -1, @publication)
  6953.             RETURN (1)
  6954.         END
  6955.  
  6956.     /*
  6957.     ** If the @article is 'all', the user wants to cancel all
  6958.     ** subscriptions on this publisher associated with the given @subscriber
  6959.     ** and @publication.
  6960.     */
  6961.  
  6962.     IF LOWER(@article) = 'all'
  6963.         BEGIN
  6964.             SELECT @cmd = ''
  6965.             SELECT @cmd = @cmd + 'DECLARE hC3 SCROLL CURSOR FOR '
  6966.             SELECT @cmd = @cmd + 'SELECT DISTINCT art.name '
  6967.             SELECT @cmd = @cmd + 'FROM sysarticles art, '
  6968.             SELECT @cmd = @cmd + 'syssubscriptions sub, '
  6969.             SELECT @cmd = @cmd + 'syspublications pub '
  6970.             SELECT @cmd = @cmd + 'WHERE sub.srvid = ' + CONVERT(char(10), @srvid)
  6971.             SELECT @cmd = @cmd + 'AND sub.artid = art.artid '
  6972.             SELECT @cmd = @cmd + 'AND art.pubid = pub.pubid '
  6973.             SELECT @cmd = @cmd + 'AND pub.name = ''' + @publication + ''''
  6974.             EXECUTE (@cmd)
  6975.             OPEN hC3
  6976.             FETCH hC3 INTO @article
  6977.             WHILE (@@fetch_status <> -1)
  6978.                 BEGIN
  6979.                     EXECUTE sp_dropsubscription @publication,
  6980.                                                 @article,
  6981.                                     @subscriber
  6982.                     FETCH hC3 INTO @article
  6983.                 END
  6984.             CLOSE hC3
  6985.             DEALLOCATE hC3
  6986.             RETURN (0)
  6987.         END
  6988.  
  6989.     /*
  6990.     ** Parameter Check: @article
  6991.     ** Check if the article exists.
  6992.     */
  6993.  
  6994.     IF @article IS NULL
  6995.         BEGIN
  6996.             RAISERROR (14043, 16, -1, 'The article')
  6997.             RETURN (1)
  6998.         END
  6999.  
  7000.     EXECUTE @retcode = sp_validname @article
  7001.  
  7002.     IF @retcode <> 0
  7003.     RETURN (1)
  7004.  
  7005.     SELECT @artid = artid
  7006.       FROM sysarticles art, syspublications pub
  7007.      WHERE pub.name = @publication
  7008.        AND art.name = @article
  7009.        AND art.pubid = pub.pubid
  7010.  
  7011.     IF @artid IS NULL
  7012.         BEGIN
  7013.             RAISERROR (15001, 11, -1, @article)
  7014.         RETURN (1)
  7015.         END
  7016.  
  7017.     /*
  7018.     ** Check if the subscription exists.
  7019.     */
  7020.  
  7021.     IF NOT EXISTS (SELECT *
  7022.                      FROM syssubscriptions
  7023.                     WHERE srvid = @srvid
  7024.                       AND artid = @artid)
  7025.     BEGIN
  7026.             RAISERROR (14055, 11, -1, @article, @publication, @subscriber)
  7027.             RETURN (1)
  7028.     END
  7029.  
  7030.     BEGIN TRANSACTION dropsubscription
  7031.  
  7032.         /*
  7033.         ** Change the status of the subscription to 'inactive'.
  7034.         */
  7035.  
  7036.         EXECUTE @retcode = sp_changesubstatus @publication,
  7037.                                               @article,
  7038.                                       @subscriber,
  7039.                                               @status = 'inactive'
  7040.         IF @@ERROR <> 0 OR @retcode <> 0
  7041.         BEGIN
  7042.             ROLLBACK TRANSACTION dropsubscription
  7043.             RETURN (1)
  7044.         END
  7045.         /*
  7046.         ** Remove subscription from syssubscriptions.
  7047.         */
  7048.  
  7049.     DELETE syssubscriptions
  7050.      WHERE artid = @artid
  7051.        AND srvid = @srvid
  7052.  
  7053.     IF @@ERROR <> 0
  7054.         BEGIN
  7055.         ROLLBACK TRANSACTION dropsubscription
  7056.         RAISERROR (14055, 16, -1, @article, @publication, @subscriber)
  7057.         RETURN (1)
  7058.         END
  7059.  
  7060.     COMMIT TRANSACTION dropsubscription
  7061.  
  7062.  
  7063. go
  7064.  
  7065. print ''
  7066. print 'Creating procedure sp_dsninfo.'
  7067. go
  7068. CREATE PROCEDURE sp_dsninfo
  7069.         @dsn varchar (30),
  7070.     @infotype varchar (30) = NULL,
  7071.     @login varchar (30) = NULL,
  7072.     @password varchar (30) = NULL
  7073.     AS
  7074.  
  7075.     SET NOCOUNT ON
  7076.  
  7077.     DECLARE @distributor varchar(30)
  7078.     DECLARE @distproc varchar (255)
  7079.     DECLARE @retcode int
  7080.  
  7081.     /*
  7082.     ** Get distribution server information for remote RPC
  7083.     ** subscription calls.
  7084.     */
  7085.  
  7086.     EXEC @retcode = sp_helpdistributor @distributor = @distributor OUTPUT
  7087.     IF @@error <> 0 OR @retcode <> 0
  7088.         BEGIN
  7089.         RAISERROR (14071, 16, -1)
  7090.             RETURN (1)
  7091.     END
  7092.  
  7093.     /*
  7094.     ** Call xp_dsninfo
  7095.     */
  7096.     SELECT @distproc = RTRIM(@distributor) + '.master..xp_dsninfo '
  7097.     EXEC @retcode = @distproc @dsn, @infotype, @login, @password
  7098.     IF @@error <> 0
  7099.         BEGIN
  7100.         RAISERROR (14071, 16, -1)
  7101.         RETURN (1)
  7102.     END
  7103.  
  7104. go
  7105.  
  7106. print ''
  7107. print 'Creating procedure sp_publishdb.'
  7108. go
  7109. CREATE PROCEDURE sp_publishdb @dbname varchar(30),@value varchar (5)
  7110.     AS
  7111.  
  7112.     DECLARE @retcode int
  7113.     DECLARE @distributor varchar(30)
  7114.     DECLARE @distribdb varchar(30)
  7115.     DECLARE @distproc varchar (255)
  7116.     DECLARE @taskname varchar (40)
  7117.  
  7118.     /*
  7119.     ** Construct Log Reader task name.
  7120.     */
  7121.     select @taskname = @@SERVERNAME + '_' + @dbname
  7122.  
  7123.     /*
  7124.     ** Get distribution server information for remote RPC call.
  7125.     */
  7126.     EXECUTE @retcode = sp_helpdistributor @distributor = @distributor OUTPUT,
  7127.        @distribdb   = @distribdb OUTPUT
  7128.  
  7129.     IF @@ERROR <> 0 or @retcode <> 0
  7130.         BEGIN
  7131.            IF LOWER(@value) = 'true'
  7132.          RAISERROR (14036, 16, -1)
  7133.        ELSE
  7134.          RAISERROR (14038, 16, -1)
  7135.        RETURN (1)
  7136.     END
  7137.  
  7138.     /*
  7139.     ** Enable the database for publishing.
  7140.     */
  7141.     IF @value = 'true'
  7142.     begin
  7143.         /*
  7144.         ** Check if the database has already been enabled.
  7145.         */
  7146.         IF EXISTS (SELECT * FROM sysdatabases
  7147.             WHERE name = @dbname
  7148.             AND (category & 1) <> 0)
  7149.             BEGIN
  7150.                 RAISERROR (14035, 10, -1, @dbname)
  7151.                 RETURN (0)
  7152.             END
  7153.  
  7154.         /*
  7155.         ** Schedule Log Reader task for the database
  7156.         */
  7157.         SELECT @distproc = RTRIM(@distributor) + '.msdb..sp_addtask'
  7158.         EXECUTE @retcode = @distproc
  7159.         @taskname,
  7160.         @subsystem = 'LogReader',
  7161.         @server = @@SERVERNAME,
  7162.         @databasename = @dbname,
  7163.         @freqtype = 64,        /* Auto-Start */
  7164.         @retryattempts = 1440,    /* Every minute for 24 hours */
  7165.         @retrydelay = 1,    
  7166.         @command = '-b100 -c100 -i1000 -t100',
  7167.         @enabled = 1,
  7168.         @loghistcompletionlevel = 0
  7169.         IF @@ERROR <> 0 or @retcode <> 0
  7170.             BEGIN
  7171.                 RETURN (1)
  7172.             END
  7173.  
  7174.         /*
  7175.             ** Add the repl_subscriber user account to the database.
  7176.         */
  7177.         IF NOT EXISTS (SELECT * FROM sysusers WHERE name = 'repl_subscriber')
  7178.             EXECUTE sp_adduser 'repl_subscriber'
  7179.     END
  7180.  
  7181. else    /* Disable the database for publishing. */
  7182.     begin
  7183.           /*
  7184.         ** Check if the database is enabled for publishing.
  7185.             */
  7186.         IF NOT EXISTS (SELECT * FROM sysdatabases
  7187.             WHERE name = @dbname
  7188.             AND (category & 1) <> 0)
  7189.             BEGIN
  7190.                 RAISERROR (14013, 10, -1)
  7191.                 return (0)
  7192.             END
  7193.             /*
  7194.             ** Delete logreader task, continue if drop is not successful
  7195.             */
  7196.             SELECT @distproc = RTRIM(@distributor) + '.msdb..sp_droptask'
  7197.             EXECUTE @distproc @name = @taskname
  7198.  
  7199.         /*
  7200.             ** Remove all subscriptions in the database.
  7201.                */
  7202.         EXEC sp_dropsubscription @publication = 'all',
  7203.             @article = 'all', @subscriber = 'all'
  7204.  
  7205.             /*
  7206.             ** Remove all publications and articles in the database.
  7207.             */
  7208.         EXEC sp_droppublication @publication = 'all'
  7209.  
  7210.         /*
  7211.         ** Remove all published database jobs from the distribution
  7212.         ** database.
  7213.         */
  7214.             SELECT @distproc = RTRIM(@distributor) + '.' +
  7215.                 RTRIM(@distribdb) + '..sp_MSremove_published_jobs '
  7216.             EXEC @distproc @@SERVERNAME, @dbname
  7217.  
  7218.         /*
  7219.         ** Remove the repl_subscriber user account from the database.
  7220.         */
  7221.  
  7222.         IF EXISTS (SELECT * FROM sysusers WHERE name = 'repl_subscriber')
  7223.            exec sp_dropuser 'repl_subscriber'
  7224.  
  7225.         /*
  7226.         ** Publishing shutdown, remove all xacts pending distribution
  7227.         */
  7228.  
  7229.         /* ensure we can get in as logreader */
  7230.  
  7231.         EXEC sp_replflush
  7232.  
  7233.         /* unmark all xacts marked for replication */
  7234.  
  7235.         EXEC ( "USE " + @dbname + " exec sp_repldone 0, 0, NULL, 0, 0, 1" )
  7236.         EXEC ( "USE " + @dbname + " checkpoint" )
  7237.  
  7238.         /* release our hold on the db as logreader */
  7239.  
  7240.         EXEC sp_replflush
  7241.     end
  7242.  
  7243.     return(0)
  7244. go
  7245.  
  7246. print ''
  7247. print 'Creating procedure sp_subscribe.'
  7248. go
  7249. CREATE PROCEDURE sp_subscribe (
  7250.     @publication varchar(30),          /* publication name */
  7251.     @article varchar(30) = 'all',          /* article name */
  7252.     @destination_db varchar (30) = NULL,  /* subscriber database */
  7253.     @sync_type varchar (15) = 'automatic' /* subscription sync type */
  7254.     ) AS
  7255.  
  7256.     SET NOCOUNT ON
  7257.  
  7258.     /*
  7259.     ** Declarations.
  7260.     */
  7261.  
  7262.     DECLARE @artid int
  7263.     DECLARE @none tinyint
  7264.     DECLARE @automatic tinyint
  7265.     DECLARE @cmd varchar(255)
  7266.     DECLARE @inactive tinyint
  7267.     DECLARE @manual tinyint
  7268.     DECLARE @pubid int
  7269.     DECLARE @restricted bit
  7270.     DECLARE @retcode int
  7271.     DECLARE @srvid smallint
  7272.     DECLARE @sync_typeid smallint
  7273.     DECLARE @subscriber_bit smallint
  7274.  
  7275.     /*
  7276.     ** Security Check
  7277.     ** Only the System Administratr (SA) or the Database Owner (dbo) or
  7278.     ** Replication subscriber (repl_subscriber) can subscribe to an article.
  7279.     */
  7280.  
  7281.     IF suser_id() <> 1 AND user_id() <> 1 AND user_id() <> 16383
  7282.         BEGIN
  7283.             RAISERROR (14093, 14, -1)
  7284.             RETURN (1)
  7285.         END
  7286.  
  7287.     /*
  7288.     ** Initializations.
  7289.     */
  7290.  
  7291.     SELECT @none = 2            /* Const: synchronization type 'none' */
  7292.     SELECT @automatic = 1       /* Const: synchronization type 'automatic' */
  7293.     SELECT @manual = 0          /* Const: synchronization type 'manual' */
  7294.     SELECT @restricted = 1      /* Const: security option 'restricted' */
  7295.     SELECT @inactive = 0        /* Const: subscription status 'inactive' */
  7296.     SELECT @subscriber_bit = 4  /* Const: subscription server status */
  7297.  
  7298.     /*
  7299.     ** Check to make sure that this procedure is not being executed on the
  7300.     ** publisher (locally).
  7301.     */
  7302.  
  7303.     IF @@REMSERVER IS NULL
  7304.         BEGIN
  7305.             RAISERROR (14073, 16, -1)
  7306.             RETURN (1)
  7307.         END
  7308.  
  7309.     SELECT @srvid = srvid
  7310.       FROM master..sysservers
  7311.      WHERE srvname = @@REMSERVER
  7312.        AND (srvstatus & @subscriber_bit) <> 0
  7313.  
  7314.     IF @srvid IS NULL
  7315.         BEGIN
  7316.             RAISERROR (14010, 16, -1)
  7317.            RETURN (1)
  7318.         END
  7319.  
  7320.     /*
  7321.     ** Parameter Check: @publication.
  7322.     ** Check to make sure that the publication exists and that it conforms
  7323.     ** to the rules for identifiers.
  7324.     */
  7325.  
  7326.     IF @publication IS NOT NULL
  7327.         BEGIN
  7328.  
  7329.             EXECUTE @retcode = sp_validname @publication
  7330.  
  7331.             IF @retcode <> 0
  7332.         RETURN (1)
  7333.  
  7334.             IF NOT EXISTS (SELECT * FROM syspublications WHERE name = @publication)
  7335.                 BEGIN
  7336.                     RAISERROR (15001, 11, -1, @publication)
  7337.                     RETURN (1)
  7338.                 END
  7339.  
  7340.         END
  7341.  
  7342.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  7343.  
  7344.     IF @pubid IS NULL
  7345.         BEGIN
  7346.             RAISERROR (14043, 16, -1, 'The publication')
  7347.             RETURN (1)
  7348.         END
  7349.  
  7350.     /*
  7351.     ** Parameter Check:  @article
  7352.     ** Check to make sure that the article exists, is not NULL, and
  7353.     ** conforms to the rules for identifiers.
  7354.     */
  7355.  
  7356.     IF LOWER(@article) = 'all'
  7357.         /*
  7358.     ** Get all articles in the publication that are not subscribed to
  7359.     ** by the @subscriber
  7360.     */
  7361.         BEGIN
  7362.  
  7363.             IF EXISTS (SELECT *
  7364.                          FROM syspublications
  7365.                         WHERE name = @publication
  7366.                           AND restricted = 1)
  7367.  
  7368.                 BEGIN
  7369.  
  7370.                     SELECT DISTINCT 'name' = a.name
  7371.                       INTO #tab1
  7372.                       FROM sysarticles a,
  7373.                            syspublications b,
  7374.                            syssubscriptions c,
  7375.                            master..sysservers d
  7376.                      WHERE a.pubid = b.pubid
  7377.                        AND b.name = @publication
  7378.                        AND a.artid = c.artid
  7379.                        AND c.srvid = d.srvid
  7380.                AND c.status = @inactive
  7381.                        AND d.srvname = @@REMSERVER
  7382.  
  7383.                     CREATE UNIQUE INDEX idx1 ON #tab1 (name)
  7384.                     SELECT @cmd = 'DECLARE hCx SCROLL CURSOR FOR SELECT name FROM #tab1'
  7385.  
  7386.                 END
  7387.  
  7388.             ELSE
  7389.  
  7390.                 BEGIN
  7391.  
  7392.                     SELECT DISTINCT 'name' = a.name
  7393.                       INTO #tab2
  7394.                       FROM sysarticles a, syspublications b
  7395.                      WHERE a.pubid = b.pubid
  7396.                        AND b.name = @publication
  7397.                AND NOT EXISTS (SELECT * from syssubscriptions s
  7398.                   WHERE s.artid = a.artid
  7399.                  AND s.srvid = @srvid)
  7400.  
  7401.                     CREATE UNIQUE INDEX idx1 ON #tab2 (name)
  7402.                     SELECT @cmd = 'DECLARE hCx SCROLL CURSOR FOR SELECT name FROM #tab2'
  7403.  
  7404.                 END
  7405.  
  7406.             /*
  7407.             SELECT @cmd = ''
  7408.             SELECT @cmd = @cmd + 'DECLARE hCx SCROLL CURSOR FOR '
  7409.             SELECT @cmd = @cmd + ' SELECT DISTINCT a.name '
  7410.             SELECT @cmd = @cmd + '   FROM sysarticles a, syspublications b '
  7411.             SELECT @cmd = @cmd + '  WHERE a.pubid = b.pubid '
  7412.             SELECT @cmd = @cmd + '    AND b.name = ''' + @publication + ''''
  7413.             */
  7414.  
  7415.             EXECUTE (@cmd)
  7416.             OPEN hCx
  7417.             FETCH hCx INTO @article
  7418.             WHILE (@@fetch_status <> -1)
  7419.                 BEGIN
  7420.                     EXECUTE sp_subscribe @publication    = @publication,
  7421.                                          @article        = @article,
  7422.                                          @destination_db = @destination_db,
  7423.                                          @sync_type      = @sync_type
  7424.                     FETCH hCx INTO @article
  7425.                 END
  7426.             CLOSE hCx
  7427.             DEALLOCATE hCx
  7428.             RETURN (0)
  7429.         END
  7430.  
  7431.     IF @article IS NULL
  7432.         BEGIN
  7433.             RAISERROR (14043, 16, -1, 'The article')
  7434.             RETURN (1)
  7435.         END
  7436.  
  7437.     SELECT @artid = artid
  7438.       FROM sysarticles
  7439.      WHERE name = @article
  7440.        AND pubid = @pubid
  7441.  
  7442.     EXECUTE @retcode = sp_validname @article
  7443.     IF @retcode <> 0
  7444.     RETURN (1)
  7445.  
  7446.     IF NOT EXISTS (SELECT *
  7447.                      FROM sysarticles
  7448.                     WHERE artid = @artid
  7449.                       AND pubid = @pubid)
  7450.         BEGIN
  7451.             RAISERROR (15001, 11, -1, @article)
  7452.             RETURN (1)
  7453.         END
  7454.  
  7455.     IF @artid IS NULL
  7456.         BEGIN
  7457.             RAISERROR (14043, 16, -1, 'The article')
  7458.             RETURN (1)
  7459.         END
  7460.  
  7461.     /*
  7462.     ** Parameter Check: @sync_type.
  7463.     ** Set sync_typeid based on the @sync_type specified.
  7464.     **
  7465.     **   sync_typeid     sync_type
  7466.     **   ===========     =========
  7467.     **             0     manual
  7468.     **             1     automatic
  7469.     **             2     none
  7470.     */
  7471.  
  7472.     IF LOWER(@sync_type) NOT IN ('automatic', 'manual', 'none')
  7473.         BEGIN
  7474.             RAISERROR (14052, 16, -1)
  7475.             RETURN (1)
  7476.         END
  7477.  
  7478.     IF LOWER(@sync_type) IN ('automatic')
  7479.         SELECT @sync_typeid = @automatic
  7480.     ELSE IF LOWER(@sync_type) IN ('manual')
  7481.         SELECT @sync_typeid = @manual
  7482.     ELSE
  7483.         SELECT @sync_typeid = @none
  7484.  
  7485.     /*
  7486.     ** If it's an automatic sync, ensure that none of the articles
  7487.     ** being subscribed to have the 'owner qualified' status bit set
  7488.     */
  7489.  
  7490.     IF @sync_typeid = @automatic
  7491.     BEGIN
  7492.         IF EXISTS ( SELECT * FROM sysarticles
  7493.                     WHERE artid = @artid AND pubid = @pubid AND
  7494.                     4 = (status & 4) )
  7495.         BEGIN
  7496.             RAISERROR( 14098, 16, -1 )
  7497.             RETURN (1)
  7498.         END
  7499.  
  7500.     END
  7501.  
  7502.  
  7503.     /*
  7504.     ** Parameter Check: @destination_db.
  7505.     ** Set @destination_db to current database if not specified.  Make
  7506.     ** sure that the @destination_db conforms to the rules for identifiers.
  7507.     */
  7508.  
  7509.     IF @destination_db IS NULL SELECT @destination_db = DB_NAME()
  7510.  
  7511.     EXECUTE @retcode = sp_validname @destination_db
  7512.  
  7513.     IF @retcode <> 0
  7514.     RETURN (1)
  7515.  
  7516.     /*
  7517.     ** Bug 12850:
  7518.     ** Make sure that the creation_script is specified if pre_creation_cmd is "drop"
  7519.     ** Note that at this point, @article cannot be all.
  7520.     */
  7521.  
  7522.     if exists (select * from sysarticles where
  7523.             name = @article AND
  7524.             pre_creation_cmd = 1 AND
  7525.             creation_script is null)
  7526.         BEGIN
  7527.             RAISERROR (14096, 16, -1)    
  7528.             RETURN (1)
  7529.         END
  7530.     
  7531.  
  7532.     BEGIN TRAN subscribe
  7533.  
  7534.         /*
  7535.         ** If 'public' publication, add the subscription.  Anyone can subscribe
  7536.         ** to a 'public' publication without intervention from the SA or DBO
  7537.         ** of the publishing server.
  7538.         */
  7539.  
  7540.         IF EXISTS (SELECT *
  7541.                  FROM syspublications
  7542.                 WHERE pubid = @pubid
  7543.                   AND restricted = 0)
  7544.             BEGIN
  7545.  
  7546.                 /*
  7547.                 ** If the subscription already exists, don't add it.
  7548.                 */
  7549.  
  7550.                 IF EXISTS (SELECT *
  7551.                                FROM syssubscriptions
  7552.                             WHERE artid = @artid
  7553.                               AND srvid = @srvid)
  7554.                     BEGIN
  7555.                         ROLLBACK TRAN subscribe
  7556.                         RAISERROR (14058, 16, -1)
  7557.                         RETURN (1)
  7558.                     END
  7559.  
  7560.                 /*
  7561.                 ** The subscription doesn't exist, so let's add it to
  7562.                 ** syssubscriptions.
  7563.                 */
  7564.  
  7565.                 INSERT syssubscriptions VALUES (@artid,
  7566.                                     @srvid,
  7567.                                     @destination_db,
  7568.                                     @inactive,
  7569.                                     @sync_typeid,
  7570.                                     NULL)
  7571.  
  7572.                 IF @@ERROR <> 0
  7573.                 BEGIN
  7574.                 ROLLBACK TRAN subsribe
  7575.                         RAISERROR (14057, 16, -1)
  7576.                 RETURN (1)
  7577.                 END
  7578.  
  7579.             END
  7580.  
  7581.         /*
  7582.         ** If 'restricted' publication, update the subscription.  A restricted
  7583.         ** subscription must already exist in syssubscriptions.  It must be
  7584.         ** created by the SA or DBO on the publishing server using
  7585.         ** sp_addsubscription.  All we need to do is set the status to
  7586.         ** 'subscribe'.
  7587.         */
  7588.  
  7589.         ELSE
  7590.             BEGIN
  7591.  
  7592.             /*
  7593.             ** First, make sure that the SA or DBO on the publishing
  7594.             ** server has created the subscription on the restricted
  7595.             ** publication.
  7596.             */
  7597.  
  7598.             IF NOT EXISTS (SELECT *
  7599.                      FROM syssubscriptions sub,
  7600.                                       syspublications pub,
  7601.                           sysarticles art
  7602.                     WHERE art.artid = @artid
  7603.                       AND pub.pubid = @pubid
  7604.                       AND sub.srvid = @srvid
  7605.                       AND sub.artid = art.artid
  7606.                       AND pub.restricted = @restricted)
  7607.                       /* AND sub.sync_type = @sync_typeid) */
  7608.                 BEGIN
  7609.                 ROLLBACK TRAN subscribe
  7610.                         RAISERROR (14072, 16, -1)
  7611.                 RETURN (1)
  7612.                 END
  7613.  
  7614.             /*
  7615.             ** A subscription exists for the restricted publication.
  7616.             */
  7617.  
  7618.             UPDATE syssubscriptions
  7619.                SET dest_db   = @destination_db,
  7620.                    sync_type = @sync_typeid
  7621.              WHERE srvid = @srvid
  7622.                AND artid = @artid
  7623.  
  7624.             IF @@ERROR <> 0
  7625.                 BEGIN
  7626.                     ROLLBACK TRAN subscribe
  7627.                         RAISERROR (14057, 16, -1)
  7628.                 RETURN (1)
  7629.                 END
  7630.             END
  7631.  
  7632.         /*
  7633.         ** If a sync is required then update the subscription status to
  7634.     ** 'subscribed'. Else, set the subscription status to 'active'.
  7635.         */
  7636.         if @sync_typeid = @none
  7637.         EXEC @retcode = sp_changesubstatus
  7638.             @publication = @publication,
  7639.                         @article     = @article,
  7640.                         @subscriber  = @@REMSERVER,
  7641.                         @status      = 'active'
  7642.     else
  7643.         EXEC @retcode = sp_changesubstatus
  7644.             @publication = @publication,
  7645.                         @article     = @article,
  7646.                         @subscriber  = @@REMSERVER,
  7647.                         @status      = 'subscribed'
  7648.  
  7649.         IF @@ERROR <> 0 OR @retcode <> 0
  7650.             BEGIN
  7651.                ROLLBACK TRAN subscribe
  7652.                    RAISERROR (14057, 16, -1)
  7653.                RETURN (1)
  7654.             END
  7655.  
  7656.     COMMIT TRAN subscribe
  7657. go
  7658.  
  7659. print ''
  7660. print 'Creating procedure sp_MSuninstall_publishing.'
  7661. go
  7662. CREATE PROCEDURE sp_MSuninstall_publishing
  7663.  
  7664. AS
  7665.  
  7666.     DECLARE @cmd varchar(255)
  7667.     DECLARE @name varchar(30)
  7668.     DECLARE @distname varchar(30)
  7669.     DECLARE @distdb varchar(30)
  7670.     DECLARE @proc varchar(255)
  7671.  
  7672.     /*
  7673.     ** Unpublish all published databases.
  7674.     */
  7675.         SELECT @cmd = ''
  7676.         SELECT @cmd = @cmd + 'DECLARE hC CURSOR FOR '
  7677.         SELECT @cmd = @cmd + 'SELECT name FROM master..sysdatabases '
  7678.         SELECT @cmd = @cmd + 'WHERE (category & 1) <> 0'
  7679.         EXECUTE (@cmd)
  7680.         OPEN hC
  7681.         FETCH hC INTO @name
  7682.         WHILE (@@fetch_status <> -1)
  7683.             BEGIN
  7684.             SELECT @name
  7685.                 EXECUTE sp_dboption @name, published, FALSE
  7686.                 FETCH hC INTO @name
  7687.             END
  7688.         CLOSE hC
  7689.         DEALLOCATE hC
  7690.  
  7691.     /*
  7692.     ** Drop all subscribers
  7693.     */
  7694.         SELECT @cmd = ''
  7695.         SELECT @cmd = @cmd + 'DECLARE hC CURSOR FOR '
  7696.         SELECT @cmd = @cmd + 'SELECT srvname FROM master..sysservers '
  7697.         SELECT @cmd = @cmd + 'WHERE (srvstatus & 4) <> 0'
  7698.         EXECUTE (@cmd)
  7699.         OPEN hC
  7700.         FETCH hC INTO @name
  7701.         WHILE (@@fetch_status <> -1)
  7702.             BEGIN
  7703.                 EXECUTE sp_dropsubscriber @name
  7704.                 FETCH hC INTO @name
  7705.             END
  7706.         CLOSE hC
  7707.         DEALLOCATE hC
  7708.  
  7709.     /*
  7710.     ** Remove the publish option on the server
  7711.     */
  7712.     EXECUTE sp_serveroption @@SERVERNAME, pub, FALSE
  7713.  
  7714.     /*
  7715.     ** Remove the publish option on the server
  7716.     */
  7717.     IF @distname IS NOT NULL
  7718.         EXECUTE sp_serveroption @@SERVERNAME, pub, FALSE
  7719.  
  7720.     /*
  7721.     ** Get the distribution server name
  7722.     */
  7723.         SELECT @distname = srvname FROM master..sysservers
  7724.         WHERE (srvstatus & 8) <> 0
  7725.  
  7726.     /*
  7727.     ** If this is a distribution server drop the distribution database
  7728.     ** and remove distribution registry entry
  7729.     */
  7730.     IF @distname = @@SERVERNAME
  7731.     BEGIN
  7732.         /*
  7733.         ** If there are distribution publishers, do not drop the
  7734.         ** distribution database
  7735.         */
  7736.         IF EXISTS (SELECT * FROM master..sysservers where
  7737.             (srvstatus & 16) <> 0)
  7738.         BEGIN
  7739.            RETURN (0)
  7740.         END
  7741.  
  7742.         /*
  7743.         ** Get the distribution database name from the Registry
  7744.         */
  7745.         SELECT @proc = 'master..xp_regread '
  7746.         EXECUTE @proc 'HKEY_LOCAL_MACHINE',
  7747.               'SOFTWARE\Microsoft\MSSQLServer\Replication',
  7748.               'DistributionDB',
  7749.             @param = @distdb OUTPUT
  7750.  
  7751.         /*
  7752.         ** Drop the distribution database
  7753.         */
  7754.         EXECUTE ('DROP DATABASE ' + @distdb)
  7755.  
  7756.         /*
  7757.         ** Clear the distribution registry values
  7758.         */
  7759.         EXECUTE master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  7760.                                    'SOFTWARE\Microsoft\MSSQLServer\Replication',
  7761.                                    'DistributionDB',REG_SZ, ''
  7762.     END        
  7763.  
  7764.     /*
  7765.     ** Remove the distribution option on the server
  7766.     */
  7767.     IF @distname IS NOT NULL
  7768.         EXECUTE sp_serveroption @distname, dist, FALSE
  7769.  
  7770.        /* 
  7771.        ** Drop all remote servers that have the DSN option set 
  7772.        */
  7773.         SELECT @cmd = ''
  7774.         SELECT @cmd = @cmd + 'DECLARE hC CURSOR FOR '
  7775.         SELECT @cmd = @cmd + 'SELECT srvname FROM master..sysservers '
  7776.         SELECT @cmd = @cmd + 'WHERE (srvstatus & 32) <> 0'
  7777.         EXECUTE (@cmd)
  7778.         OPEN hC
  7779.         FETCH hC INTO @name
  7780.         WHILE (@@fetch_status <> -1)
  7781.             BEGIN
  7782.                 EXECUTE sp_dropserver @name
  7783.                 FETCH hC INTO @name
  7784.             END
  7785.         CLOSE hC
  7786.         DEALLOCATE hC
  7787. GO
  7788.  
  7789. print ''
  7790. print 'Creating procedure sp_unsubscribe.'
  7791. go
  7792. CREATE PROCEDURE sp_unsubscribe (
  7793.     @publication varchar(30) = NULL,       /* publication name */
  7794.     @article varchar(30) = NULL            /* article name */
  7795.     ) AS
  7796.  
  7797.     SET NOCOUNT ON
  7798.  
  7799.     /*
  7800.     ** Declarations.
  7801.     */
  7802.  
  7803.     DECLARE @cmd varchar(255)
  7804.     DECLARE @pubid int
  7805.     DECLARE @artid int
  7806.     DECLARE @public tinyint
  7807.     DECLARE @srvid smallint
  7808.     DECLARE @subscriber_bit smallint
  7809.     DECLARE @retcode int
  7810.     DECLARE @active tinyint
  7811.  
  7812.     /*
  7813.     ** Security Check
  7814.     ** Only the System Administratr (SA) or the Database Owner (dbo) or
  7815.     ** Replication subscriber (repl_subscriber) can unsubscribe from an article.
  7816.     */
  7817.  
  7818.     IF suser_id() <> 1 AND user_id() <> 1 AND user_id() <> 16383
  7819.         BEGIN
  7820.             RAISERROR (14093, 14, -1)
  7821.             RETURN (1)
  7822.         END
  7823.  
  7824.     /*
  7825.     ** Initializations.
  7826.     */
  7827.  
  7828.     SELECT @public = 0          /* Const: security = 'public'. */
  7829.     SELECT @subscriber_bit = 4  /* Const: subscription server status */
  7830.     SELECT @active = 2          /* Const: subscription status 'active' */
  7831.  
  7832.     /*
  7833.     ** Check to make sure that this procedure is not being executed on the
  7834.     ** publisher (locally).
  7835.     */
  7836.  
  7837.     IF @@REMSERVER IS NULL
  7838.         BEGIN
  7839.             RAISERROR (14073, 16, -1)
  7840.             RETURN (1)
  7841.         END
  7842.  
  7843.     /*
  7844.     ** Check if the server exists and that it is a subscription server.
  7845.     */
  7846.  
  7847.     SELECT @srvid = srvid
  7848.                  FROM sysservers
  7849.                     WHERE srvname = @@REMSERVER
  7850.                       AND (srvstatus & @subscriber_bit) <> 0
  7851.     IF @srvid IS NULL
  7852.         BEGIN
  7853.             RAISERROR (14010, 16, -1)
  7854.         RETURN (1)
  7855.         END
  7856.  
  7857.     /*
  7858.     ** If the @publication is 'all' the user wants to cancel all
  7859.     ** @publication @article subscriptions.
  7860.     */
  7861.  
  7862.     IF LOWER(@publication) = 'all'
  7863.         BEGIN
  7864.  
  7865.             SELECT DISTINCT a.name
  7866.               INTO #unsubscribe1
  7867.               FROM syspublications a,
  7868.                    sysarticles b,
  7869.                    syssubscriptions c
  7870.              WHERE c.srvid = @srvid
  7871.                AND c.artid = b.artid
  7872.                AND b.pubid = a.pubid
  7873.  
  7874.             CREATE UNIQUE INDEX idx1 ON #unsubscribe1 (name)
  7875.  
  7876.             SELECT @cmd = 'DECLARE hC1 SCROLL CURSOR FOR SELECT * FROM #unsubscribe1'
  7877.             EXECUTE (@cmd)
  7878.  
  7879.             OPEN hC1
  7880.             FETCH hC1 INTO @publication
  7881.  
  7882.             WHILE (@@fetch_status <> -1)
  7883.                 BEGIN
  7884.                     EXECUTE sp_unsubscribe @publication, 'all'
  7885.                     FETCH hC1 INTO @publication
  7886.                 END
  7887.             CLOSE hC1
  7888.             DEALLOCATE hC1
  7889.             RETURN (0)
  7890.         END
  7891.  
  7892.     /*
  7893.     ** Parameter Check:  @publication.
  7894.     ** Check to make sure that the publication exists.
  7895.     */
  7896.  
  7897.     IF @publication IS NOT NULL
  7898.         BEGIN
  7899.  
  7900.             EXECUTE @retcode = sp_validname @publication
  7901.  
  7902.             IF @retcode <> 0
  7903.         RETURN (1)
  7904.  
  7905.             IF NOT EXISTS (SELECT * FROM syspublications WHERE name = @publication)
  7906.                 BEGIN
  7907.                     RAISERROR (15001, 11, -1, @publication)
  7908.                     RETURN (1)
  7909.                 END
  7910.  
  7911.         END
  7912.  
  7913.     SELECT @pubid = pubid FROM syspublications WHERE name = @publication
  7914.  
  7915.     IF @pubid IS NULL
  7916.         BEGIN
  7917.             RAISERROR (14043, 16, -1, 'The publication')
  7918.             RETURN (1)
  7919.         END
  7920.  
  7921.     /*
  7922.     ** If the @article is 'all', the user wants to cancel all subscriptions
  7923.     ** for the publication.
  7924.     */
  7925.  
  7926.     IF LOWER(@article) = 'all'
  7927.         BEGIN
  7928.  
  7929.             SELECT a.name
  7930.               INTO #unsubscribe2
  7931.               FROM sysarticles a,
  7932.                    syssubscriptions b
  7933.              WHERE a.pubid = @pubid
  7934.                AND b.srvid = @srvid
  7935.                AND b.artid = a.artid
  7936.  
  7937.             CREATE UNIQUE INDEX idx1 ON #unsubscribe2 (name)
  7938.  
  7939.             SELECT @cmd = 'DECLARE hC2 SCROLL CURSOR FOR SELECT * FROM #unsubscribe2'
  7940.             EXECUTE (@cmd)
  7941.  
  7942.             OPEN hC2
  7943.             FETCH hC2 INTO @article
  7944.  
  7945.             WHILE (@@fetch_status <> -1)
  7946.                 BEGIN
  7947.                     EXECUTE sp_unsubscribe @publication, @article
  7948.                     FETCH hC2 INTO @article
  7949.                 END
  7950.             CLOSE hC2
  7951.             DEALLOCATE hC2
  7952.             RETURN (0)
  7953.         END
  7954.  
  7955.     /*
  7956.     ** Parameter Check:  @article.
  7957.     ** Check to make sure that the article exists.
  7958.     */
  7959.  
  7960.     SELECT @artid = artid
  7961.       FROM sysarticles
  7962.      WHERE name = @article
  7963.        AND pubid = @pubid
  7964.  
  7965.     IF @article IS NOT NULL
  7966.         BEGIN
  7967.             EXECUTE @retcode = sp_validname @article
  7968.             IF @retcode <> 0
  7969.         RETURN (1)
  7970.  
  7971.         IF NOT EXISTS (SELECT *
  7972.                              FROM sysarticles
  7973.                             WHERE artid = @artid
  7974.                               AND pubid = @pubid)
  7975.                 BEGIN
  7976.                     RAISERROR (15001, 11, -1, @article)
  7977.                     RETURN (1)
  7978.                 END
  7979.         END
  7980.  
  7981.     IF @artid IS NULL
  7982.         BEGIN
  7983.             RAISERROR (14043, 16, -1, 'The article')
  7984.             RETURN (1)
  7985.         END
  7986.  
  7987.     IF NOT EXISTS (SELECT *
  7988.                      FROM syssubscriptions a,
  7989.                           sysarticles b,
  7990.                           syspublications c
  7991.                     WHERE a.srvid = @srvid
  7992.                       AND a.artid = b.artid
  7993.                       AND b.pubid = c.pubid
  7994.                       AND c.pubid = @pubid
  7995.                       AND a.status <> 0)
  7996.         BEGIN
  7997.             RAISERROR (14050, 11, -1)
  7998.             RETURN (1)
  7999.         END
  8000.  
  8001.     BEGIN TRAN unsubscribe
  8002.  
  8003.         /*
  8004.         ** Change the status of the subscription to 'inactive', then delete
  8005.         ** subscription row.  If the subscription is a public subscription,
  8006.         ** it can safely be deleted.
  8007.         */
  8008.  
  8009.         /*
  8010.         ** Change the status of the subscription to 'inactive'.
  8011.         */
  8012.  
  8013.         EXECUTE @retcode  = sp_changesubstatus @publication = @publication,
  8014.                                    @article     = @article,
  8015.                                                @subscriber  = @@REMSERVER,
  8016.                                                @status      = 'inactive'
  8017.  
  8018.         IF @@ERROR <> 0 OR @retcode <> 0
  8019.             BEGIN
  8020.                 ROLLBACK TRAN unsubscribe
  8021.                 RAISERROR (14056, 16, -1)
  8022.                 RETURN (1)
  8023.             END
  8024.  
  8025.         /*
  8026.         ** If the publication is 'public', delete the subscription.
  8027.         */
  8028.  
  8029.         IF EXISTS (SELECT *
  8030.                      FROM syspublications
  8031.                     WHERE pubid = @pubid
  8032.                       AND restricted = @public)
  8033.             BEGIN
  8034.  
  8035.                 DELETE syssubscriptions
  8036.                  WHERE srvid = @srvid
  8037.                    AND artid = @artid
  8038.  
  8039.             IF @@ERROR <> 0
  8040.                 BEGIN
  8041.                     ROLLBACK TRAN unsubscribe
  8042.                         RAISERROR (14056, 16, -1)
  8043.                     RETURN (1)
  8044.                 END
  8045.             END
  8046.  
  8047.     COMMIT TRAN unsubscribe
  8048.  
  8049. go
  8050.  
  8051. print ''
  8052. print 'Creating procedure sp_create_distribution_tables.'
  8053. go
  8054. CREATE PROCEDURE sp_create_distribution_tables
  8055. AS
  8056.  
  8057. BEGIN
  8058.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSjobs' and type = 'U')
  8059.    BEGIN
  8060.       /****************************************************************************/
  8061.       PRINT ''
  8062.       PRINT 'Creating Table:  dbo.MSjobs'
  8063.       PRINT ''
  8064.       /****************************************************************************/
  8065.       CREATE TABLE MSjobs
  8066.       (
  8067.       publisher_id smallint,
  8068.       publisher_db varchar (  30 ) ,
  8069.       job_id int,
  8070.       type tinyint, /* 0- sql cmd 1-noop cmd 2-sql script 3/4-bcp cmd 5-manual sync*/
  8071.       xactid_page int,
  8072.       xactid_row smallint,
  8073.       xactid_ts binary (  8 ) ,
  8074.       entry_time datetime
  8075.       )
  8076.  
  8077.       /* Set category bit to reflect MS objects */
  8078.       UPDATE sysobjects SET category = category | 2 WHERE sysstat & 0xf = 3 AND
  8079.          name = 'MSjobs'
  8080.  
  8081.       PRINT ''
  8082.       PRINT 'Creating Clustered Index: ucMSjobs'
  8083.       PRINT ''
  8084.       CREATE UNIQUE CLUSTERED INDEX ucMSjobs ON dbo.MSjobs
  8085.          (publisher_db, publisher_id, job_id)
  8086.    END
  8087.  
  8088.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSjob_commands' and type = 'U')
  8089.    BEGIN
  8090.       /****************************************************************************/
  8091.       PRINT ''
  8092.       PRINT 'Creating Table:  dbo.MSjob_commands'
  8093.       PRINT ''
  8094.       /****************************************************************************/
  8095.       CREATE TABLE MSjob_commands (
  8096.       publisher_id smallint,
  8097.       publisher_db varchar (  30 ) ,
  8098.       job_id int,
  8099.       command_id int,
  8100.       art_id int,
  8101.       incomplete bit,
  8102.       command varchar (  255 ) NULL
  8103.       )
  8104.       /* Set category bit to reflect MS objects */
  8105.       UPDATE sysobjects SET category = category | 2 WHERE sysstat & 0xf = 3 AND
  8106.          name = 'MSjob_commands'
  8107.  
  8108.       PRINT ''
  8109.       PRINT 'Creating Clustered Index: ucMSjob_commands'
  8110.       PRINT ''
  8111.       CREATE UNIQUE CLUSTERED INDEX ucMSjob_commands ON dbo.MSjob_commands
  8112.          (publisher_db, publisher_id, job_id, command_id)
  8113.    END
  8114.  
  8115.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSsubscriber_jobs' and type = 'U')
  8116.    BEGIN
  8117.       /****************************************************************************/
  8118.       PRINT ''
  8119.       PRINT 'Creating Table:  dbo.MSsubscriber_jobs'
  8120.       PRINT ''
  8121.       /****************************************************************************/
  8122.       CREATE TABLE MSsubscriber_jobs
  8123.       (
  8124.       publisher_id smallint,
  8125.       publisher_db varchar (30),
  8126.       job_id int,
  8127.       subscriber_id smallint,
  8128.       subscriber_db varchar (  30 ) ,
  8129.       command_id int
  8130.       )
  8131.  
  8132.       /* Set category bit to reflect MS objects */
  8133.       UPDATE sysobjects SET category = category | 2 WHERE sysstat & 0xf = 3 AND
  8134.           name = 'MSsubscriber_jobs'
  8135.  
  8136.       PRINT ''
  8137.       PRINT 'Creating Clusteredd Index: ucMSsubscriber_jobs'
  8138.       PRINT ''
  8139.       CREATE UNIQUE CLUSTERED INDEX ucMSsubscriber_jobs ON dbo.MSsubscriber_jobs
  8140.          (publisher_db, publisher_id, subscriber_db, subscriber_id, job_id, command_id)
  8141.  
  8142.       PRINT ''
  8143.       PRINT 'Creating NonClustered Index: ncMSsubscriber_jobs'
  8144.       PRINT ''
  8145.       CREATE NONCLUSTERED INDEX ncMSsubscriber_jobs ON dbo.MSsubscriber_jobs
  8146.          (publisher_db, publisher_id, job_id)
  8147.    END
  8148.  
  8149.  
  8150.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSsubscriber_status' and type = 'U')
  8151.    BEGIN
  8152.       /****************************************************************************/
  8153.       PRINT ''
  8154.       PRINT 'Creating Table:  dbo.MSsubscriber_status'
  8155.       PRINT ''
  8156.       /****************************************************************************/
  8157.       CREATE TABLE MSsubscriber_status
  8158.       (
  8159.       publisher_id smallint,
  8160.       publisher_db varchar (  30 ) ,
  8161.       job_id int,
  8162.       subscriber_id smallint,
  8163.       subscriber_db varchar (  30 ) ,
  8164.       completion_time datetime,
  8165.       delivery_latency int,
  8166.       delivered_jobs int,
  8167.       delivery_rate int,
  8168.       status int
  8169.       )
  8170.  
  8171.       /* Set category bit to reflect MS objects */
  8172.       UPDATE sysobjects SET category = category | 2 WHERE sysstat & 0xf = 3 AND
  8173.          name = 'MSsubscriber_status'
  8174.  
  8175.       PRINT ''
  8176.       PRINT 'Creating Clustered Index: ucMSsubscriber_status'
  8177.       PRINT ''
  8178.       CREATE UNIQUE CLUSTERED INDEX ucMSsubscriber_status on dbo.MSsubscriber_status
  8179.        (publisher_db, publisher_id, subscriber_db, subscriber_id, job_id)
  8180.  
  8181.    END
  8182.  
  8183.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSsubscriber_info' and type = 'U')
  8184.    BEGIN
  8185.       /****************************************************************************/
  8186.       PRINT ''
  8187.       PRINT 'Creating Table:  dbo.MSsubscriber_info'
  8188.       PRINT ''
  8189.       /****************************************************************************/
  8190.       CREATE TABLE MSsubscriber_info
  8191.       (
  8192.       publisher  varchar (30),
  8193.       subscriber  varchar (30),
  8194.       type tinyint,           /* 0: MS SQL Server 1: ODBC Data Source */
  8195.       login varchar(30) NULL,
  8196.       password varchar(30) NULL,
  8197.       commit_batch_size int,
  8198.       status_batch_size int,
  8199.       flush_frequency int,
  8200.       frequency_type int,
  8201.       frequency_interval int,
  8202.       frequency_relative_interval int,
  8203.       frequency_recurrence_factor int,
  8204.       frequency_subday int,
  8205.       frequency_subday_interval int,
  8206.       active_start_time_of_day int,
  8207.       active_end_time_of_day int,
  8208.       active_start_date int,
  8209.       active_end_date int,
  8210.       retryattempts int,
  8211.       retrydelay int,
  8212.       description varchar(255) NULL,
  8213.       )
  8214.  
  8215.       /* Set category bit to reflect MS objects */
  8216.       UPDATE sysobjects SET category = category | 2 WHERE sysstat & 0xf = 3 AND
  8217.      name = 'MSsubscriber_info'
  8218.  
  8219.       PRINT ''
  8220.       PRINT 'Creating Clustered Index: ucMSsubscriber_info'
  8221.       PRINT ''
  8222.       CREATE UNIQUE CLUSTERED INDEX ucMSsubscriber_info ON dbo.MSsubscriber_info
  8223.      (publisher, subscriber)
  8224.    END
  8225.    ELSE
  8226.    BEGIN
  8227.       IF NOT EXISTS (select * from syscolumns
  8228.         where name = 'description'
  8229.         and id=object_id('MSsubscriber_info'))
  8230.       BEGIN
  8231.          /****************************************************************************/
  8232.          PRINT ''
  8233.          PRINT 'Alter Table:  dbo.MSsubscriber_info'
  8234.          PRINT ''
  8235.          /****************************************************************************/
  8236.          ALTER TABLE MSsubscriber_info ADD description varchar (255) NULL
  8237.      UPDATE MSsubscriber_info SET description = 'SQL Server 6.0'
  8238.       END
  8239.    END
  8240.  
  8241.    IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSjob_subscriptions' and type = 'U')
  8242.    BEGIN
  8243.       /****************************************************************************/
  8244.       PRINT ''
  8245.       PRINT 'Creating Table:  dbo.MSjob_subscriptions'
  8246.       PRINT ''
  8247.       /****************************************************************************/
  8248.       CREATE TABLE MSjob_subscriptions
  8249.       (
  8250.       publisher varchar ( 30 ),
  8251.       publisher_id smallint,
  8252.       publisher_db varchar (  30 ) ,
  8253.       subscriber varchar ( 30 ),
  8254.       subscriber_id smallint,
  8255.       art_id int,
  8256.       subscriber_db varchar (  30 ) ,
  8257.       status tinyint,
  8258.       ts binary (8)
  8259.       )
  8260.  
  8261.       /* Set category bit to reflect MS objects */
  8262.       UPDATE sysobjects SET category = category | 2 WHERE sysstat & 0xf = 3 AND
  8263.      name = 'MSjob_subscriptions'
  8264.  
  8265.       PRINT ''
  8266.       PRINT 'Creating Clustered Index: ucMSsubscriptions'
  8267.       PRINT ''
  8268.       CREATE UNIQUE CLUSTERED INDEX ucMSsubscriptions ON dbo.MSjob_subscriptions
  8269.      (publisher_db, publisher_id, art_id, subscriber_id)
  8270.    END
  8271. END
  8272. GO
  8273.  
  8274.  
  8275.  
  8276. if exists (select * from sysobjects
  8277.         where sysstat & 0xf = 4
  8278.             and name = 'sp_repldone')
  8279.     exec sp_dropextendedproc 'sp_repldone'
  8280. go
  8281.  
  8282. if exists (select * from sysobjects
  8283.         where sysstat & 0xf = 4
  8284.             and name = 'sp_repltrans')
  8285.     exec sp_dropextendedproc 'sp_repltrans'
  8286. go
  8287.  
  8288. if exists (select * from sysobjects
  8289.         where sysstat & 0xf = 4
  8290.             and name = 'sp_replcmds')
  8291.     exec sp_dropextendedproc 'sp_replcmds'
  8292. go
  8293.  
  8294. if exists (select * from sysobjects
  8295.         where sysstat & 0xf = 4
  8296.             and name = 'sp_replcounters')
  8297.     exec sp_dropextendedproc 'sp_replcounters'
  8298. go
  8299.  
  8300. if exists (select * from sysobjects
  8301.         where sysstat & 0xf = 4
  8302.             and name = 'sp_replflush')
  8303.     exec sp_dropextendedproc 'sp_replflush'
  8304. go
  8305.  
  8306. if exists (select * from sysobjects
  8307.         where sysstat & 0xf = 4
  8308.             and name = 'sp_replstatus')
  8309.     exec sp_dropextendedproc 'sp_replstatus'
  8310. go
  8311.  
  8312. /*
  8313. ** Add extended stored procedures for replication support.
  8314. */
  8315. sp_addextendedproc  'sp_repldone', 'repldone extended procedure'
  8316. go
  8317.  
  8318. sp_addextendedproc  'sp_repltrans', 'repltrans extended procedure'
  8319. go
  8320.  
  8321. sp_addextendedproc  'sp_replcounters', 'replcounters extended procedure'
  8322. go
  8323.  
  8324. sp_addextendedproc  'sp_replcmds', 'replcmds extended procedure'
  8325. go
  8326.  
  8327. sp_addextendedproc  'sp_replflush', 'replflush extended procedure'
  8328. go
  8329.  
  8330. sp_addextendedproc  'sp_replstatus', 'replstatus extended procedure'
  8331. go
  8332.  
  8333. print ''
  8334. print 'Adding logins and users for replication.'
  8335. print ''
  8336. go
  8337. /*
  8338. **  Add the login and user named 'repl_subscriber'.  These are used when a
  8339. **  replication publisher.  Use the maximum user id for the login id.
  8340. */
  8341. if not exists (select * from syslogins where name = 'repl_subscriber')
  8342.     insert into syslogins (suid,status,accdate,totcpu,totio,spacelimit,
  8343.             timelimit,resultlimit,dbname,name,password,language)
  8344.     values (16383, 9, getdate(), 0, 0, 0, 0, 0,'master','repl_subscriber',
  8345.             pwdencrypt(convert(char(30),@@dbts)),NULL)
  8346. go
  8347.  
  8348. if not exists (select * from sysusers where name = 'repl_subscriber')
  8349.     exec sp_adduser 'repl_subscriber'
  8350. go
  8351.  
  8352. /*
  8353. **  Add the login and user named 'repl_publisher'.  This is used when a
  8354. **  replication subscriber.
  8355. */
  8356. if not exists (select * from syslogins where name = 'repl_publisher')
  8357.     insert into syslogins (suid,status,accdate,totcpu,totio,spacelimit,
  8358.             timelimit,resultlimit,dbname,name,password,language)
  8359.     values (16382, 9, getdate(), 0, 0, 0, 0, 0,'master','repl_publisher',
  8360.             pwdencrypt(convert(char(30),@@dbts)),NULL)
  8361. go
  8362.  
  8363. /*
  8364. ** Add xp_enum_dsn extended procedure
  8365. */
  8366. sp_addextendedproc 'xp_dsninfo','xpsql60.dll'
  8367. go
  8368.  
  8369. /*
  8370. ** Add xp_enum_dsn extended procedure
  8371. */
  8372. sp_addextendedproc 'xp_enumdsn','xpsql60.dll'
  8373. go
  8374.  
  8375. grant execute on sp_addarticle to public
  8376. go
  8377. grant execute on sp_addpublication to public
  8378. go
  8379. grant execute on sp_addsubscription to public
  8380. go
  8381. grant execute on sp_articlecolumn to public
  8382. go
  8383. grant execute on sp_articlefilter to public
  8384. go
  8385. grant execute on sp_articletextcol to public
  8386. go
  8387. grant execute on sp_articleview to public
  8388. go
  8389. grant execute on sp_changearticle to public
  8390. go
  8391. grant execute on sp_changepublication to public
  8392. go
  8393. grant execute on sp_changesubscription to public
  8394. go
  8395. grant execute on sp_distcounters to public
  8396. go
  8397. grant execute on sp_droparticle to public
  8398. go
  8399. grant execute on sp_droppublication to public
  8400. go
  8401. grant execute on sp_dropsubscription to public
  8402. go
  8403. grant execute on sp_helparticle to public
  8404. go
  8405. grant execute on sp_helparticlecolumns to public
  8406. go
  8407. grant execute on sp_helpdistributor to public
  8408. go
  8409. grant execute on sp_helppublication to public
  8410. go
  8411. grant execute on sp_helppublicationsync to public
  8412. go
  8413. grant execute on sp_helpreplicationdb to public
  8414. go
  8415. grant execute on sp_helpsubscription to public
  8416. go
  8417. grant execute on sp_helpsubscriberinfo to public
  8418. go
  8419. grant execute on sp_replcounters to probe
  8420. go
  8421. grant execute on sp_replstatus to public
  8422. go
  8423. grant execute on sp_subscribe to public
  8424. go
  8425. grant execute on sp_textcolstatus to public
  8426. go
  8427. grant execute on sp_unsubscribe to public
  8428. go
  8429.  
  8430. sp_configure 'allow updates',0
  8431. go
  8432. reconfigure with override
  8433. go
  8434.  
  8435. print ''
  8436. print 'Checking objects created by instrepl.sql.'
  8437. go
  8438.  
  8439. --obsolete   exec sp_check_objects 'repl'
  8440. exec sp_MS_upd_sysobj_category 2  --set sysobjects.category | 2 based on crdate.
  8441. go
  8442.  
  8443. print ''
  8444. print 'instrepl.sql completed successfully.'
  8445. go
  8446.  
  8447. dump tran master with no_log
  8448. go
  8449. checkpoint
  8450. go
  8451. -- - -----
  8452.