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

如何按不同UID分批执行存储过程处理表中对应每行数据

解决方案

原有代码问题

  • 声明VARCHAR类型未指定长度,默认长度为1会导致数据截断,逻辑直接失效
  • 内层游标仅遍历UID值,未读取当前UID对应所有行的其余字段参数,也没有实际关联行调用存储过程的逻辑,因此无法实现按UID批量处理的要求

方案1:优化游标实现(推荐,代码简洁性能足够)

使用FAST_FORWARD类型游标(只读、只进,性能开销极低),外层遍历唯一UID,内层遍历当前UID下所有行调用存储过程,完全符合业务要求:

-- 声明存储过程需要的所有入参变量,根据实际字段类型调整
DECLARE 
    @UID VARCHAR(50),
    @Version INT,
    @Site VARCHAR(10),
    @QuestionOI INT,
    @GeneralAnswer VARCHAR(100)

-- 外层游标:遍历所有唯一UID,保证按UID分批
DECLARE uid_cursor CURSOR FAST_FORWARD FOR
SELECT DISTINCT UID FROM #InsertTable
ORDER BY UID -- 可按需要调整排序规则

OPEN uid_cursor
FETCH NEXT FROM uid_cursor INTO @UID

WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT 'Processing UID: ' + @UID
    -- 内层游标:读取当前UID对应的所有行参数,循环调用存储过程
    DECLARE row_cursor CURSOR FAST_FORWARD FOR
    SELECT Version, Site, QuestionOI, GeneralAnswer 
    FROM #InsertTable 
    WHERE UID = @UID

    OPEN row_cursor
    FETCH NEXT FROM row_cursor INTO @Version, @Site, @QuestionOI, @GeneralAnswer

    WHILE @@FETCH_STATUS = 0
    BEGIN
        -- 调用存储过程,按实际参数顺序调整
        EXEC stored_proc @UID, @Version, @Site, @QuestionOI, @GeneralAnswer
        FETCH NEXT FROM row_cursor INTO @Version, @Site, @QuestionOI, @GeneralAnswer
    END

    CLOSE row_cursor
    DEALLOCATE row_cursor

    FETCH NEXT FROM uid_cursor INTO @UID
END

CLOSE uid_cursor
DEALLOCATE uid_cursor
PRINT 'All tasks completed'

方案2:无游标循环实现

如果不想使用游标,可以用临时表加行号的方式实现,逻辑同样直观:

-- 生成带唯一行号的临时表,区分不同UID和同一UID下的行
SELECT 
    DENSE_RANK() OVER (ORDER BY UID) AS uid_batch, -- 同一UID批次号相同
    ROW_NUMBER() OVER (PARTITION BY UID ORDER BY (SELECT 1)) AS row_in_batch,
    UID, Version, Site, QuestionOI, GeneralAnswer
INTO #temp_process
FROM #InsertTable

DECLARE 
    @current_batch INT = 1,
    @max_batch INT,
    @current_row INT,
    @max_row INT,
    @UID VARCHAR(50),
    @Version INT,
    @Site VARCHAR(10),
    @QuestionOI INT,
    @GeneralAnswer VARCHAR(100)

SELECT @max_batch = MAX(uid_batch) FROM #temp_process

WHILE @current_batch <= @max_batch
BEGIN
    -- 取当前批次UID
    SELECT TOP 1 @UID = UID FROM #temp_process WHERE uid_batch = @current_batch
    PRINT 'Processing UID: ' + @UID

    SELECT @current_row = 1, @max_row = MAX(row_in_batch) 
    FROM #temp_process 
    WHERE uid_batch = @current_batch

    -- 处理当前UID下所有行
    WHILE @current_row <= @max_row
    BEGIN
        SELECT 
            @Version = Version,
            @Site = Site,
            @QuestionOI = QuestionOI,
            @GeneralAnswer = GeneralAnswer
        FROM #temp_process 
        WHERE uid_batch = @current_batch AND row_in_batch = @current_row

        EXEC stored_proc @UID, @Version, @Site, @QuestionOI, @GeneralAnswer
        SET @current_row += 1
    END

    SET @current_batch += 1
END

DROP TABLE #temp_process
PRINT 'All tasks completed'

性能说明

5000行数据量级下两种方案的执行效率几乎没有差异,外层循环的开销可以忽略,核心耗时取决于内部存储过程的执行速度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 12:06:05