【问题标题】:Insert into from temp table - creating too many rows从临时表插入 - 创建太多行
【发布时间】:2010-10-12 23:49:25
【问题描述】:

我将 CSV 文件批量导入到临时表中,然后将行插入到目标表中(如果它们不存在)。

当我开始这个过程时,我的表有以下值

VECH01 AAA 111
VECH01 BBB 222
VECH01 CCC 333
VECH02 AAA 111
VECH02 BBB 222
VECH02 CCC 333

当我导入具有这些值的 CSV 文件时:

VECH01|DDD|444
VECH01|DDD|555
VECH02|CCC|XXX

第一行导入VECH01 DDD不在数据库中。
OK

第 2 行已导入,但 VECH01 DDD 已在数据库中,它是在上一次插入时导入的。
NOT OK

第 3 行未导入,因为 VECH02 CCC 已存在于数据库中。
OK

CREATE TABLE #csv 
(
 CarRedbookCode nvarchar(50) COLLATE Latin1_General_CI_AS,
 AccessoryCode nvarchar(50) COLLATE Latin1_General_CI_AS,
 AccessoryCodeAutoGeneral nvarchar(50) COLLATE Latin1_General_CI_AS
)

DECLARE @SqlStatement nvarchar(4000)
SET @SqlStatement =
'
BULK INSERT #csv
 FROM ''' + @FileName + '''
    WITH 
    ( 
        FIELDTERMINATOR = ''|'', 
        ROWTERMINATOR = ''\n'' 
    )
'
EXEC sp_executesql @SqlStatement

INSERT INTO  MapRedbookAccessory (CarRedbookCodeAccessoryCode, CarRedbookCode,     AccessoryCode, AccessoryCodeAutoGeneral) 
 select 
  src.CarRedbookCode + src.AccessoryCode
 , src.CarRedbookCode
 , src.AccessoryCode
 , src.AccessoryCodeAutoGeneral 
 from
  #csv src
 left join
  MapRedbookAccessory dst on dst.CarRedbookCodeAccessoryCode = src.CarRedbookCode + src.AccessoryCode
 where
  dst.CarRedbookCodeAccessoryCode is null

【问题讨论】:

    标签: sql-server sql-server-2005 tsql


    【解决方案1】:

    发生这种情况是因为 INSERT 语句没有单独处理行。可能有更好的方法来做到这一点,但您可以使用 ROW_NUMBER 函数仅插入每个代码/附件的第一行:

    INSERT INTO  MapRedbookAccessory (CarRedbookCodeAccessoryCode, CarRedbookCode,     AccessoryCode, AccessoryCodeAutoGeneral) 
     select 
      src.CarRedbookCode + src.AccessoryCode
     , src.CarRedbookCode
     , src.AccessoryCode
     , src.AccessoryCodeAutoGeneral 
     from
     (select *, ROW_NUMBER() OVER (PARTITION BY CarRedbookCode, AccessoryCode ORDER BY AccessoryCodeAutoGeneral) AS row
        from #csv) src
     left join
      MapRedbookAccessory dst on dst.CarRedbookCodeAccessoryCode = src.CarRedbookCode + src.AccessoryCode
     where
      dst.CarRedbookCodeAccessoryCode is null
      and src.row = 1
    

    如果有多行,您可以根据要插入的 AccessoryCodeAutoGeneral 更改 ORDER BY

    【讨论】:

      【解决方案2】:

      在您的示例 CSV 导入数据中,两个 DDD 行后面有不同的数值,这会使它们成为不同的行。所以 VECH01|DDD 应该被插入两次。这是正确的,还是样本数据不正确?

      【讨论】:

      • 样本数据正确,应该插入第1行VECH01|DDD|444,第2行VECH01|DDD|555被丢弃,只有红皮书代码(Vech01 ) 和附件代码 (DDD) 是密钥的一部分,显然我可以在 CSV 文件中获取重复的密钥,但我只想插入第一个出现并丢弃任何其他的。
      猜你喜欢
      • 2019-07-26
      • 2014-08-03
      • 2010-10-24
      • 2012-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-16
      相关资源
      最近更新 更多