2015-12-31 68 views
2

這是一個將TRANSACTION添加到我的代碼的好方法。我必須先更新我的代碼,如果失敗,那麼插入也應該不起作用。如果這是一種正確的方式,請看看。如果沒有,那麼請改善。這是將事務添加到sql的好方法嗎?

Begin Transaction[Transaction1] 

    Begin Try 

     IF(@ServiceInfoToJobStatus = 1) 
      Update ServiceInfo 
      Set ServiceInfoToJobStatus= 0 --To set all current jobs to prior because one person cannot have many jobs selected as current 
      Where @ServiceInfoToJobStatus = 1 AND ServiceInfo.fk_PersonalInfo_ServiceInfo_PID= @fk_PersonalInfo_ServiceInfo_PID 

      Set @ServiceInfoEntryDateTime= (Select GetDate()) 

       Insert into dbo.ServiceInfo 
       (

       ServiceInfoInitialDesignation, 
       ServiceInfoInitialBPS, 
       fk_Districts_ServiceInfo_InitialDistrictID, 
       ServiceInfoJobStatus, 
       ServiceInfoFromDate, 
       ServiceInfoDepartment, 
       fk_PersonalInfo_ServiceInfo_PID, 
       ServiceInfoServiceType , 
       ServiceInfoOffice , 
       ServiceInfoCadre , 
       fk_WebUsers_ServiceInfo_UserID, 
       ServiceInfoEntryDateTime, 
       ServiceInfoToDesignation  , 
       ServiceInfoToBPS  , 
       fk_Districts_ServiceInfo_ToDistrictID  , 
       ServiceInfoToJobStatus  , 
       ServiceInfoToDate  , 
       ServiceInfoToDepartment  , 
       ServiceInfoToServiceType  , 
       ServiceInfoToOffice  , 
       ServiceInfoToCadre  
      ) 

       Values 
       (

       @ServiceInfoInitialDesignation, 
       @ServiceInfoInitialBPS, 
       @fk_Districts_ServiceInfo_InitialDistrictID, 
       @ServiceInfoJobStatus, 
       @ServiceInfoFromDate, 
       @ServiceInfoDepartment, 
       @fk_PersonalInfo_ServiceInfo_PID, 
       @ServiceInfoServiceType , 
       @ServiceInfoOffice , 
       @ServiceInfoCadre , 
       @fk_WebUsers_ServiceInfo_UserID, 
       Convert(varchar, @ServiceInfoEntryDateTime, 113), 
       @ServiceInfoToDesignation  , 
       @ServiceInfoToBPS  , 
       @fk_Districts_ServiceInfo_ToDistrictID  , 
       @ServiceInfoToJobStatus  , 
       @ServiceInfoToDate  , 
       @ServiceInfoToDepartment  , 
       @ServiceInfoToServiceType  , 
       @ServiceInfoToOffice  , 
       @ServiceInfoToCadre  
      ) 

       Set @ReturnStatus = 1 


    Commit Transaction[Transaction1] 

    End Try 

    Begin Catch 

       ROLLBACK Transaction[Transaction1] 

       Set @ReturnStatus= 0 
       Set @ReturnStatusMessage= (Select ERROR_MESSAGE())    

    End Catch 

回答

0

建議使用添加transaction (try/catch block)如果代碼在表中updatesinserts數據。在你的情況下,答案是肯定的。但在您的交易塊中,無法識別數據insert/update是否已完成。

我會使用下面的語法添加@@error

BEGIN TRY 
     BEGIN TRAN 

     //YOUR CODE 

     IF @@ERROR = 0 
      BEGIN 
       COMMIT TRAN; 
      END 
END TRY 
BEGIN CATCH 
     SELECT @@ERROR AS ERROR 
ROLLBACK TRAN; 
END CATCH  
0

對我來說,目前還不清楚update fails手段(錯誤或沒有行更新),但它沒有多大意義,因爲你可以測試都是很簡單:

DECLARE @UpdateErrorNo INT 
DECLARE @UpdateCount INT 
DECLARE @InsertErrorNo INT 

Begin Transaction[Transaction1] 
Begin Try 
    IF(@ServiceInfoToJobStatus = 1) 
     Update ServiceInfo 
     Set ServiceInfoToJobStatus= 0 --To set all current jobs to prior because one person cannot have many jobs selected as current 
     Where @ServiceInfoToJobStatus = 1 AND ServiceInfo.fk_PersonalInfo_ServiceInfo_PID= @fk_PersonalInfo_ServiceInfo_PID 

    SET @UpdateErrorNo = @@ERROR 
    SET @UpdateCount = @@ROWCOUNT 

    Set @ServiceInfoEntryDateTime= (Select GetDate()) 

    Insert into dbo.ServiceInfo 
    (
     -- skipped for readability 
    ) 

    Values 
    (
     -- skipped for readability 
    ) 

    SET @InsertErrorNo = @@ERROR 

    Set @ReturnStatus = 1 

Commit Transaction[Transaction1] 

End Try 

Begin Catch 

    ROLLBACK Transaction[Transaction1] 

    Set @ReturnStatus= 0 
    Set @ReturnStatusMessage= (Select ERROR_MESSAGE())    

End Catch 

-- here you can read `@UpdateErrorNo`, `@InsertErrorNo` to check for errors 

棘手的部分是該@@ ERROR在每個語句後設置,所以如果你有這樣的情況下(沒有的try/catch):

BEGIN TRAN 
INSERT ... -- fails 
UPDATE ... -- success 

-- @@ERROR will not show that it is a failure 
COMMIT 

它可能會導致意想不到的結果。

0

聲明@cdt日期時間= GETDATE() 開始嘗試 開始事務

Update dbo.ServiceInfo 
Set ServiceInfoToJobStatus= 0 --To set all current jobs to prior because one person cannot have many jobs selected as current 
Where @ServiceInfoToJobStatus = 1 
     AND fk_PersonalInfo_ServiceInfo_PID= @fk_PersonalInfo_ServiceInfo_PID 

      Insert into dbo.ServiceInfo 
      (

      ServiceInfoInitialDesignation, 
      ServiceInfoInitialBPS, 
      fk_Districts_ServiceInfo_InitialDistrictID, 
      ServiceInfoJobStatus, 
      ServiceInfoFromDate, 
      ServiceInfoDepartment, 
      fk_PersonalInfo_ServiceInfo_PID, 
      ServiceInfoServiceType , 
      ServiceInfoOffice , 
      ServiceInfoCadre , 
      fk_WebUsers_ServiceInfo_UserID, 
      ServiceInfoEntryDateTime, 
      ServiceInfoToDesignation  , 
      ServiceInfoToBPS  , 
      fk_Districts_ServiceInfo_ToDistrictID  , 
      ServiceInfoToJobStatus  , 
      ServiceInfoToDate  , 
      ServiceInfoToDepartment  , 
      ServiceInfoToServiceType  , 
      ServiceInfoToOffice  , 
      ServiceInfoToCadre  
     ) 

      Values 
      (

      @ServiceInfoInitialDesignation, 
      @ServiceInfoInitialBPS, 
      @fk_Districts_ServiceInfo_InitialDistrictID, 
      @ServiceInfoJobStatus, 
      @ServiceInfoFromDate, 
      @ServiceInfoDepartment, 
      @fk_PersonalInfo_ServiceInfo_PID, 
      @ServiceInfoServiceType , 
      @ServiceInfoOffice , 
      @ServiceInfoCadre , 
      @fk_WebUsers_ServiceInfo_UserID, 
      Convert(varchar, @cdt, 113), 
      @ServiceInfoToDesignation  , 
      @ServiceInfoToBPS  , 
      @fk_Districts_ServiceInfo_ToDistrictID  , 
      @ServiceInfoToJobStatus  , 
      @ServiceInfoToDate  , 
      @ServiceInfoToDepartment  , 
      @ServiceInfoToServiceType  , 
      @ServiceInfoToOffice  , 
      @ServiceInfoToCadre  
     ) 

      return ... 

commit transaction 

端嘗試 如果開始捕獲 (@@ TRANCOUNT> 0) 回滾事務

return ... 

端catch

0

這就是我使用的:

Begin Try 
    Begin Tran 

    -- Do your thing... some DML statements 

    Commit Tran 
End Try 

Begin Catch 
    If (@@TranCount > 0) 
     Rollback Tran 
End Catch 
相關問題