home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Internet Business Development Kit / PRODUCT_CD.iso / sqlsvr / i386 / instrepl.sql < prev    next >
Encoding:
Text File  |  1995-12-08  |  231.7 KB  |  8,325 lines

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