2017-11-21 22 views
0

위한 시도 - 캐치에도 불구하고 데이터를 로컬 커밋에 실패 트리거, 나는 그것이 MYLINKEDSERVERTestDatabaseTestTable의 내용을 삭제하고 처음부터 모든 것을 다시 삽입합니다. 이렇게하려면 MyTable에서 트리거를 사용합니다. 이 방법이 비효율적이지만 레코드 수가 10 개 미만이라는 것을 알고 있습니다.SQL 서버 2012 - 내가 <code>MyDatabase</code>에 <code>MyTable</code>을 변경 한 경우 sp_testlinkedserver

링크 된 서버가 다운 된 경우에도 로컬에서 변경 사항을 MyTable으로 커밋하고 linkedserver가 업데이트 되십시오. 연결된 서버를 사용할 수 없을 때 커밋 할 로컬 트랜잭션을 가져 오지 못했습니다 ... XACT_ABORT 함께 망쳐 봤지만 다른 오류가 발생합니다.

내가 뭘 잘못하고 있니?

CREATE TRIGGER trig_updatelinkedserver ON MyDatabase.dbo.MyTable 
FOR INSERT, UPDATE, DELETE 
AS 
BEGIN 

DECLARE @linked_server SYSNAME = 'MYLINKEDSERVER' 
, @tablename SYSNAME --name of the table calling the trigger so we can send error details in alert eamil 

SELECT @tablename = OBJECT_NAME(parent_object_id) 
FROM sys.objects 
WHERE sys.objects.name = OBJECT_NAME(@@PROCID) 

BEGIN TRY 
    --If linkedserver fails to connect, we do not want the remaining code in the block to run 
    --but we do want the original transaction that triggered this to complete. 
    EXEC sp_testlinkedserver @servername = @linked_server 

    DELETE FROM MYLINKEDSERVER.TestDatabase.dbo.TestTable 

    INSERT INTO MYLINKEDSERVER.TestDatabase.dbo.TestTable 
    SELECT * 
    FROM MyDatabase.dbo.MyTable 
END TRY 

BEGIN CATCH 
    DECLARE @subj VARCHAR(1000) = 'TRIGGER FAILURE: ' + @tablename + ': Could not locate linkedserver ' + @linked_server 

    EXEC msdb.dbo.sp_send_dbmail 
    @recipients = '[email protected]' 
    , @subject = @subj 
    , @body = '' 
    , @body_format = 'HTML' 
    , @profile_name = 'MyEmailProfile' 
END CATCH 

END 
+0

https://docs.microsoft.com/en-us/sql/t-sql/statements/set-xact-abort-transact-sql을 확인하고 SET XACT_ABORT를 OFF로 설정하십시오. – Naidu

답변

0

tsql의 오류 처리가 복잡하고 일관성이 없습니다. 너 뭐 잘못 했니? 가정하기. 트리거에 대해 이해하는 것이 중요합니다 무엇

도, 그들이 방아쇠를 발사 명령의 일부이며, 트리거 당신이 트랜잭션에 항상이다 : 여기 ERLAND이 주제에 대한 자신의 긴 discussion에 말씀입니다 BEGIN TRANSACTION을 사용하지 않았다면 트리거가 실패 할 경우 트리거를 실행 한 명령을 롤백하지 않는 트리거를 작성할 수 있는지 SQL Server 포럼의 사람들에게 질문하는 경우가 있습니다. 대답은 당신이 이것을 신뢰할 수있게 할 수있는 방법이 없다는 것입니다. 그래서 시도하지 않는 것이 좋습니다. 이러한 유형의 요구 사항이있는 경우 트리거를 전혀 사용하지 말고 다른 솔루션을 사용해야합니다.

마지막 문장을 마음에 새겨주십시오. 이 링크를 클릭하면 토론이 진행됩니다. 그리고 페이지 끝에는 관련 주제로 이어지는 링크가 있습니다. 그 중 하나는 연결된 서버에 관한 것입니다.

+0

나는 그것을 (저장 점을 사용하여) 연결된 서버에 연결하는 동안 오류가 발생해도 오류가 없으면 처음에는 저장 지점을 좋아하지 않으므로 전혀 커밋되지 않습니다. 나는 혼란 스럽다. – eek142