假设我有以下简单的表变量:

declare @databases table
(
    DatabaseID    int,
    Name        varchar(15),   
    Server      varchar(15)
)
-- insert a bunch rows into @databases

如果我想遍历各行,声明和使用游标是我唯一的选择吗?还有别的办法吗?


当前回答

简单说明一下,如果你使用的是SQL Server(2008及以上版本),下面的例子有:

While (Select Count(*) From #Temp) > 0

会不会更好

While EXISTS(SELECT * From #Temp)

Count将不得不触及表中的每一行,EXISTS只需要触及第一行。

其他回答

你可以使用while循环:

While (Select Count(*) From #TempTable) > 0
Begin
    Insert Into @Databases...

    Delete From #TempTable Where x = x
End

我真的不明白为什么你需要使用可怕的光标。 但是如果你使用的是2005/2008版本的SQL Server,还有另一种选择 使用递归

declare @databases table
(
    DatabaseID    int,
    Name        varchar(15),   
    Server      varchar(15)
)

--; Insert records into @databases...

--; Recurse through @databases
;with DBs as (
    select * from @databases where DatabaseID = 1
    union all
    select A.* from @databases A 
        inner join DBs B on A.DatabaseID = B.DatabaseID + 1
)
select * from DBs

我将提供基于集合的解决方案。

insert  @databases (DatabaseID, Name, Server)
select DatabaseID, Name, Server 
From ... (Use whatever query you would have used in the loop or cursor)

这比任何循环技术都要快得多,而且更容易编写和维护。

SELECT @pk = @pk + 1

会更好:

SET @pk += @pk

避免使用SELECT如果你没有引用表,只是分配值。

我是这样做的:

declare @RowNum int, @CustId nchar(5), @Name1 nchar(25)

select @CustId=MAX(USERID) FROM UserIDs     --start with the highest ID
Select @RowNum = Count(*) From UserIDs      --get total number of records
WHILE @RowNum > 0                          --loop until no more records
BEGIN   
    select @Name1 = username1 from UserIDs where USERID= @CustID    --get other info from that row
    print cast(@RowNum as char(12)) + ' ' + @CustId + ' ' + @Name1  --do whatever

    select top 1 @CustId=USERID from UserIDs where USERID < @CustID order by USERID desc--get the next one
    set @RowNum = @RowNum - 1                               --decrease count
END

没有游标,没有临时表,没有额外的列。 USERID列必须是唯一的整数,就像大多数主键一样。