Is there anyway to loop through a table variable in T-SQL?
DECLARE @table1 TABLE ( col1 int )
INSERT into @table1 SELECT col1 FROM table2
Here's another answer, similar to Justin's, but doesn't need an identity or aggregate, just a primary (unique) key.
declare @table1 table(dataKey int, dataCol1 varchar(20), dataCol2 datetime)
declare @dataKey int
while exists select 'x' from @table1
begin
select top 1 @dataKey = dataKey
from @table1
order by /*whatever you want:*/ dataCol2 desc
-- do processing
delete from @table1 where dataKey = @dataKey
end
My two cents.. From KM.'s answer, if you want to drop one variable, you can do a countdown on @RowsToProcess instead of counting up.
DECLARE @RowsToProcess int;
DECLARE @table1 TABLE (RowID int not null primary key identity(1,1), col1 int )
INSERT into @table1 (col1) SELECT col1 FROM table2
SET @RowsToProcess = @@ROWCOUNT
WHILE @RowsToProcess > 0 -- Countdown
BEGIN
SELECT *
FROM @table1
WHERE RowID=@RowsToProcess
--do your thing here--
SET @RowsToProcess = @RowsToProcess - 1; -- Countdown
END
DECLARE @table1 TABLE (
idx int identity(1,1),
col1 int )
DECLARE @counter int
SET @counter = 1
WHILE(@counter < SELECT MAX(idx) FROM @table1)
BEGIN
DECLARE @colVar INT
SELECT @colVar = col1 FROM @table1 WHERE idx = @counter
-- Do your work here
SET @counter = @counter + 1
END
Believe it or not, this is actually more efficient and performant than using a cursor.
look like this demo:
DECLARE @vTable TABLE (IdRow int not null primary key identity(1,1),ValueRow int);
-------Initialize---------
insert into @vTable select 345;
insert into @vTable select 795;
insert into @vTable select 565;
---------------------------
DECLARE @cnt int = 1;
DECLARE @max int = (SELECT MAX(IdRow) FROM @vTable);
WHILE @cnt <= @max
BEGIN
DECLARE @tempValueRow int = (Select ValueRow FROM @vTable WHERE IdRow = @cnt);
---work demo----
print '@tempValueRow:' + convert(varchar(10),@tempValueRow);
print '@cnt:' + convert(varchar(10),@cnt);
print'';
--------------
set @cnt = @cnt+1;
END
Version without idRow, using ROW_NUMBER
DECLARE @vTable TABLE (ValueRow int);
-------Initialize---------
insert into @vTable select 345;
insert into @vTable select 795;
insert into @vTable select 565;
---------------------------
DECLARE @cnt int = 1;
DECLARE @max int = (select count(*) from @vTable);
WHILE @cnt <= @max
BEGIN
DECLARE @tempValueRow int = (
select ValueRow
from (select ValueRow
, ROW_NUMBER() OVER(ORDER BY (select 1)) as RowId
from @vTable
) T1
where t1.RowId = @cnt
);
---work demo----
print '@tempValueRow:' + convert(varchar(10),@tempValueRow);
print '@cnt:' + convert(varchar(10),@cnt);
print'';
--------------
set @cnt = @cnt+1;
END
Select Top 1 can easily resolve it without the need of any sequence/order.
Create Function Test_Range()
Returns
@Result Table (ID Int)
As
Begin
Declare @ID Varchar(10) = ''
Declare @Rows Int, @Row Int = 0
Declare @Num Int, @RangeTo Int
Declare @RangeTable Table (ID Varchar(10), RangeFrom Int, RangeTo Int)
Insert Into @RangeTable Values ('A', 1, 10)
Insert Into @RangeTable Values ('B', 25,30)
Set @Rows = (Select Count(*) From @RangeTable)
While @Row <= @Rows
Begin
Set @Row = @Row + 1
Select Top 1 @ID = ID, @Num = RangeFrom, @RangeTo = RangeTo From @RangeTable
Where ID > @ID
While @Num <= @RangeTo
Begin
Insert Into @Result Values (@Num)
Set @Num = @Num + 1
End
End
Return
End