我试图在作为发布者的数据库中删除一个表。有问题的表格没有发布。我得到的错误是:
Msg 15021, Level 16, State 1, Procedure sp_MStran_ddlrepl, Line 14 [Batch Start Line 1]
Invalid value given for parameter @procmapid. Specify a valid parameter value.
Msg 3609, Level 16, State 2, Line 2
The transaction ended in the trigger. The batch has been aborted.
我检查sysarticles
了是否有旧记录或孤立记录,但表格没有出现。关于这里的问题有什么想法吗?
编辑:SQL Server 2016 RTM
TL;DR:如果您恢复(或移动)以前复制到较低版本和/或补丁级别的服务器的数据库,然后重新启用复制,则可能会发生此错误。有关解决方案和更长的解释,请参见下文。
复制对某些事情使用数据库触发器
在 SQL Server 中为事务复制发布数据库时,作为设置过程的一部分,会创建几个数据库级触发器。通常,它们是:
您可以通过在对象资源管理器中扩展数据库,然后查看“可编程性”和“数据库触发器”来找到它们。他们几乎按照他们所说的去做。如果您查看其中的代码,
tr_MStran_altertable
您会看到每次触发 ALTER TABLE 语句的触发器时,SQL Server 使用 EventData() 函数来捕获正在更改的内容,然后调用另一个复制存储过程,该过程将实际捕获活动并将相关的 DDL 事务发送到分发数据库。这与查找和捕获数据更改的日志读取器代理不同。每次发布数据库进行复制时都会创建这些触发器,并且也会在删除复制过程中删除这些触发器。
SQL Server 2014 SP2 和 SQL Server 2016 SP1 中的新 DROP TABLE 支持
在 SQL Server 2014 SP2 和 SQL Server 2016 SP1 中,Microsoft 引入了对 SQL Server 复制的更改:支持 DROP TABLE ( https://support.microsoft.com/en-us/help/3170123 )。以前,您不能删除标记为要复制的表。这个默认不启用的新特性意味着 DROP TABLE 语句将不再抛出错误。为了促进这一变化,添加了一个新的数据库级触发器:
tr_MStran_droptable
. 这是为每个删除表操作触发的触发器,它使用事件数据来确定正在删除哪个表,以及是否启用了即使表标记为复制也支持事务的选项。但是“旧”版本的 SQL Server 呢?
这就是问题所在:这个触发器只能通过在支持它的版本上复制来创建......并且只能通过在支持它的版本上复制来删除。因此,即使您决定使用类似
sp_removedbreplication
此触发器的内容进行核对复制,也不会删除,并且每次尝试删除表时都会继续触发,即使您尝试删除的表未标记为复制。在以下情况下可能会发生这种情况:您可以自己进行测试:如果您禁用复制并重新启用它,您会注意到数据库触发器的创建时间将与您重新启用发布的时间一致,但
tr_MStran_droptable
触发器仍然存在。解决问题
要解决此问题,您可以: