2012-10-27 2 views
0

헤더, 하위 헤더 및 광고 항목 세부 정보가있는 광고 주문을 삭제하고 대체 광고 제목이 무엇이든 동일한 광고 주문을 작성하기 전에 광고 항목 세부 정보가 표시 될 수 있습니다. 변경 사항이있는 최신 버전을 다시 쓰려고하면 pk 위반 오류가 발생합니다. 분석 후에는 DELETE 문이 작동하는 것처럼 보일지라도 (예 : x 행이 영향을 받음) - 대상 표가 변경되지 않은 채로 남아 있습니다. 그래서, 그것은 pk vio 문제를 설명 할 것입니다. 내가 뭘 놓치고 있니?tsql : 동작 삭제

다음은 문 중 하나입니다 :

 -- detail level (drop products) 
     DELETE dprods FROM [SQLsever].[WIP].[order].DropProducts as dprods 
     INNER JOIN #dropprods t on t.OrderId = dprods.OrderId 
      AND t.OrderDropId = dprods.OrderDropId 
      AND t.DropProdId = dprods.DropProdId; 

문을 실행 한 후, 난 여전히 목표 테이블의 모든 200 개 이상의 행이와 나는 #dropprods 임시 테이블에있는 200 개 이상의 ID를 가지고있다. 왜? 더 나은 문제를 ** * ** * ** * ** * * DELETE 문을 정의하려면 편집을 할

** 는 문제가되지 않았다. 이 문제는 중첩 된/명명 된 트랜잭션 집합과 관련이 있습니다. DELETE 문은 하나 아래에 있고 INSERT 문은 다른 문 아래에 있습니다. 여기에 내가 가진 것이있다. 그것은 분명히 잘못되었습니다. 내가 뭘하려는 건 내가 좋은 대체 INSERT를해야 알기 전에 DELETE를 저 지르지 않도록하는 것이다. 여기에 내가 한 일이 있습니다 : * 수정 된 T-SQL (저장 트랜잭션) 수정 * ** 이 TSQL이 작동합니다.

-- CHANGED 
    BEGIN TRANSACTION 
    SAVE TRANSACTION process_orders 
    BEGIN TRY 
    -- detail level 
    DELETE lprods FROM [SQLServer].[WIP].[order].LiftProducts as lprods 
    INNER JOIN #liftprods t on t.OrderId = lprods.OrderId 
     AND t.OrderLiftId = lprods.OrderLiftId 
     AND t.LiftProdId = lprods.LiftProdId; 
      -- the rest of the deletes 
      --NOTE: No commit transaction here; saving it to the end 
    END TRY 
    BEGIN CATCH 
     SELECT 
      ERROR_NUMBER() AS ErrorNumber, 
      ERROR_SEVERITY() AS ErrorSeverity, 
      ERROR_MESSAGE() AS ErrorMessage; 
     IF @@TRANCOUNT > 0 
      ROLLBACK TRANSACTION process_orders; 
     END CATCH 

     BEGIN TRANSACTION 
     -- CHANGED 
     SAVE TRANSACTION process_orders 
     BEGIN TRY  
      -- CHANGED 
       COMMIT TRANSACTION process_orders;  
     END TRY 
     BEGIN CATCH 
      SELECT 
      ERROR_NUMBER() AS ErrorNumber, 
      ERROR_SEVERITY() AS ErrorSeverity, 
      ERROR_MESSAGE() AS ErrorMessage; 
      IF @@TRANCOUNT > 0 
       ROLLBACK TRANSACTION process_orders ; 
     END CATCH 
+0

세계적인 난독 화 챔피언 쉽에 참가할 계획이 있습니까? DropOrder, OrderDrop dprods, t ... 우리가 함께 일하면 나랑 너는 커다란 스타일로 떨어질거야. 트랜잭션을 커밋하는 것을 잊어 버리는 것 말고는, 삭제 된 것으로보고되는 경우, 그들은 생각하는 트랜잭션이 아닙니다. 계단식 삭제를 검색 할 수도 있습니다 ... –

+0

Tony에 답해 주셔서 감사합니다. 5 분 전에 나는 모든 거래와 비올라를 꺼냈다. 삭제가 작동했습니다. 천국에 감사하십시오. 나는 내 마음을 잃어 버렸다고 생각하지 않았다. 어쨌든이 경기장에서는 아니야! :) 트랜잭션 문제로 인해 문제 설명을 업데이트 중입니다. – plditallo

+0

제 생각에는 잘 맞았지만 추측이었습니다. :) –

답변

1

먼저 ROLLBACK TRANSACTION 후에 트랜잭션 이름을 제거해야합니다. 내부 트랜잭션은 롤백 할 수 없으므로 가장 바깥 쪽 트랜잭션 만 롤백 할 수 있습니다.

둘째, SQL Server는 내부 트랜잭션 커밋을 무시합니다 (예 : 잠금은 가장 바깥 쪽 트랜잭션이 커밋되고 릴리스 될 때까지 대기합니다). 따라서 트랜잭션 이름없이 하나의 COMMIT TRANSACTION 만 필요합니다.

당신이 필요로하는 경우 아무런 문제가 없을것 코드는 안심하기 : 다른 사용자가 변경 내용을 무시하고

  • 을 그 삽입하면 변경 내용을 적용 성공할 경우는 true, 그렇지 않은 경우는 폐기 당신은 삽입을 시작 삭제 succeedes 경우

    • 모두

    COMMIT (말하기 : 다른 개발자가 일부 SP에 삽입 코드를 작성하고 삽입 코드가 너무 크다는 등 ...)을하기 전에 더 많은 것을 보증해야하는 경우 #liftprods 임시 테이블 분명히 삭제/삽입 할 키가 있습니다. rt) 키를 삽입해야한다고 생각하는 항목과 일치하는지 확인하십시오. 그렇지 않으면 트랜잭션을 롤백 할 RAISERROR ('Some message', 16, 1)을 실행하십시오.

  • +0

    응답 주셔서 감사합니다 - 네, 확실히 내부 트랜잭션 커밋을 무시합니다. 첫 번째 트랜잭션 process_orders에 이름을 지정하고 SAVE TRANSACTION을 INSERTS에 추가하여이를 해결했습니다. 마법의 주문처럼 작동합니다! :) – plditallo

    +0

    글쎄요, 트랜잭션을 저장하는 것이 좋습니다. 그러나 제안 된 해결책은 올바른 것이어야합니다. 삽입물이 올바르게 발행 될 때까지 삭제를하지 않기 때문입니다. ;) – OzrenTkalcecKrznaric

    +0

    절대적으로. 귀하의 솔루션 작동합니다. – plditallo