从临时表插入 - 创建太多行

Posted

技术标签:

【中文标题】从临时表插入 - 创建太多行【英文标题】: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

【问题讨论】:

【参考方案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 文件中获取重复的密钥,但我只想插入第一个出现并丢弃任何其他的。

以上是关于从临时表插入 - 创建太多行的主要内容,如果未能解决你的问题,请参考以下文章

SQL 从临时表插入表,并将输出插入临时表

SQL Server 存储过程创建临时表并插入值

将数据插入临时表

插入临时表,并创建一个 IDENTITY 字段,而不先声明临时表?

SQL临时表使用

mysql创建临时表,将查询结果插入已有表中