在Sql Server 2008中截断/清除表变量

shr*_*eep 61 sql sql-server

是否可以在sql server 2008中截断或清除表变量?

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 
Run Code Online (Sandbox Code Playgroud)

pet*_*ter 83

只是删除一切

DELETE FROM @tableVariable
Run Code Online (Sandbox Code Playgroud)

  • 一个更好的答案是"你不能",然后解释替代方案. (29认同)
  • 这将有效,但请记住,正如@ Martin%20Smith在下面指出的那样,将删除此删除.如果变量中有很多行,或者这个SQL将定期执行,这可能会有问题. (3认同)

TTe*_*ple 35

不,你不能TRUNCATE表变量,因为它不是物理表.删除它会更快.请参阅Aaron Bertrand的回答.

  • 对于大量的行`TRUNCATE`肯定会更快.从表变量中删除会记录到`tempdb`事务日志中. (4认同)
  • 如果你不能截断它就不会更快。只有删除选项。 (4认同)

Mik*_*Vee 11

如果你碰巧在你的变量中有一个Identity-Field (例如)并且你想重新使用这个表(即使你重新声明它,我添加到" 技术上 "正确的答案使用它一个循环)它仍然在范围内,也没有办法重新种植它.DELETE @VariableTable@Tablei int (1,1)

请参阅:表变量标识列

最好#TempTable在这些情况下使用- 然后您可以截断或使用DBCC重新种植.
您将通过Truncate获得性能改进,并能够创建其他索引.
我认为经验法则是,如果你要删除所有使用的东西DELETE @VariableTable,那么你已经引入了一种代码气味,说你应该使用#TempTable而TRUNCATE不是.


Mar*_*ith 7

表变量不支持TRUNCATE语法 - 通过让它们超出范围隐式地截断它们的唯一方法.

临时表和表变量在存储过程中使用时都可以缓存,下面可能最终使用截断后使用的相同表变量而不是实际的drop并创建

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 
Run Code Online (Sandbox Code Playgroud)

当然,更容易的替代方案是切换到使用#temp表而不是TRUNCATE直接支持.

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

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