表变量可以在其作用域内像正常的表一样使用。更确切的说,表变量可以被当成正常的表或者表表达式一样在SELECT,DELETE,UPDATE,INSERT语句中使用,但是表变量不能在类似"SELECT select_list INTO table_variable"这样的语句中使用。而在SQL Server2000中,表变量也不能用于INSERT INTO table_variable EXEC stored_procedure这样的语句中。
表变量不能做如下事情:
4、不能对临时表进行分区。
5、不能对临时表加外键约束。
6、临时表内列的数据类型不能定义成没有在TempDb中没有定义自定义数据类型(自定义数据类型是数据库级别的对象,而临时表属于TempDb)。由于TempDb在每次SQL Server重启后会被自动创建,所以你必须使用startup stored procedure来为TempDb创建自定义数据类型。你也可以通过修改Model数据库来达到这一目标。
7、XML列不能定义成XML集合的形式,除非这个集合已经在TempDb中定义。
临时表既可以通过Create Table语句创建,也可以通过"SELECT INTO #table"语句创建。你还可以针对临时表用"INSERT INTO #table EXEC stored_procedure"这样的语句。
临时表可以拥有命名的约束和索引。但是,当两个用户在同一时间调用同一存储过程时,将会产生”There is already an object named ‘’ in the database”这样的错误。所以最好的做法是不用为建立的对象进行命名,而使用系统分配的在TempDb中唯一的。 三、误区
误区1.表变量仅仅在内存中。
误区2.临时表仅仅存储在物理介质中。
这两种观点都是错误的,只有内存足够,表变量和临时表都会在内存中创建和处理。他们也同样可以在任何时间被存入磁盘。
注意表变量的名字是系统分配的,表变量的第一个字符”@”并不是一个字母,所以它并不是一个有效的变量名。系统会在TempDb中为表变量创建一个系统分配的名称,所以任何在sysobjects或sys.tables查找表变量的方法都会失败。
正确的方法应该是我前面例子中的方法,我看到很多人使用如下查询查表变量:
select * from sysobjects where name like'#tempTables%' 上述代码看上去貌似很好用,但会产生多用户的问题。你建立两个连接,在第一个连接中创建临时表,在第二个窗口中运行上面的语句能看到第一个连接创建的临时表,如果你在第二个连接中尝试操作这个临时表,那么可能会产生错误,因为这个临时表不属于你的会话。
误区3.表变量不能拥有索引。
这个误区也同样错误。虽然一旦你创建一个表变量之后,就不能对其进行DDL语句了,这包括Create Index语句。然而你可以在表变量定义的时候为其创建索引)比如如下语句。
declare @MyTableVariable table (RowID intPRIMARY KEY CLUSTERED) 这个语句将会创建一个拥有聚集索引的表变量。由于主键有了对应的聚集索引,所以一个系统命名的索引将会被创建在RowID列上。
下面的例子演示你可以在一个表变量的列上创建唯一约束以及如何建立复合索引。
declare @temp TABLE (
RowID int NOT NULL,