【问题标题】:How to properly trigger an insert to a linked sql server?如何正确触发对链接的 sql 服务器的插入?
【发布时间】:2014-04-03 08:01:12
【问题描述】:

我在两个不同的 sql 服务器中有同一张表(一个是 SqlServer 2000,另一个是 2008)。

我正在使用 sql server management studio。

我希望每次在 SqlServer 2000 表(Table_1)中的表上进行插入时,都会发生触发器,并且该记录也将插入到 SqlServer 2008 表(也是 Table_1)中的同一个表中。

sql server 2008 被定义为链接服务器,可以使用 sql server management studio 从 2000 db 连接在 2008 db 上运行查询和执行插入操作。

触发器定义如下:

ALTER TRIGGER [dbo].[trgrTable] 
   ON  [dbo].[Table_1]
   AFTER INSERT
AS 
BEGIN

 INSERT INTO [TLVSQL].[AVI_DEV].[dbo].[Table_1](ID, Value)
      SELECT INSERTED.ID AS ID, INSERTED.Value AS Value
      FROM INSERTED

END

[TLVSQL].[AVI_DEV] 是 2008 数据库名称。

但是每次我在 2000 表上执行插入时,我都会收到一条消息,指出插入失败,因为“sqloledb 无法启动分布式事务链接服务器...”。

链接服务器的安全委托定义明确,我将安全凭证明确设置为 db_owner 的用户/密码。

我做错了什么?我问的还有其他方法吗?

谢谢。

【问题讨论】:

  • 我同意现有的答案 - 从触发器中,您不应尝试访问当前数据库的任何 外部 内容。它会严重减慢任何插入活动,如果它们是任何网络问题或远程服务器因任何原因而关闭,那么您将导致原始事务回滚。这很少是正确的做法——你让系统的可靠性取决于两台服务器的可靠性,而不是一台(假设它们都有 99% 的可靠性——你的系统将它们联系在一起)现在有 98% 的整体可靠性)

标签: sql sql-server sql-server-2008 triggers linked-server


【解决方案1】:

从触发器执行插入到链接服务器上的表中 - 错误的决定。 这将对源表([dbo].[Table_1])中的插入性能产生很大影响 还有一个分布式事务,以及配置服务器 支持分布式事务 - 噩梦。

一种可能的解决方案是:

  1. 您可以在源服务器上创建同步队列表。例如:

    CREATE TABLE dbo.SyncQueue
    (
        QueueId INT IDENTITY(1,1),        
        KeyForSync INT, -- Primary key value of record in dbo.SourceTable
        SyncStatus INT  -- statuses can be: 0 - New, 1 - Synchronized, 2 - Error
    )
    
    suppose you source table is
    
    CREATE TABLE dbo.SourceTable
    (
            Key INT, -- primary key of the table
            Data varchar(xxx)
    )
    
  2. dbo.SourceTable 上的Triger 可以快速插入到dbo.SyncQueue 记录中需要同步的Key

  3. 一些定期执行的存储过程可以从队列中插入记录 链接服务器上的表。

【讨论】:

  • 好的,谢谢。性能在这里根本不是问题。我们谈论的是极少数的记录(一周不到 10 条)。尽管您的解决方案看起来明智且干净,但我需要能够为其他没有 ID 密钥的表执行此操作,这意味着我需要为许多小表创建同步。我宁愿有一个我可以在每张桌子上轻松实施的解决方案 9
  • 续。 (由于某种原因我无法编辑) - 就像每个触发器一样 - 但即使不建议也有可能吗?
  • 那么是的,就您而言,您的解决方案更好。如果 SQL Server 的版本 > 2008,您还可以使用 "Сhange data capture" 功能 (simple-talk.com/sql/learn-sql-server/…)。但是你有SQL 2000 ..那么你需要正确配置"Distributed Transaction Coordinator"。另请参阅support.microsoft.com/kb/839279 可能对您有帮助。
  • 所有关于如何将 DTC 启用到正确配置的信息都在这里msdn.microsoft.com/en-us/library/dd327979.aspx。我必须做的另一件事是在触发器内将 XACT_ABORT 设置为 ON。我以类似的方式结束 ALTER TRIGGER [dbo].[trgrTable] ON [dbo].[Table_1] AFTER INSERT AS BEGIN SET XACT_ABORT ON INSERT [TLVSQL].[AVI_DEV].[dbo].[Table_1] ([ID] ,[Value]) SELECT INSERTED.ID AS ID, INSERTED.Value AS Value FROM INSERTED END
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多