SQL Server 2005事务复制无法发布包含索引创建的存储过程

Mic*_*son 7 sql sql-server replication sql-server-2005 transactional-replication

我遇到过SQL Server 2005 Transactional Publication的一个奇怪问题.问题是:如果发布包含的文章是包含create index语句的存储过程,则在尝试将存储过程的模式复制到订阅服务器时会引发错误.

这种行为非常奇怪,因为即使创建索引语句被注释掉,它仍然会给出异常,并且只有在完全删除它时它才会起作用.

这是返回的确切错误:

尝试的命令:GRANT EXECUTE ON [dbo].[usp_Test] TO [CompanyDatabase_access]

(事务序列号:0x00000170000008B9000500000000,命令ID:5)

错误消息:找不到对象'us​​p_Test',因为它不存在或您没有权限.(来源:MSSQLServer,错误号:15151)获取帮助:http:// help/15151 无法找到对象'us​​p_Test',因为它不存在或您没有权限.(来源:MSSQLServer,错误号:15151)获取帮助:http:// help/15151

错误是准确的,因为当我检查订阅者时,存储过程未按预期创建...但这是出版物的目的......

此外,我可以在订阅服务器上手动创建存储过程,但是当我生成快照时,它会删除现有的存储过程,然后仍然会返回此错误消息.

这是一个创建此问题的示例出版物.

存储过程:

USE [CompanyDatabase]
GO

CREATE PROCEDURE [dbo].[usp_Test]

AS

CREATE TABLE #TempTable(ID INT)
CREATE NONCLUSTERED INDEX [IX_TempTable] ON [dbo].[#TempTable](ID)
SELECT 'Test'
GO

GRANT EXECUTE ON [dbo].[usp_Test] TO [CompanyDatabase_access]
GO
Run Code Online (Sandbox Code Playgroud)

出版脚本:

-- Adding the transactional publication
use [CompanyDatabase]
exec sp_addpublication 
    @publication = N'Replication Test', 
    @description = N'Publication of database ''CompanyDatabase''.', 
    @sync_method = N'concurrent', 
    @retention = 0, 
    @allow_push = N'true', 
    @allow_pull = N'true', 
    @allow_anonymous = N'false', 
    @enabled_for_internet = N'false', 
    @snapshot_in_defaultfolder = N'true', 
    @compress_snapshot = N'false', 
    @ftp_port = 21, 
    @ftp_login = N'anonymous', 
    @allow_subscription_copy = N'false', 
    @add_to_active_directory = N'false', 
    @repl_freq = N'continuous', 
    @status = N'active', @independent_agent = N'true', 
    @immediate_sync = N'false', 
    @allow_sync_tran = N'false', 
    @autogen_sync_procs = N'false', 
    @allow_queued_tran = N'false', 
    @allow_dts = N'false', 
    @replicate_ddl = 1, 
    @allow_initialize_from_backup = N'false', 
    @enabled_for_p2p = N'false', 
    @enabled_for_het_sub = N'false'
GO

-- Adding the transactional articles
use [CompanyDatabase]
exec sp_addarticle 
    @publication = N'Replication Test', 
    @article = N'usp_Test', 
    @source_owner = N'dbo', 
    @source_object = N'usp_Test', 
    @type = N'proc schema only', 
    @description = N'', 
    @creation_script = N'', 
    @pre_creation_cmd = N'drop', 
    @schema_option = 0x0000000048000001, 
    @destination_table = N'usp_Test', 
    @destination_owner = N'dbo', 
    @status = 16
GO

-- Adding the transactional subscriptions
use [CompanyDatabase]
exec sp_addsubscription 
    @publication = N'Replication Test', 
    @subscriber = N'OtherDatabaseServer', 
    @destination_db = N'CompanyDatabase', 
    @subscription_type = N'Pull', 
    @sync_type = N'automatic', 
    @article = N'all', 
    @update_mode = N'read only', 
    @subscriber_type = 0
GO
Run Code Online (Sandbox Code Playgroud)

订阅脚本:

/****** Begin: Script to be run at Subscriber ******/
use [CompanyDatabase]
exec sp_addpullsubscription 
    @publisher = N'DatabaseServer', 
    @publication = N'Replication Test', 
    @publisher_db = N'CompanyDatabase', 
    @independent_agent = N'True', 
    @subscription_type = N'pull', 
    @description = N'', 
    @update_mode = N'read only', 
    @immediate_sync = 0

exec sp_addpullsubscription_agent 
    @publisher = N'DatabaseServer', 
    @publisher_db = N'CompanyDatabase', 
    @publication = N'Replication Test', 
    @distributor = N'DatabaseServer', 
    @distributor_security_mode = 1, 
    @distributor_login = N'', 
    @distributor_password = N'', 
    @enabled_for_syncmgr = N'False', 
    @frequency_type = 64, 
    @frequency_interval = 0, 
    @frequency_relative_interval = 0, 
    @frequency_recurrence_factor = 0, 
    @frequency_subday = 0, 
    @frequency_subday_interval = 0, 
    @active_start_time_of_day = 0, 
    @active_end_time_of_day = 235959, 
    @active_start_date = 0, 
    @active_end_date = 0, 
    @alt_snapshot_folder = N'', 
    @working_directory = N'', 
    @use_ftp = N'False', 
    @job_login = null, 
    @job_password = null, 
    @publication_type = 0
GO
/****** End: Script to be run at Subscriber ******/
Run Code Online (Sandbox Code Playgroud)

同样,奇怪的是,如果创建索引语句被注释掉,则发布仍将包含相同的错误,但如果将其完全删除则它将起作用.

现在,我刚刚从发布中删除了包含这些创建索引语句的所有存储过程,但我希望将它们复制到订阅者,以便对过程的任何DDL更新将自动反映在订阅者身上.

- 编辑 -

查看快照目录,usp_Test的.sch文件包含我之前为存储过程发布的完全相同的代码块...根据返回的错误,似乎快照代理决定不运行CREATE PROCEDURE命令包含一个创建索引,但随后继续并尝试运行GRANT EXECUTE命令,这会导致错误.

另外,我确切的SQL Server版本是:

Microsoft SQL Server 2005 - 9.00.5254.00(2005 + SP4累积更新1)

- 结束编辑 -

我的问题是,为什么会发生这种情况?我的出版物或订阅的配置是否存在问题?和其他人一样经历过这样的事吗?我将从哪里开始解决此问题?

- 更新 -

我一直在和希拉里·科特谈科技网......但仍然没有运气.如果我删除了该过程的GRANT EXECUTE权限,那么它将使用CREATE INDEX成功创建.因此它可以与GRANT EXECUTE CREATE INDEX一起使用,但不能同时使用.Hilary建议我的域中某些类型的垃圾邮件设备阻止快照在包含这两个关键字时正确传输,但如果我手动将.sch文件复制到订阅者并验证它包含预期命令,我仍然遇到同样的问题.

Mic*_*son 1

使用以下代码:快照中的存储过程将无法应用:

CREATE NONCLUSTERED INDEX [IX_TempTable] ON [dbo].[#TempTable](ID)
Run Code Online (Sandbox Code Playgroud)

但是,稍微更改语法会导致存储过程创建时不会出现问题:

ALTER TABLE dbo.#TempTable ADD CONSTRAINT IX_TempTable UNIQUE NONCLUSTERED ( ID )
Run Code Online (Sandbox Code Playgroud)

我无法解释它,在花了几个小时解决这个问题之后,我准备停止寻找解释并解决这个问题。