首页 > 解决方案 > SQL Server:CTE WHILE LOOP 将相同的值分配给变量

问题描述

我有一个名为 prd0101 的表,其中包含以下数据:

codi        descr               nomfam                  nomsub          nomgru      marc    codf                peso    estado  fe_i
---------------------------------------------------------------------------------------------------------------------------------------------------------
0301-011611 TIRAS DE PRUEBA     PRODUCTOS TERMINADOS    ALIGERADOS      ALIGERADOS  ND      123456789ABCDEF     0.0250  1       2019-06-27 00:00:00.000
0301-011612 TIRAS PRUEBAS 2     PRODUCTOS TERMINADOS    ALIGERADOS      ALIGERADOS  ND      123456789ABCDE1     0.0360  1       2019-06-27 00:00:00.000
0301-011613 TIRAS PRUEBA 3      PRODUCTOS TERMINADOS    ALIGERADOS      ALIGERADOS  ND      123456789ABCDEF2    0.0690  1       2019-06-27 00:00:00.000

这是我选择数据并将其插入另一个名为 product2 的表中的查询:

DECLARE 
     @COUNTER INT = 0 ,
     @MAX INT = (SELECT COUNT(*)
                 FROM prd0101 p 
                 LEFT JOIN tbl01itm i ON p.codi = i.codi
                 LEFT JOIN tbl01grp g ON g.codgru = i.codgru
                 LEFT JOIN tbl01sbf s ON s.codsub = g.codsub
                 LEFT JOIN tbl01fam f ON f.codfam = s.codfam
                 WHERE p.fe_i >= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)),
     @CODI NVARCHAR(100), 
     @DESCR NVARCHAR(100), 
     @NOMFAM NVARCHAR(100),
     @NOMSUB NVARCHAR(100), 
     @NOMGRU NVARCHAR(100), 
     @MARC NVARCHAR(100), 
     @CODF NVARCHAR(100),
     @PESO NVARCHAR(100), 
     @ESTADO NVARCHAR(100)


WHILE @COUNTER < @MAX
BEGIN
    --cte
    ;WITH cte AS
    (
        SELECT   
            p.codi, p.descr, f.nomfam, s.nomsub,
            g.nomgru, p.marc, p.codf, p.peso, p.estado, p.fe_i
        FROM 
            prd0101 p 
        LEFT JOIN
            tbl01itm i ON p.codi = i.codi
        LEFT JOIN
            tbl01grp g ON g.codgru = i.codgru
        LEFT JOIN
            tbl01sbf s ON s.codsub = g.codsub
        LEFT JOIN
            tbl01fam f ON f.codfam = s.codfam
    )
    SELECT 
        @CODI = cte.codi, @DESCR = cte.descr, 
        @NOMFAM = cte.nomfam, @NOMSUB = cte.nomsub, 
        @NOMGRU = cte.nomgru, @MARC = cte.marc, 
        @CODF = cte.codf, @PESO = cte.peso, @ESTADO = cte.estado
    FROM 
        cte
    WHERE 
        cte.fe_i >= DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)
        AND cte.estado = 1

    IF NOT EXISTS (SELECT codi FROM Product2 WHERE codi = @CODI)
    BEGIN
        INSERT INTO Product2 (codi, "Description", Familia__c, Subfamilia__c, Grupo__c, Marca__c, ProductCode, Peso__c, IsActive)
        VALUES (@CODI, @DESCR, @NOMFAM, @NOMSUB, @NOMGRU, @MARC, @CODF, @PESO, @ESTADO)
    END

    SET @COUNTER = @COUNTER + 1
END

问题是在循环中它总是分配相同的记录。codi = 0301-011613 的记录

我在循环中打印了一些变量,并为它们中的 3 个打印了相同的最后一行。

我希望插入 3 条记录,但它只插入最后一条。

标签: sql-servervariableswhile-loopcommon-table-expression

解决方案


我修复了它,将其添加到 cte 选择中:

ROW_NUMBER() OVER(ORDER BY p.codi) AS 'Row1'

在 WHERE 子句之后的 cte 之外,我添加了这个:

AND Row1 = @COUNTER + 1

正如我预期的那样迭代所有行。


推荐阅读