我看过许多关于SQL Server游标方面的文章,大部分都对它抱怨连连。我也不例外,真希望SQL Server从来没有引入这样一个功能。但是事实已然这样,抱怨是无济于事的。游标造成的问题有很多,比如延长锁问题,无法缓存执行计划以及加大内存与CPU开销问题等。许多T-SQL程序员和DBA都不知道如何不使用游标而成功记录循环。在本文中,我将分享一些不使用游标而实现循环功能的方法。
方法一:带有标识列的临时表
在这一方法中,我们将使用带有标识列的临时表,它允许逐行选择。如果你执行一个INSERT/UPDATE/DELETE命令,要确保使用显式事务。在每次循环交付时,这将极大地减少你的日志文件负载,并且在失败时阻止了大量的回滚。
set nocount on
declare @i int --iterator
declare @iRwCnt int --rowcount
declare @sValue varchar(100)
set @i = 1 --initialize
create table #tbl(ID int identity(1,1), Value varchar(100))
insert into #tbl(Value)
select name
from master..sysdatabases (nolock)
set @iRwCnt = @@ROWCOUNT --SCOPE_IDENTITY() would also work
create clustered index idx_tmp on #tbl(ID) WITH FILLFACTOR = 100
/*
每次执行插入都要进行此操作,因为批量添加索引总比每次写入临时表时更新索引要快。既然你已知道列中的数据,你可以将填充因子设置为100%以获取最佳的读取时间。
*/
while @i <= @iRwCnt
begin
select @sValue = Value from #tbl where ID = @i
--begin tran
print 'My Value is ' + @sValue --replace with your operations on this value
--commit tran
set @i = @i + 1
end
drop table #tbl