1

我写了一个触发器来更新链接服务器上的本地表和类似表。

CREATE TRIGGER myTtableUpdate ON myTable
AFTER UPDATE AS
IF (COLUMNS_UPDATED() > 0)
BEGIN
DECLARE @retval int;
BEGIN TRY
EXEC @retval = sys.sp_testlinkedserver N'my_linked_server';
END TRY
BEGIN CATCH
SET @retval = sign(@@error);
END CATCH;

IF (@retval = 0)
BEGIN
UPDATE remoteTable SET remoteTable.datafield = i.datafield
FROM my_linked_server.remote_database.dbo.myTable remoteTable
INNER JOIN inserted i ON (remoteTable.id = i.id)
END
END -- end of trigger

不幸的是,当连接断开时,我收到错误消息
'Msg 3616,Level 16,State 1,Line
2''Transaction 在触发器中注定失败。Batch has been aborted'
并回滚本地制作的更新。

有没有办法维护这个错误并保持本地更新?
请注意,我在运行 Windows XP Pro 的两台 PC 上都使用 SQL Server 2005 Express Edition。

编辑 1:SQL 服务器是 Express 版 编辑 2
:两台 PC 都运行 Windows XP Pro,所以这些不是服务器

4

2 回答 2

2

不要在触发器中写入远程服务器。

  • 创建一个本地表来存储需要推送到远程服务器的行
  • 在触发器中插入这个新的本地表
  • 创建一个每 N 分钟运行一次的作业,以从该本地表插入远程服务器。

该作业可以运行一个可以测试连接的过程,当它备份时,它将处理新本地表中的所有行。它可以这样处理本地表中的行:

declare @OutputTable table (RowID int not null)

insert into my_linked_server.remote_database.dbo.myTable remoteTable(...columns...)
    OUTPUT INSERTED.RowID
    INTO @OutputTable
    SELECT ...columns...
        from NewLocalTable

delete NewLocalTable
   from NewLocalTable           n
       inner join @OutputTable  o ON n.RowID=o.RowID

插入到这个新的本地表后,基于 EDIT 的 OP 注释
从触发器(sp_start_job)启动作业,它将在自己的范围内运行。如果不能使用 sql server 作业,请使用 xp_cmdshell 执行存储过程(查找 SQLCMD 或 ISQL 或 OSQL,我不确定你有什么)。仍然每 N 分钟安排一次作业,所以它最终会在连接建立时运行。

于 2009-05-29T15:16:06.307 回答
0

至少有一台服务器是 Workgroup 版本或更高版本吗?您可以使用 Service Broker 来发送您的记录而不是链接服务器,但由于许可限制,它无法在 Express 版本之间工作。是一个完全依赖 SQL 的解决方案,在发生事件时提供可靠性(其中一个服务器不可用),并且您的更新将实时传播(一旦提交)。我的网站有很多关于如何做到这一点的示例,您可以从这篇文章开始,了解如何实现高消息吞吐量

于 2009-05-29T15:59:35.683 回答