繁体   English   中英

存储过程将新记录转移到链接服务器的连接断开

[英]Stored procedure transferring new records to linked server losing connection

首先,我不是SQL专家,以此作为我的序言。 在此先感谢您审核我的问题。

在将新记录传输到那里的表(很多记录)的过程中,存储过程会定期失去与链接服务器的连接,这给我带来了麻烦。 我想知道一些事情。

首先,是否有更好的方法来完成更快,更高效的任务?

其次,是否有一种方法可以更好地处理连接丢失的问题,尝试重新尝试上一步,以尝试从上次中断的位置继续进行,可能需要等待15分钟左右,以防与链接服务器之间的某些临时断开连接(可能会比终止之前允许的持续时间更长)?

我也很好奇,当发生诸如突出显示的步骤之类的事情时,如果正在对链接服务器执行sql,并且连接丢失了,sql是否会尝试重新连接并继续超时,或者这是一个compare语句它会破裂吗? 我不太了解它是如何工作的。

这是连接丢失最常见的部分,通常在第一个insert语句(begin catch块中的第一步)中发生:

UPDATE [LINKEDSERVER.XYZ.COM].dest_database1.dbo.run
  SET last_result = 32
  WHERE type = 158;

BEGIN TRY
    INSERT INTO [LINKEDSERVER.XYZ.COM].[dest_database2].dbo.table1 ( CID , BID , Question1 , Question2 , Question3 , Question4 , Question5 , Question6 , Question7 , Question8 , Question9 , Question10 , Comments , EmailAddress , Name , Address , Address2 , City , State , Zip ) 
    SELECT src.CID , src.BID , src.Question1 , src.Question2 , src.Question3 , src.Question4 , src.Question5 , src.Question6 , src.Question7 , src.Question8 , src.Question9 , src.Question10 , src.Comments , src.EmailAddress , src.Name , src.Address , src.Address2 , src.City , src.State , src.Zip 
      FROM table1 AS src LEFT OUTER JOIN [LINKEDSERVER.XYZ.COM].[dest_database2].dbo.table1 AS dst ON src.CID = dst.CID AND src.BID = dst.BID
      WHERE dst.CID IS NULL;

    INSERT INTO [LINKEDSERVER.XYZ.COM].[dest_database2].dbo.table2 ( CID , AccountNumber , Name , Address , Address2 , City , State , Zip , BShort, EmailAddress ) 
    SELECT src.CID , src.AccountNumber , src.Name , src.Address , src.Address2 , src.City , src.State , src.Zip , src.BShort, src.EmailAddress 
      FROM table2 AS src LEFT OUTER JOIN [LINKEDSERVER.XYZ.COM].[dest_database2].dbo.table2 AS dst ON src.BShort = dst.BShort
      WHERE dst.BShort IS NULL;
END TRY
BEGIN CATCH
    SELECT @ErrorCode = @@Error;
    SELECT @ErrorResult = 109;
    SELECT @ErrorMessage = 'Failed Copy ' + CAST ( @ErrorCode AS varchar ) ;
    GOTO ExitWithError;
END CATCH;

INSERT INTO [LINKEDSERVER.XYZ.COM].dest_database1.dbo.system_log ( notes , log_type , source_type , parent_id ) 
VALUES ( 'Copied tables xyz ' , 45 , 58 , 0 ) ;

UPDATE [LINKEDSERVER.XYZ.COM].dest_database1.dbo.run
  SET last_result = 31
  WHERE type = 158;

我知道,如果连接丢失,则不会执行catch块,因此不会使用ExitWithError。 而且我想我知道当连接丢失时,会发生回滚(不知道如何/是否与链接服务器一起工作,因为发生这种情况时会传输某些记录),并且它只是退出执行所有操作-因为没有执行catch或整个begin catch块之后的语句。 我希望在发生这种情况时记录一些信息,以便存储过程再次运行时(设置为每30分钟运行一次,直到成功),它可以从中断的地方开始,因为我的代码开头查找最后的状态/日志条目并确定要执行的操作。 有没有更好的方法来解决这个问题?

因此,第一个技巧是,如果可以,请从其他服务器(目标)执行存储过程。 换句话说,切换本地服务器和链接服务器。 原因是我已大大改善了从链接服务器到本地表的DML(插入/更新/删除)命令的性能。 将DML制作到链接表时,性能很差!

接下来有效使用ID,它们是顺序的吗? 您能否仅使用目标服务器上的最大值,而不必在服务器之间加入大型表?

如果您不能依靠顺序,则可以在源服务器上构建一个临时表并在其中进行过滤,而不是尝试跨表进行操作。 如果只是id,您还可以尝试来回传递nvarchar格式的XML。 或者,您可以在源上维护一个跟踪表,以使您知道使用插入语句中的OUTPUT insert.id INTO ....已经处理了哪些ID。

最后,将过程设置为批处理/分批处理,并以较小的块(例如一次SELECT TOP x#个记录)进行事务。 您仍然可以将整个事情放在while循环中,这样就可以在proc的一次执行中完成所有工作,但是随后您可以以更小,更易于管理的方式进行事务。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM