Вставить в временную таблицу - создать слишком много строк - PullRequest
3 голосов
/ 13 октября 2010

Я массово импортирую 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

1-я строка импортирована. VECH01 DDD отсутствует в базе данных.
OK

2-я строка импортирована, но VECH01 DDD уже находится в базе данных, она была импортирована в предыдущей вставке.
НЕ ОК

3-я строка не импортирована, поскольку VECH02 CCC уже существуетв базе данных.
ОК

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

Ответы [ 2 ]

4 голосов
/ 13 октября 2010

Это происходит потому, что оператор 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

Вы можете изменить ORDER BY в зависимости от того, какой AccessoryCodeAutoGeneral выхотите вставить, если есть несколько строк.

0 голосов
/ 13 октября 2010

В данных примера импорта CSV две строки DDD имеют разные числовые значения после них, что делает их разными строками. Поэтому VECH01 | DDD должен быть вставлен дважды. Это правильно, или данные выборки неверны?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...