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

动态数据映射存储过程输出重复问题求助

问题描述

我有一张包含SourceTable、SourceField、DestinationTable、DestinationField、ExtraMappingLogin字段的表。为实现源表到目标表的动态数据映射,编写了如下存储过程,但执行PRINT时输出的SQL语句出现重复,我仅需插入第一行数据,不清楚重复原因,请求协助排查。

Declare   @O_Cols           sysname
        , @N_Cols           sysname
        , @O_Tabl           sysname
        , @N_Tabl           sysname
        , @InsertColsList   NVARCHAR(MAX) =''
        , @SelectColsLIst   NVARCHAR(MAX) =''
        , @Sql              NVARCHAR(MAX);

DROP TABLE IF EXISTS #Unq   
 Select distinct SourceTable,[DestinationTable], ranking 
 into #Unq from (SELECT
    SourceTable,[DestinationTable],
    DENSE_RANK () OVER ( 
        ORDER BY [DestinationTable] DESC
    ) ranking 
FROM
    ##MappingData where Destinationtable IS NOT NULL) A

DECLARE @inirow INT=1;  
DECLARE @NumberofRowint INT
DECLARE @DestTable NVARCHAR(50)  
SELECT @NumberofRowint = COUNT(*) FROM #Unq

WHILE @inirow <= @NumberofRowInt  
BEGIN

SELECT @DestTable = DestinationTable
      ,@O_Tabl = SourceTable
FROM #Unq WHERE ranking=@inirow  

DECLARE Cur CURSOR LOCAL FAST_FORWARD FOR
SELECT  SourceField AS OriginalColumn ,  DestinationField AS NewColumn

FROM ##MappingData
WHERE DestinationTable = @DestTable
OPEN Cur
  FETCH NEXT FROM Cur INTO @O_Cols , @N_Cols

WHILE (@@FETCH_STATUS = 0)
BEGIN
        SET @SelectColsLIst += ISNULL(',' + QUOTENAME(@O_Cols), '');
        SET @InsertColsList += ISNULL(',' + QUOTENAME(@N_Cols), '');
    
    FETCH NEXT FROM Cur INTO @O_Cols , @N_Cols
END

CLOSE Cur
DEALLOCATE Cur;

    SET @SelectColsLIst = STUFF(@SelectColsLIst, 1 ,1,'');
    SET @InsertColsList = STUFF(@InsertColsList, 1 ,1,'');

 SET @Sql = N' INSERT INTO ' + @DestTable + N'( ' + @InsertColsList + N' )'
          + N' SELECT ' + @SelectColsLIst
          + N' FROM ' + @O_Tabl;
PRINT @Sql
END
--EXEC sp_executesql @Sql;
问题排查与解决

核心原因

  1. 变量未重置:@SelectColsLIst和@InsertColsList在循环外初始化,每次处理新目标表时未清空,导致字段拼接结果累积,最终SQL出现重复字段。
  2. 循环逻辑冗余:外层WHILE会遍历#Unq所有行生成多条插入语句,不符合仅处理第一行的需求。

修正后的代码

Declare   @O_Cols           sysname
        , @N_Cols           sysname
        , @O_Tabl           sysname
        , @N_Tabl           sysname
        , @InsertColsList   NVARCHAR(MAX) =''
        , @SelectColsLIst   NVARCHAR(MAX) =''
        , @Sql              NVARCHAR(MAX);

DROP TABLE IF EXISTS #Unq   
Select distinct SourceTable,[DestinationTable], ranking 
into #Unq from (SELECT
    SourceTable,[DestinationTable],
    DENSE_RANK () OVER ( 
        ORDER BY [DestinationTable] DESC
    ) ranking 
FROM
    ##MappingData where Destinationtable IS NOT NULL) A

-- 直接取第一行映射关系
SELECT @DestTable = DestinationTable
      ,@O_Tabl = SourceTable
FROM #Unq WHERE ranking=1  

DECLARE Cur CURSOR LOCAL FAST_FORWARD FOR
SELECT  SourceField AS OriginalColumn ,  DestinationField AS NewColumn
FROM ##MappingData
WHERE DestinationTable = @DestTable

OPEN Cur
FETCH NEXT FROM Cur INTO @O_Cols , @N_Cols

WHILE (@@FETCH_STATUS = 0)
BEGIN
        SET @SelectColsLIst += ISNULL(',' + QUOTENAME(@O_Cols), '');
        SET @InsertColsList += ISNULL(',' + QUOTENAME(@N_Cols), '');
    
    FETCH NEXT FROM Cur INTO @O_Cols , @N_Cols
END

CLOSE Cur
DEALLOCATE Cur;

SET @SelectColsLIst = STUFF(@SelectColsLIst, 1 ,1,'');
SET @InsertColsList = STUFF(@InsertColsList, 1 ,1,'');

SET @Sql = N' INSERT INTO ' + @DestTable + N'( ' + @InsertColsList + N' )'
          + N' SELECT ' + @SelectColsLIst
          + N' FROM ' + @O_Tabl;
PRINT @Sql
--EXEC sp_executesql @Sql;

关键修改点

  • 移除外层WHILE循环,直接通过ranking=1获取第一行需处理的映射关系。
  • 确保字段拼接仅针对单个目标表,无累积重复。

若后续需处理多个目标表,只需在每次循环开始时重置拼接变量:

WHILE @inirow <= @NumberofRowInt  
BEGIN
    -- 重置字段拼接变量
    SET @SelectColsLIst = '';
    SET @InsertColsList = '';

    SELECT @DestTable = DestinationTable
          ,@O_Tabl = SourceTable
    FROM #Unq WHERE ranking=@inirow  

    -- 后续游标逻辑不变...
END

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:55:18