簡體   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