如何使用循环将数据逐步更新到另一个表?

时间:2016-02-18 05:57:32

标签: sql sql-server tsql

我有一个查询,如下所示:

CREATE TABLE #Employee
(Id INT, Name NVARCHAR(100), Status TINYINT)
GO
INSERT INTO #Employee ( Id, Name, Status)
Values (1, 'Basavaraj Biradar', 0),
        (2, 'Shree Biradar', 0),
        (3, 'Kalpana Biradar', 0)
GO

DECLARE @LoopCounter INT = 1, @MaxEmployeeId INT = 10 , 
        @EmployeeName NVARCHAR(100)

WHILE(@LoopCounter <= @MaxEmployeeId)
BEGIN
   SELECT @EmployeeName = (Name)
   FROM #Employee WHERE Id = @LoopCounter


   SET @LoopCounter  = @LoopCounter  + 1     
    PRINT @EmployeeName     
END

给出结果:

Basavaraj Biradar
Shree Biradar
Kalpana Biradar
Kalpana Biradar
Kalpana Biradar
Kalpana Biradar
Kalpana Biradar
Kalpana Biradar
Kalpana Biradar
Kalpana Biradar

预期产出:

1 Basavaraj Biradar
2 Shree Biradar
3 Kalpana Biradar
4 Basavaraj Biradar
5 Shree Biradar
6 Kalpana Biradar
7 Basavaraj Biradar
8 Shree Biradar
9 Kalpana Biradar
10 Basavaraj Biradar
11 Shree Biradar
12 Kalpana Biradar

3 个答案:

答案 0 :(得分:1)

由于表中有3行,SELECT语句只运行3次。之后,它只是继续打印@EmployeeName变量,直到循环中断。因为表中的最后一条记录在EmployeeName列中有'Kalpana Biradar',所以在后续迭代中它不会被更改,因此每次都会打印相同的字符串。

要执行表中实际记录数的循环,可以修改代码以将@MaxEmployeeId设置为:

SELECT @MaxEmployeeId = COUNT(*) FROM #Employee

编辑:

由于你想在到达结尾后从第一条记录开始,代码应该是这样的:

DECLARE @LoopCounter INT = 1, @MaxEmployeeId INT = 10 , 
        @EmployeeName NVARCHAR(100), @AnotherCounter INT = 1

WHILE(@AnotherCounter <= @MaxEmployeeId)
BEGIN
   SELECT @EmployeeName = (Name)
   FROM #Employee WHERE Id = @LoopCounter

   IF @LoopCounter >= (SELECT COUNT(*) FROM #Employee)
         SET @LoopCounter = 1
   ELSE
      SET @LoopCounter  = @LoopCounter  + 1 

    PRINT @EmployeeName
    SET @AnotherCounter = @AnotherCounter + 1     
END

DROP TABLE #employee

答案 1 :(得分:1)

您需要两个循环。外部循环定义重复次数,而内部循环将打印表中的所有可用名称。 试试这个 -

CREATE TABLE #Employee
(Id INT, Name NVARCHAR(100), Status TINYINT)
GO
INSERT INTO #Employee ( Id, Name, Status)
Values (1, 'Basavaraj Biradar', 0),
        (2, 'Shree Biradar', 0),
        (3, 'Kalpana Biradar', 0)
GO

DECLARE @OuterLoopCounter INT = 1, 
        @InnerLoopCounter INT=1,
        @MaxEmployeeID INT,
        @EmployeeName nvarchar(100)

WHILE @OuterLoopCounter <= 4 -- Change to whatever value
BEGIN
   SELECT @MaxEmployeeID = MAX(ID) FROM #Employee
   WHILE @InnerLoopCounter <= @MaxEmployeeID
   BEGIN
        SELECT @EmployeeName = Name
        FROM #Employee WHERE Id = @InnerLoopCounter
        PRINT @EmployeeName 
        SET @InnerLoopCounter  = @InnerLoopCounter  + 1     
   END
   SET @InnerLoopCounter = 1
   SET @OuterLoopCounter =@OuterLoopCounter +1
END

答案 2 :(得分:0)

这可以在没有unsigned int循环或WHILE的情况下完成。您所需要的只是Tally Table

SQL Fiddle

CURSOR

如果它只是重​​复记录的次数:

SQL Fiddle

DECLARE @MaxEmployeeId INT = 10;

DECLARE @N INT; 
SELECT @N = CEILING(@MaxEmployeeId/(COUNT(*)*1.0)) FROM #Employee;

;WITH E1(N) AS(
    SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N)
),
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b),
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b),
CteTally(N) AS(
    SELECT TOP(@N) ROW_NUMBER() OVER(ORDER BY(SELECT NULL))
    FROM E4
),
CteFinal AS(
    SELECT *, Rn = ROW_NUMBER() OVER(ORDER BY N, Id) 
    FROM #Employee e
    CROSS JOIN CteTally t
)
SELECT Rn, Name FROM CteFinal WHERE Rn <= @MaxEmployeeId ORDER BY Rn

结果:

DECLARE @RepeatTimes INT = 4
;WITH E1(N) AS(
    SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N)
),
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b),
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b),
CteTally(N) AS(
    SELECT TOP(@RepeatTimes) ROW_NUMBER() OVER(ORDER BY(SELECT NULL))
    FROM E4
)
SELECT 
    Rn = ROW_NUMBER() OVER(ORDER BY N, Id), e.Name
FROM Employee e
CROSS JOIN CteTally t
ORDER BY Rn