最近在看《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(@TA.col=@TB.col);
4)在修改表变量的查询中,不使用并行执行计划。
原文:http://www.cnblogs.com/xiaoxiaohong/p/6343691.html