最近在看《Microsoft SQL Server2005技術內幕:T-SQL程式設計》 1、表變數的事務上下文中提到,表變數不受外部事務回滾影響。 舉個例子: DECLARE @TA TABLE(col INT);INSERT @TA VALUES(0);SELECT * FROM @TA;BEG ...
最近在看《Microsoft SQL Server2005技術內幕:T-SQL程式設計》
1、表變數的事務上下文中提到,表變數不受外部事務回滾影響。
舉個例子:
DECLARE @TA TABLE(col INT);
INSERT @TA VALUES(0);
SELECT * FROM @TA;
BEGIN TRAN
INSERT @TA VALUES(1);
SELECT * FROM @TA;
ROLLBACK;
SELECT * FROM @TA;
/*--------------------------------------------*/
第一個SELECT輸出結果:
col
0
/*--------------------------------------------*/
第二個SELECT輸出結果:
col
0
1
/*--------------------------------------------*/
第三個SELECT輸出結果:
col
0
1
/*--------------------------------------------*/
原文中舉了一個例子,概括起來就是如果在觸發器(inserted/deleted)中回滾數據變更,但又想記錄這些變更,怎麼做呢?可以把inserted/deleted中的變更數據保存到表變數中,然後事務回滾數據變更操作。
作者還提到,利用表變數這個特性,不僅可以記錄修改後撤銷的數據,而且對比臨時表(臨時表會產生日誌操作和鎖操作,但涉及的鎖比數據表少),可以減少日誌操作和鎖操作。
2、使用表變數時候的限制條件
1)表變數只能創建主鍵key和唯一索引,不支持非唯一索引。如果需要把某個非主鍵欄位col1構建為索引,可以將key和col1構建成一個主鍵key。比如說,產品表變數@Product,主鍵為Id_Guid,現在需要將@Product中的產品編碼欄位Code_Nvarchar欄位加入索引,可以將(Id_Guid,Code_Nvarchar)構建為主鍵Key
2)表變數創建之後,就不能修改它的結構。比如說創建了表變數@Product(Id_Guid,Code_Nvarchar)之後,就不能為@Product再添加或者刪除一個欄位。表變數的這個限制條件也可以減少編譯次數。(表的架構更改之後會導致重新編譯)
3)表變數中,不能以表名.列表的方式來訪問列。比如不能用@Product.Id_Guid來訪問表變數@Product的Id_Guid欄位。
DECLARE @TA TABLE(col INT);
DECLARE @TB TABLE(col INT);
INSERT @TA VALUES(1);
INSERT @TB VALUES(1);
SELECT * FROM @TA A JOIN @TB B ON(A.col=B.col);
/*下麵這個語句會報語法錯誤*/
--SELECT * FROM @TA JOIN @TB ON(@[email protected]);
4)在修改表變數的查詢中,不使用並行執行計劃。