截断/清除Sql Server 2008中的表variables

是否有可能在sql server 2008中截断或清除表variables?

Declare @tableVariable table ( id int, value varchar(20) ) while @start<=@stop begin insert into @tableVariable(id,value) select id , value from xTable where id=@start --Use @tableVariable --@tableVariable should be flushed out of -- old values before inserting new values set @start = @start + 1 end 

只是删除一切

 DELETE FROM @tableVariable 

不,你不能TRUNCATE表variables,因为它不是物理表。 删除它会更快。 从Aaron Bertrand看到这个答案。

我会添加到“ 技术上 ”正确的答案使用DELETE @VariableTable ,如果你碰巧也有一个标识字段在你的@Tablevariables(例如i int (1,1) ),使用这个表(即使你在循环中重新声明),它仍然在范围之内,也没有办法重新设定它。

请参阅: 表variables标识列

在这种情况下最好使用#TempTable ,然后可以截断或使用DBCC重新设置种子。
您将通过Truncate获得性能改进, 能够创build其他索引。
我认为经验法则是,如果你要删除所有使用DELETE @VariableTable东西,那么你已经引入了一个代码异味,说你应该使用#TempTableTRUNCATE来代替。

表variables不支持TRUNCATE语法 – 截断它们的唯一方法是让它们超出范围。

在存储过程中使用时,临时表和表variables都可以被caching ,下面的代码可能最终会在截断后使用相同的表variables,而不是实际的下降并创build

 CREATE PROC dbo.foo @start INT AS BEGIN DECLARE @tableVariable TABLE ( id INT, value VARCHAR(20)) INSERT INTO @tableVariable (id, value) SELECT id, value FROM xTable WHERE id = @start; --Use @tableVariable END GO WHILE @start <= @stop BEGIN EXEC dbo.foo @start SET @start = @start + 1 END 

当然,更简单的方法是直接切换到使用#temp表格,而不是直接支持TRUNCATE

表variables和临时表上的DML写入tempdb事务日志。 是否值得切换到TRUNCATE而不是DELETE取决于所涉及的数据的大小。 TRUNCATE将只logging页面释放。 DELETE将logging实际删除的值。 两者之间的另一个区别是, TRUNCATE从表中取消分配最后一页,而DELETE不取消。 如果在每次循环迭代中仅插入和删除less量数据,则logging已删除行的开销可能小于不断释放和重新分配表中单个页面的开销。

相反,如果您将在每次迭代中插入和删除大量数据,则可能发现TRUNCATE不仅使删除所有行的操作更有效,而且还可以使后续插入语句受益 。

我知道这是一个古老的问题,但我已经想出了一个办法做到这一点。 我们拥有数百万行的表,并且由于事务日志空间而不想删除它们。

创build一个你想要截断的表名中传递的过程,该过程将创build另一个过程,执行trucate并删除过程。

 USE [My_Database] GO /****** Object: StoredProcedure [dbo].[ClearOutTable_p1] Script Date: 23/09/2015 09:03:14 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: Oraclebhoy -- Create date: 23/09/2015 -- Description: -- -- removes the content of the table passed in through the parameter -- ============================================= create procedure [dbo].[ClearOutTable_p1] @tablename varchar(max) as -- CREATE THE TRUNCATE STATEMENT PASSING IN TABLE VARIABLE declare @truncatesql varchar(max) set @truncatesql = 'truncate table ' + @tablename -- IF PROCEDURE EXISTS DROP if exists (select name from sys.all_objects where name = 'ClearOutTable_TEMP'and type = 'P') begin drop procedure [dbo].[ClearOutTable_TEMP] end -- CREATE TEMP PROCEDURE exec ('create procedure [dbo].[ClearOutTable_TEMP] as '+@truncatesql+'') -- EXECUTE THE PROCEDURE exec [dbo].[ClearOutTable_TEMP] -- DROP THE PROCEDURE drop procedure [dbo].[ClearOutTable_TEMP] 

希望这可以帮助。