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

发布于 2024-11-01 11:05:05 字数 5049 浏览 0 评论 0原文

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

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

这是返回的确切错误:

尝试命令:GRANT EXECUTE ON [dbo].[usp_Test] 至 [公司数据库访问]

(交易序列号: 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 ******/

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

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

-- 编辑 --

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

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

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

-- 编辑结束 --

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

-- 更新 --

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

I've experienced a bizarre problem with a SQL Server 2005 Transactional Publication. The issue is this: If the publication contains an article that is a stored procedure that contains a create index statement, then there is an error thrown when attempting to replicate the schema of the stored procedure to a subscriber.

The behavior is very odd, because even if the create index statement is commented out, it still gives the exception, and it will only work if it is removed altogether.

Here is the exact error that's being returned:

Command attempted: GRANT EXECUTE ON
[dbo].[usp_Test] TO
[CompanyDatabase_access]

(Transaction sequence number:
0x00000170000008B9000500000000,
Command ID: 5)

Error messages: Cannot find the object
'usp_Test', because it does not exist
or you do not have permission.
(Source: MSSQLServer, Error number:
15151) Get help: http://help/15151
Cannot find the object 'usp_Test',
because it does not exist or you do
not have permission. (Source:
MSSQLServer, Error number: 15151) Get
help: http://help/15151

The error is accurate, because when I check on the subscriber, the stored procedure wasn't created as expected... but that was the purpose of the publication...

Additionally, I can create the stored procedure manually on the subscriber, but when I generate a snapshot, it deletes the existing stored procedure and then still returns this error message.

And here's a sample publication that creates this issue.

The stored procedure:

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

The publication script:

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

The subscription script:

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

Again, the odd thing is that the publication will still contain the same error if the create index statement is commented out, but it will work if it is removed altogether.

For now, I've just removed all stored procedures that contain these create index statements from the publication, but I would like to have them replicated to the subscribers so that any DDL updates to the procedures will be automatically reflected on the subscribers.

-- EDIT --

Looking in the snapshot directory, the .sch file for usp_Test contains the exact same code block I previously posted for the stored procedure... based on the error returned, it seems like the snapshot agent decides not to run the CREATE PROCEDURE command if it contains a create index, but then continues on and tries to run the GRANT EXECUTE command, which causes the error.

Also, my exact version of SQL Server is:

Microsoft SQL Server 2005 -
9.00.5254.00 (2005 + SP4 Cumulative Update 1)

-- END EDIT --

My question is, why is this happening? Is there an issue with the configuration of my publication or subscription? As anyone else experienced anything like this? Where would I start in troubleshooting this issue?

-- UPDATE --

I've been talking to Hilary Cotter on technet... and still no luck. If I remove the GRANT EXECUTE permission on the procedure, then it creates successfully with the CREATE INDEX. So it will work with GRANT EXECUTE OR CREATE INDEX, but not both. Hilary suggested that it might be some type of spam appliance in my domain that was preventing the snapshot from being transferred correctly when it contained both of those keywords, but if I manually copy the .sch file to the subscriber and validate that it contains the expected commands, I still get the same issue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白芷 2024-11-08 11:05:05

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

Hmm... nothing's jumping out at me. Out of curiosity, what's in the snapshot .sch file? That's what gets run by the snapshot agent at the subscriber.

洒一地阳光 2024-11-08 11:05:05

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

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

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

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

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

With the following code: the stored procedure in the snapshot will failed to be applied:

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

But, changing the syntax slightly causes the stored procedure to create without issue:

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

I can't explain it, and after spending literally hours on this glitch, I'm ready to just stop looking for an explanation and settle for this workaround.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文