假设我有以下简单的表变量:
declare @databases table
(
DatabaseID int,
Name varchar(15),
Server varchar(15)
)
-- insert a bunch rows into @databases
如果我想遍历各行,声明和使用游标是我唯一的选择吗?还有别的办法吗?
假设我有以下简单的表变量:
declare @databases table
(
DatabaseID int,
Name varchar(15),
Server varchar(15)
)
-- insert a bunch rows into @databases
如果我想遍历各行,声明和使用游标是我唯一的选择吗?还有别的办法吗?
当前回答
我是这样做的:
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列必须是唯一的整数,就像大多数主键一样。
其他回答
-- [PO_RollBackOnReject] 'FININV10532'
alter procedure PO_RollBackOnReject
@CaseID nvarchar(100)
AS
Begin
SELECT *
INTO #tmpTable
FROM PO_InvoiceItems where CaseID = @CaseID
Declare @Id int
Declare @PO_No int
Declare @Current_Balance Money
While (Select ROW_NUMBER() OVER(ORDER BY PO_LineNo DESC) From #tmpTable) > 0
Begin
Select Top 1 @Id = PO_LineNo, @Current_Balance = Current_Balance,
@PO_No = PO_No
From #Temp
update PO_Details
Set Current_Balance = Current_Balance + @Current_Balance,
Previous_App_Amount= Previous_App_Amount + @Current_Balance,
Is_Processed = 0
Where PO_LineNumber = @Id
AND PO_No = @PO_No
update PO_InvoiceItems
Set IsVisible = 0,
Is_Processed= 0
,Is_InProgress = 0 ,
Is_Active = 0
Where PO_LineNo = @Id
AND PO_No = @PO_No
End
End
Step1:下面的select语句为每条记录创建一个具有唯一行号的临时表。
select eno,ename,eaddress,mobno int,row_number() over(order by eno desc) as rno into #tmp_sri from emp
步骤2:声明所需的变量
DECLARE @ROWNUMBER INT
DECLARE @ename varchar(100)
步骤3:从临时表中获取总行数
SELECT @ROWNUMBER = COUNT(*) FROM #tmp_sri
declare @rno int
Step4:根据在temp中创建的唯一行号循环temp表
while @rownumber>0
begin
set @rno=@rownumber
select @ename=ename from #tmp_sri where rno=@rno **// You can take columns data from here as many as you want**
set @rownumber=@rownumber-1
print @ename **// instead of printing, you can write insert, update, delete statements**
end
轻量级,不需要创建额外的表,如果您在表上有一个整数ID
Declare @id int = 0, @anything nvarchar(max)
WHILE(1=1) BEGIN
Select Top 1 @anything=[Anything],@id=@id+1 FROM Table WHERE ID>@id
if(@@ROWCOUNT=0) break;
--Process @anything
END
我更喜欢使用偏移获取,如果你有一个唯一的ID,你可以排序你的表:
DECLARE @TableVariable (ID int, Name varchar(50));
DECLARE @RecordCount int;
SELECT @RecordCount = COUNT(*) FROM @TableVariable;
WHILE @RecordCount > 0
BEGIN
SELECT ID, Name FROM @TableVariable ORDER BY ID OFFSET @RecordCount - 1 FETCH NEXT 1 ROW;
SET @RecordCount = @RecordCount - 1;
END
这样我就不需要向表中添加字段或使用窗口函数。
可以使用游标来做到这一点:
创建函数[dbo].f_teste_loop 返回@tabela表 ( 鳕鱼int, 省varchar (10) ) 作为 开始
insert into @tabela values (1, 'verde');
insert into @tabela values (2, 'amarelo');
insert into @tabela values (3, 'azul');
insert into @tabela values (4, 'branco');
return;
end
创建过程[dbo].[sp_test_loop] 作为 开始
DECLARE @cod int, @nome varchar(10);
DECLARE curLoop CURSOR STATIC LOCAL
FOR
SELECT
cod
,nome
FROM
dbo.f_teste_loop();
OPEN curLoop;
FETCH NEXT FROM curLoop
INTO @cod, @nome;
WHILE (@@FETCH_STATUS = 0)
BEGIN
PRINT @nome;
FETCH NEXT FROM curLoop
INTO @cod, @nome;
END
CLOSE curLoop;
DEALLOCATE curLoop;
end