是否可以在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)
TTe*_*ple 35
不,你不能TRUNCATE表变量,因为它不是物理表.删除它会更快.请参阅Aaron Bertrand的回答.
Mik*_*Vee 11
如果你碰巧在你的变量中有一个Identity-Field (例如)并且你想重新使用这个表(即使你重新声明它,我添加到" 技术上 "正确的答案使用它一个循环)它仍然在范围内,也没有办法重新种植它.DELETE @VariableTable@Tablei int (1,1)
请参阅:表变量标识列
最好#TempTable在这些情况下使用- 然后您可以截断或使用DBCC重新种植.
您将通过Truncate获得性能改进,并能够创建其他索引.
我认为经验法则是,如果你要删除所有使用的东西DELETE @VariableTable,那么你已经引入了一种代码气味,说你应该使用#TempTable而TRUNCATE不是.
表变量不支持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语句受益.
| 归档时间: |
|
| 查看次数: |
80857 次 |
| 最近记录: |