存储过程将新记录传输到链接服务器丢失连接

时间:2016-08-18 16:04:32

标签: sql sql-server tsql stored-procedures linked-server

让我先说一下我不是一个SQL专家。在此先感谢您审核我的问题。

我遇到了一个存储过程的问题,在将新记录传输到那里的表(很多记录)的过程中,它会定期丢失它与链接服务器的连接。我对某些事情感到疑惑。

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

第二,是否有办法更好地处理尝试重新尝试上一步的连接丢失,以便继续停止,可能在等待15分钟左右以防万一与链接服务器临时断开连接(可能比终止前允许的更多)?

此外,我很好奇,当突出显示的步骤发生时,如果正在对链接服务器执行sql,并且连接丢失,sql是否会尝试重新连接并继续超时期间或者因为这是一个比较声明它只是打破了吗?我真的不明白它是如何运作的。

以下是连接丢失最常见的部分,通常发生在第一个插入语句中(开始捕获块中的第一步):

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。而且我想我理解当连接丢失时,会发生回滚(不确定如何/如果这对链接服务器起作用,因为当发生这种情况时会传输某些记录),并且它只是退出执行所有内容 - 因为它们都没有执行或整个开始捕获块之后的语句。我希望,如果发生这种情况,记录一些东西,以便存储过程,当它再次运行(设置为每30分钟运行一次,直到成功),它可以从它停止的地方拿起,因为我在开始时有代码查找最后一个状态/日志条目并确定要执行的操作。 有没有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:0)

首先提示,如果可以,请从其他服务器(目标)执行存储过程。换句话说,切换本地和链接的服务器。原因是我从链接服务器到本地表的DML(插入/更新/删除)命令的性能得到了显着提高。当DML进入链接表时,性能很糟糕!

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

如果您不能指望顺序,那么您可以在源服务器上构建临时表并在那里进行过滤,而不是尝试跨表执行。如果只是ids,你也可以尝试来回传递nvarchar格式的XML。或者,您可以在源代码上维护一个跟踪表,以便使用插入语句中的OUTPUT inserted.id INTO ....来了解已经处理了哪些ID。

最后将您的程序设置为批处理/剪切并以较小的块进行处理,例如一次选择SELECT TOP x#记录。您仍然可以将整个事物放在while循环中,以便它在proc的一次执行中完成所有操作,但是您可以在更小的更易于管理的部分中执行事务。