You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL游标中WHILE语句返回空值,合并同用户多手机号问题求解

问题原因

你代码存在以下几个核心错误,导致最终插入空值:

  • NULL值判断逻辑错误
    SQL中不能使用=判断变量是否为NULL,必须用IS NULL。你写的IF @Telefonos = NULL永远不会返回真,@Telefonos初始为NULL,后续执行拼接逻辑时NULL + 任意字符串结果仍为NULL,最终插入的手机号字段自然是空值。
  • 游标变量赋值逻辑混乱
    第一层循环首次FETCH的第三个字段Telefono_v1(单条手机号)赋值给了@Prev_Telefono,但后续循环的FETCH却把第三个字段赋值给了@Telefonos,变量对应关系完全错误。
  • 内层循环逻辑冗余且错误
    你已经通过关联临时表让游标返回同一个用户的多条手机号记录,不需要再套内层WHILE @Cuenta !=0的循环。这个内层循环只会反复拼接同一个手机号N次,还会把@Cuenta减到0,最终插入的手机号重复、数量字段也为0,完全不符合需求。
  • 变量未重置
    处理完一个用户的所有手机号后,没有重置@Telefonos变量,会导致下一个用户的手机号和上一个用户的结果拼接在一起。

修正后的游标实现代码

-- 创建目标表
CREATE TABLE Telefono_General_V2 (
    Cedula_v2 varchar(50),
    Nombre_v2 varchar(50),
    Cantidad int, 
    Telefono_v2 varchar(max)
)
GO

-- 声明游标变量
DECLARE
@Cedula varchar(50),
@PrevCedula varchar(50),
@Nombre varchar(50),
@Telefono varchar(max),
@Telefonos varchar(max),
@Cantidad int

-- 声明游标:按身份证排序,同一个用户的记录连续返回
DECLARE cursor_telefonos CURSOR FOR 
SELECT Cedula_v1, Nombre_v1, Telefono_v1
FROM Telefonos_General
WHERE Cedula_v1 is not null
ORDER BY Cedula_v1

OPEN cursor_telefonos  
FETCH NEXT FROM cursor_telefonos INTO @Cedula, @Nombre, @Telefono
SET @PrevCedula = @Cedula
SET @Telefonos = @Telefono
SET @Cantidad = 1

WHILE @@FETCH_STATUS = 0   
BEGIN  
    -- 同一个用户,拼接手机号
    IF @Cedula = @PrevCedula
    BEGIN
        SET @Telefonos = @Telefonos + ', ' + @Telefono
        SET @Cantidad = @Cantidad + 1
    END
    ELSE
    BEGIN
        -- 新用户,先插入上一个用户的数据
        INSERT INTO Telefono_General_V2 (Cedula_v2, Nombre_v2, Cantidad, Telefono_v2)
        VALUES (@PrevCedula, @Nombre, @Cantidad, @Telefonos)
        -- 重置变量为当前新用户的值
        SET @PrevCedula = @Cedula
        SET @Telefonos = @Telefono
        SET @Cantidad = 1
    END
    FETCH NEXT FROM cursor_telefonos INTO @Cedula, @Nombre, @Telefono
END
-- 插入最后一个用户的数据
INSERT INTO Telefono_General_V2 (Cedula_v2, Nombre_v2, Cantidad, Telefono_v2)
VALUES (@PrevCedula, @Nombre, @Cantidad, @Telefonos)

CLOSE cursor_telefonos
DEALLOCATE cursor_telefonos

更优方案(无需游标)

如果你使用的是SQL Server 2017及以上版本,可以直接用内置的STRING_AGG聚合函数实现,性能远高于游标:

INSERT INTO Telefono_General_V2 (Cedula_v2, Nombre_v2, Cantidad, Telefono_v2)
SELECT 
    Cedula_v1,
    MAX(Nombre_v1) AS Nombre_v2,
    COUNT(1) AS Cantidad,
    STRING_AGG(Telefono_v1, ', ') AS Telefono_v2
FROM Telefonos_General
WHERE Cedula_v1 IS NOT NULL
GROUP BY Cedula_v1

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 07:06:04