我在服务器 1 上设置了快照复制发布。服务器 2 订阅了服务器 1 上的发布。数据复制成功。
服务器 2 的订阅服务器的分发服务器代理和代理作业在服务器 1(分发服务器数据库所在的位置)上运行。
我在服务器 2 上创建了一个存储过程,以在服务器 2 的订户数据库上删除(预复制)和创建(复制后)模式绑定实体。(我过去成功地做到了这一点,因为如果订阅数据库中存在绑定到复制实体的模式的实体,快照复制可能会停止。)
我还创建了一个脚本,该脚本通过链接服务器从服务器 1 到服务器 2 执行此存储过程。(我已验证链接服务器设置正确,我可以从服务器查询数据并通过链接服务器手动执行存储过程1 到服务器 2。)我已将此脚本添加到快照发布的“快照”属性中:
最初,我在快照代理作业中收到错误,因为我的快照代理没有对脚本中路径的文件共享访问权限,但我添加了该帐户,然后错误消失了,快照作业现在成功完成。
但是 SQL 脚本中的实体不会被删除或创建,而且我在任何地方都没有看到错误。我还尝试将之前和之后的脚本文件移动到服务器 1 本地的文件夹共享并使用 UNC 路径(与屏幕截图中的网络路径相反)引用它,但行为仍然没有变化。
我已经使用以下代码使用非常简单的测试更新了 TEST.sql 脚本:
INSERT INTO DatabaseA.dbo.Table1 (Field1) -- DatabaseA is on Server1, so it should insert to the local table
SELECT 'Test' AS Field1
当我重新运行快照代理时,它仍然成功运行,但表没有插入(在服务器 1 上)。
为什么我的前置脚本和后置脚本无法运行,但我也没有收到任何错误?
(我在服务器 1 上还有另一个事务复制发布,它将数据同步到与快照复制相同的数据库中的服务器 2。但即使我在服务器 1 上的事务性发布,我仍然没有收到任何错误,并且 SQL 没有执行。)
编辑:我也只是尝试将脚本文件移动到服务器 1 的本地文件夹,授予快照代理对该文件夹和脚本文件的读取权限,然后重新运行快照代理,但仍然没有。没有执行脚本,也没有错误。
但有趣的是,如果我手动修改订阅代理作业本身并添加一个步骤来执行相同的确切 SQL 查询,它确实可以工作。
我还注意到 SQL 代理作业在不同的 SQL 帐户“sqlmin”下运行,然后我期望某些步骤(我创建的新步骤,或者称为“快照代理启动消息”的作业的第一步 - 我猜是因为这些步骤不是t 类型为“REPL-Distributor”)。但是其他预先存在的步骤作为我指定的 SQL 代理执行,即“DBReplication”。我知道的“sqlmin”帐户在服务器 1 和服务器 2 上都具有非常小的 SQL 权限,这可能是为什么当我没有执行复制前和复制后脚本的原因(但我也没有在任何地方收到错误)在快照发布 - 快照属性的前置和后置字段上设置脚本?
还有关于分发者帐户(也是我的快照代理帐户)的其他详细信息:分发者是一个 Windows AD 帐户,在服务器 1 和服务器 2 上都有 SQL LOGIN,并且在复制的源和目标中都具有 db_owner 的 SQL 角色数据库以及分发数据库(位于服务器 1 上)上的 db_owner。
在分析各种选项时,我会尝试一些事情的快速总结......
您是否尝试过在脚本中传递四部分对象标识符?
而不是使用:
尝试使用:
或者在您使用链接服务器的情况下,它将是:
您将值定义为:
这取决于脚本必须在哪里修改数据。这在您的描述中不是很清楚,但是看到您确实提到了链接服务器,我想我会提到它。
该脚本在订阅服务器上执行,如下所述:
此处提供的其他信息非常重要:
参考: 修改 SQL 复制的快照初始化选项(Microsoft | SQL Docs)
如果脚本不能与用于订阅代理的帐户一起使用并且不能与sqlcmd一起使用,那么它在订阅中将无法使用。
然后,您可能想查看文章疑难解答:查找 SQL Server 事务复制错误。我不是说你还没有这样做,但你没有说你有。谁知道呢,也许你可以在复制代理的工作历史中找到问题...
重新发布我的评论作为答案
从 BoL 中提取“您可以在应用快照之前或之后指定要在订阅者(我的重点,又名 Server2)处执行的脚本。脚本可以用于多种原因,例如在以下位置创建登录名和模式(对象所有者)每个订阅者。”
https://learn.microsoft.com/en-us/sql/relational-databases/replication/snapshot-options?view=sql-server-ver15