sp_replmonitorhelppublisher - “无法嵌套INSERT EXEC语句。”

时间:2014-05-19 20:01:58

标签: sql sql-server sql-server-2008 tsql stored-procedures

问题

我在Microsoft SQL Server 2008上收到此错误:

  

消息8164,级别16,状态1,过程sp_MSload_tmp_replication_status,第80行       无法嵌套INSERT EXEC语句。

背景

我正在尝试以编程方式监视Microsoft SQL Server中的复制状态。我在 sp_replmonitorhelppublisher 上使用INSERT EXEC语句来获取状态,后面的问题不仅限于此proc,但我提到它是因为proc是内置的,所以我不能重写它来获取数据“它应该做的方式”。获取数据的我(简化)代码是:

declare @t table (
    publisher nvarchar(max) null,
    distribution_db nvarchar(max) null,
    status nvarchar(max) null,
    warning nvarchar(max) null,
    publicationcount nvarchar(max) null,
    returnstamp nvarchar(max) null
)
insert into @t exec sp_replmonitorhelppublisher 'MY_PUBLISHER'

问题

我理解导致错误的MS SQL Server限制,我猜在内置proc中的某处有一些INSERT EXEC语句。我不明白的是:

  1. 为什么它有时会在没有错误的情况下运行(我已经看过它几次成功运行)?
  2. 为什么在实际的INSERT EXEC运行之前运行相同的EXEC语句(而不是INSERT EXEC的一部分)的解决方法没有错误?即这段代码工作正常:

    declare @t table (
        publisher nvarchar(max) null,
        distribution_db nvarchar(max) null,
        status nvarchar(max) null,
        warning nvarchar(max) null,
        publicationcount nvarchar(max) null,
        returnstamp nvarchar(max) null
    )
    exec sp_replmonitorhelppublisher 'MY_PUBLISHER' -- extra call before main call
    insert into @t exec sp_replmonitorhelppublisher 'MY_PUBLISHER'
    
  3. 这种解决方法是否可以保证在没有错误的情况下运行?为什么?

  4. 或者是否存在某种形式的缓存,这恰好对我有用,但不能保证每次通话都能正常工作?
  5. 有没有更好的方法以编程方式监控复制?

1 个答案:

答案 0 :(得分:0)

我正在处理同一问题-以编程方式监视复制状态。我发现执行sp_replmonitor*存储过程还会更新表dbo.MSReplication_monitordata。该表包含复制的当前状态信息。

因此,我的解决方案是执行sp_replmonitorhelppublisher,然后从dbo.MSReplication_monitordata中读取值。

例如:启动发布,然后等待发布完成(在SQL Server代理作业中)是这样的:

USE [DB]
DECLARE @StartDateTime datetime = GETDATE()
EXEC sp_startpublication_snapshot @publication='publ_DB'

USE [distribution]
DECLARE @Status int = 1

WHILE @status NOT IN (2, 6)
BEGIN
    WAITFOR DELAY '00:00:05'
    EXEC sp_replmonitorhelppublisher
    SELECT @Status = status FROM dbo.MSReplication_monitordata WHERE publication='publ_DB' AND agent_type=1 AND time_stamp>@StartDateTime
END

希望这会有所帮助!