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

SQL Server如何将表行按Qty字段批量复制为多行至另一表?

解决SQL Server存储过程重复插入、行数翻倍问题

正确的存储过程实现(替代循环的高效方案)

避免使用逐行循环(易引发逻辑错误或并发问题),改用递归CTE生成对应次数的行,直接批量插入:

CREATE PROCEDURE crdShuffleDeck
AS
BEGIN
    SET NOCOUNT ON;

    -- 生成唯一的新RoundID,加锁避免并发冲突
    DECLARE @NewRoundID INT;
    BEGIN TRANSACTION;
    SELECT @NewRoundID = ISNULL(MAX(RoundID), 0) + 1 
    FROM crdShuffle WITH (UPDLOCK, HOLDLOCK);

    -- 递归CTE生成1到最大Qty的数字序列
    WITH NumberSequence AS (
        SELECT 1 AS Num
        UNION ALL
        SELECT Num + 1 FROM NumberSequence 
        WHERE Num < (SELECT MAX(Qty) FROM crdCard)
    )
    -- 批量插入对应次数的行到crdShuffle
    INSERT INTO crdShuffle (RoundID, CardID, /* 替换为你的实际字段 */)
    SELECT 
        @NewRoundID,
        c.CardID,
        -- 这里添加crdCard中需要复制的其他字段
        c.CardName, c.CardType -- 示例字段,根据实际表结构调整
    FROM crdCard c
    JOIN NumberSequence ns ON ns.Num <= c.Qty
    OPTION (MAXRECURSION 0); -- 当最大Qty超过100时必须开启

    COMMIT TRANSACTION;
END

导致重复插入的常见原因

  • 存储过程被重复调用:应用端重复发起请求、作业配置重复执行,或触发器触发多次,导致同一批数据被插入多次。
  • RoundID生成无锁保护:并发场景下多个会话同时获取到相同的RoundID,造成同一RoundID下重复插入数据。
  • 原循环逻辑错误:逐行循环时,内层循环次数计算错误、变量未正确重置,或循环条件导致重复遍历行。
  • 事务处理不当:未正确提交/回滚事务,导致重试时重复插入数据。

排查与修复步骤

  1. 验证调用频次:检查应用日志、SQL Server作业历史,确认crdShuffleDeck是否被多次执行。
  2. 修复RoundID生成逻辑:必须加UPDLOCK, HOLDLOCK锁,确保并发时RoundID唯一,避免冲突。
  3. 替换循环为批量插入:递归CTE的批量插入方式比逐行循环更高效,且避免循环逻辑错误。
  4. 检查表结构与数据:确认crdCard表的Qty字段值是否正确,是否存在异常大值导致插入行数超出预期。
  5. 查看插入时间戳:如果crdShuffle表有创建时间字段,查询重复行的插入时间,判断是单次执行插入多次还是多次执行存储过程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 05:22:17