7

我在 SQL Server 2005 Transactional Publication 中遇到了一个奇怪的问题。问题是这样的:如果发布包含的文章是包含创建索引语句的存储过程,则在尝试将存储过程的架构复制到订阅者时会引发错误。

这种行为很奇怪,因为即使 create index 语句被注释掉了,它仍然会给出异常,并且只有完全删除它才会起作用。

这是返回的确切错误:

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

(交易序号:0x00000170000008B9000500000000,命令ID:5)

错误消息:找不到对象“usp_Test”,因为它不存在或您没有权限。(来源:MSSQLServer,错误号:15151) 获取帮助:http://help/15151 找不到对象“usp_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

发布脚本:

-- 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

订阅脚本:

/****** 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 ******/

同样,奇怪的是,如果注释掉 create index 语句,发布仍然会包含相同的错误,但如果将其完全删除,它将起作用。

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

- 编辑 -

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

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

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

-- 结束编辑 --

我的问题是,为什么会这样?我的发布或订阅的配置是否存在问题?像其他人经历过这样的事情吗?我应该从哪里着手解决这个问题?

- 更新 -

我一直在 technet 上与 Hilary Cotter 交谈……但仍然没有运气。如果我删除该过程的 GRANT EXECUTE 权限,那么它会使用 CREATE INDEX 成功创建。所以它将与 GRANT EXECUTECREATE INDEX 一起使用,但不能同时使用。Hilary 建议可能是我的域中的某种类型的垃圾邮件设备在包含这两个关键字时阻止正确传输快照,但是如果我手动将 .sch 文件复制到订阅者并验证它是否包含预期的命令,我仍然遇到同样的问题。

4

2 回答 2

2

嗯……没有什么对我跳出来的。出于好奇,快照 .sch 文件中有什么内容?这就是订阅者的快照代理运行的内容。

于 2011-04-14T02:30:35.640 回答
1

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

CREATE NONCLUSTERED INDEX [IX_TempTable] ON [dbo].[#TempTable](ID)

但是,稍微更改语法会导致创建存储过程没有问题:

ALTER TABLE dbo.#TempTable ADD CONSTRAINT IX_TempTable UNIQUE NONCLUSTERED ( ID )

我无法解释它,并且在这个故障上花费了数小时之后,我已经准备好停止寻找解释并解决这个解决方法。

于 2011-04-29T20:35:29.097 回答