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

如何按条件从源表向多张目标表插入数据

数据批量插入方案

需求概述

从源表向指定目标表插入数据,需满足:

  • 严格按照参数表定义的行数插入,无重复数据
  • 同批次(相同FILENAME)下,按ID顺序划分源表数据行范围:先取前N行插入第一个目标表,再接着取M行插入下一个目标表(如FILENAME_X批次,前200行入TABLE_A,第201-500行入TABLE_B)

数据表结构

参数表(dbo.parameter_table)

ID批次文件名总数据行数待插入行数目标表
1FILENAME_X500200TABLE_A
2FILENAME_X500300TABLE_B
3FILENAME_Y400100TABLE_C
4FILENAME_Y400300TABLE_D

源表

源表ID(s_id)手机号姓名
78Cell 1Cell 2
88Cell 3Cell 4

目标表(TABLE_A/TABLE_B/TABLE_C/TABLE_D,结构完全一致)

ID手机号姓名
1XXXXXXXX
2XXXXXXXX
3XXXXXXXX
4XXXXXXXX

修正后的SQL实现代码

原代码存在变量重复赋值、游标未声明、无批次行号跟踪等问题,以下是完善版本:

-- 声明变量
DECLARE @RowNum INT,
        @ID INT,
        @FILENAME VARCHAR(100),
        @TOTAL_ROWS INT,
        @NUMBER_OF_ROWS_TO_INSERT INT,
        @DESTINATION_TABLE VARCHAR(100),
        @CurrentStartRow INT = 1 -- 跟踪当前批次的起始行号

-- 声明游标:按批次分组,同批次内按ID排序确保插入顺序正确
DECLARE cursor_files CURSOR FOR
SELECT 
    ROW_NUMBER() OVER(PARTITION BY FILENAME ORDER BY ID) AS RowNum,
    ID,
    FILENAME,
    TOTAL_ROWS,
    NUMBER_OF_ROWS_TO_INSERT,
    DESTINATION_TABLE
FROM [dbo].[parameter_table]
ORDER BY FILENAME, ID

OPEN cursor_files
-- 首次读取游标数据
FETCH NEXT FROM cursor_files INTO @RowNum, @ID, @FILENAME, @TOTAL_ROWS, @NUMBER_OF_ROWS_TO_INSERT, @DESTINATION_TABLE

WHILE @@FETCH_STATUS = 0
BEGIN
    IF @NUMBER_OF_ROWS_TO_INSERT > 0
    BEGIN
        -- 动态构建插入语句,按行范围筛选源表数据
        DECLARE @InsertSQL NVARCHAR(MAX)
        SET @InsertSQL = N'
        INSERT INTO ' + QUOTENAME(@DESTINATION_TABLE) + ' (ID, PHONE, NAME)
        SELECT s_id, PHONE, NAME
        FROM (
            -- 对源表数据生成连续行号,确保行范围稳定(可根据实际需求调整排序字段)
            SELECT 
                s_id, 
                PHONE, 
                NAME,
                ROW_NUMBER() OVER(ORDER BY s_id) AS SourceRowNum
            FROM [dbo].[source_table] -- 替换为你的实际源表名称
        ) t
        WHERE SourceRowNum BETWEEN ' + CAST(@CurrentStartRow AS NVARCHAR(10)) + ' 
          AND ' + CAST(@CurrentStartRow + @NUMBER_OF_ROWS_TO_INSERT - 1 AS NVARCHAR(10))
        
        -- 执行动态SQL
        EXEC sp_executesql @InsertSQL

        -- 更新下一次插入的起始行号
        SET @CurrentStartRow = @CurrentStartRow + @NUMBER_OF_ROWS_TO_INSERT
    END

    -- 检查下一条数据是否属于新批次,若是则重置起始行号
    DECLARE @NextFilename VARCHAR(100)
    FETCH NEXT FROM cursor_files INTO @RowNum, @ID, @NextFilename, @TOTAL_ROWS, @NUMBER_OF_ROWS_TO_INSERT, @DESTINATION_TABLE
    IF @@FETCH_STATUS = 0
    BEGIN
        IF @NextFilename <> @FILENAME
        BEGIN
            SET @CurrentStartRow = 1
            -- 回退游标,确保下一次循环处理当前读取的新批次数据
            FETCH PRIOR FROM cursor_files INTO @RowNum, @ID, @FILENAME, @TOTAL_ROWS, @NUMBER_OF_ROWS_TO_INSERT, @DESTINATION_TABLE
        END
        ELSE
        BEGIN
            -- 回退游标,继续处理当前批次
            FETCH PRIOR FROM cursor_files INTO @RowNum, @ID, @FILENAME, @TOTAL_ROWS, @NUMBER_OF_ROWS_TO_INSERT, @DESTINATION_TABLE
        END
    END

    -- 读取下一条游标数据
    FETCH NEXT FROM cursor_files INTO @RowNum, @ID, @FILENAME, @TOTAL_ROWS, @NUMBER_OF_ROWS_TO_INSERT, @DESTINATION_TABLE
END

-- 清理游标
CLOSE cursor_files
DEALLOCATE cursor_files

关键实现说明

  • 批次行号跟踪:用@CurrentStartRow变量记录当前批次的起始行,避免跨批次行号混乱,确保同批次内数据连续无重复
  • 动态SQL适配:通过QUOTENAME函数防止SQL注入,同时适配不同目标表
  • 游标分组排序:用PARTITION BY FILENAME对批次分组,同批次内按ID排序,保证插入顺序符合需求
  • 源表行号稳定:对源表数据生成连续行号(按s_id排序),确保每次执行的行范围一致

内容的提问来源于stack exchange,提问作者BΛDЯ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 02:01:14