事務點 savepoint 的使用 簡單來說就是事務點 savepoint 将整個完整的事務分割成若幹個分組,如: saveopint a , saveopint b , saveopint c ,按照順序往下排列,當 rollback to b 的時候, saveopint c 後面的操作就相當于是撤銷了,同理,當 rollback a 的時候,事務點 savepoint b 後面進行的操作也就會被撤銷了。 每一次 Begin Transaction 都會引起 @@TranCount 加 1 。而每一次 Commit Transaction 都會使 @@TranCount 減 1 ,而 RollBack Transaction 會復原所有的嵌套事務包括已經送出的事務和未送出的事務,而使 @@TranCount 置 0 。 Begin Transaction -- @@TranCount = 1 BeginTransaction -- @@TranCount = 2 BeginTransaction -- @@TranCount = 3 Commit Transaction -- @@TranCount = 2 Commit Transaction -- @@TranCount = 1 Commit Transaction -- @@TranCount = 0 Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION statement is missing. Previous count = 1, current count = 0. 如果被嵌套的事務中發生錯誤, 最簡單的方法應該是無論如何都先将它送出,同時傳回錯誤碼 (一個正常情況不可能出現的代碼 如 -1 )讓上一層事務來處理這個錯誤,進而使 @@TranCount 減 1 。 這樣外層事務在復原或者送出的時候能夠保證外層事務在開始的時候和結束的時候保持一緻。由于裡層事務傳回了錯誤碼,是以外層事務(最外層)可以復原事務,這樣裡面已經送出的事務也可以被復原而不會出現錯誤。 在項目中應該會常常出現這樣的情況,一個存儲過程裡面用了事務,但是不能保證它會被别的帶有事務的存儲過程調用,如果單獨調用的話,出現錯誤可以直接復原,但是如果是被别的帶事務的存儲過程調用的話, RollBack 就會出錯了。是以需要一種機制來區分,建立一個臨時的變量來區分是否嵌套,和嵌套的層數,如下: DECLARE @TranCounter INT; SET @TranCounter = @@TRANCOUNT; IF @TranCounter > 0 SAVE TRANSACTION ProcedureSave; ELSE BEGIN TRANSACTION; ………… -- 事務内要執行的代碼 ………… IF @@ERROR<>0 goto Error Commit Transaction Commit Transaction -- 下面傳回要傳回的值 0 隻是個例子 Return 0 Error: IF @TranCounter = 0 ROLLBACK TRANSACTION; Else ROLLBACK TRANSACTION ProcedureSave; Return @Error CONVERT 函數: 文法: CONVERT(int,' 字段 ') 用法: CONVERT() 函數是把日期轉換為新資料類型的通用函數。 CONVERT() 函數可以用不同的格式顯示日期 / 時間資料。