SQL Server BULK INSERT данные фиксированной длины - PullRequest
0 голосов
/ 02 апреля 2012

Я использую SQL Server 2008 и у меня есть таблица с 5 столбцами с типом символов.

CREATE TABLE [dbo].[deviceDataBulk](
[f1] [char](9) NULL,
[f2] [char](5) NULL,
[f3] [char](7) NULL,
[f4] [char](7) NULL,
[f5] [char](6) NULL)

У меня также есть файл формата bcp;

<RECORD>
 <FIELD ID="1" xsi:type="CharFixed" LENGTH="9" COLLATION="Turkish_CI_AS"/>
 <FIELD ID="2" xsi:type="CharFixed" LENGTH="5" COLLATION="Turkish_CI_AS"/>
 <FIELD ID="3" xsi:type="CharFixed" LENGTH="7" COLLATION="Turkish_CI_AS"/>
 <FIELD ID="4" xsi:type="CharFixed" LENGTH="7" COLLATION="Turkish_CI_AS"/>
 <FIELD ID="5" xsi:type="CharFixed" LENGTH="6" COLLATION="Turkish_CI_AS"/>
</RECORD>
<ROW>
 <COLUMN SOURCE="1" NAME="f1" NULLABLE="YES" xsi:type="SQLCHAR"/>
 <COLUMN SOURCE="2" NAME="f2" NULLABLE="YES" xsi:type="SQLCHAR"/>
 <COLUMN SOURCE="3" NAME="f3" NULLABLE="YES" xsi:type="SQLCHAR"/>
 <COLUMN SOURCE="4" NAME="f4" NULLABLE="YES" xsi:type="SQLCHAR"/>
 <COLUMN SOURCE="5" NAME="f5" NULLABLE="YES" xsi:type="SQLCHAR"/>
</ROW>

Файл данных содержит фиксированную длинуданные char без разделителей полей в каждой строке.Таким образом, полная строка будет состоять из 34 символов.

Моя проблема в поле 4, и поле 5 может отсутствовать для каждой строки.В этом файле может быть 21 строка длинной или 28 символов.

Нет случая, чтобы поле 5 существовало, а поле 4 - нет.

Возможные сценарии для текстового файла:

f1 f2 f3 f4 f5
f1 f2 f3 f4
f1 f2 f3

Не удалось вставить этот файл с BULK INSERT.Я хочу, чтобы BULK INSERT вставлял нули, когда у него нет этих полей, если инструмент достигает конца строки, просто вставьте нули для остальных полей.

1 Ответ

0 голосов
/ 02 апреля 2012

Как насчет двухэтапного подхода? Сначала загрузите данные в промежуточную таблицу как «большие строки», затем используйте второй запрос, чтобы разбить необработанные строки на соответствующие поля и обработать «отсутствующие столбцы f5 и / или f4» соответственно?

будет выглядеть (более или менее) так: (не проверено!)

CREATE TABLE [dbo].[deviceDataBulk_staging](
 [rowid] int IDENTITY(1 , 1) PRIMARY KEY,
 [raw] [varchar](34) NOT NULL)

GO
BULK INSERT [deviceDataBulk_staging]
FROM '<your file>' 
-- not sure if you really need a format-file here, 
-- simply make sure to pass the correct line-separator if it is 'exotic'.

GO

INSERT [deviceDataBulk] (f1, f2, f3, f4, f5)
SELECT f1 = SubString([raw], 1 , 9),
       f1 = SubString([raw], 10 , 5),
       f1 = SubString([raw], 15 , 7),
       f1 = (CASE WHEN Length([raw] < 22 THEN NULL ELSE SubString([raw], 22 , 7) END),
       f1 = (CASE WHEN Length([raw] < 29 THEN NULL ELSE SubString([raw], 29 , 6) END)
  FROM [deviceDataBulk_staging]
 ORDER BY [rowid]

В этом случае промежуточный файл будет выглядеть так:

[rowid] предназначен для того, чтобы сохранить порядок, идентичный порядку, изначально указанному в файле, он может вам и не понадобиться, но ИМХО издержки минимальны, и MSSQL в любом случае не слишком заинтересован в таблицах HEAP, поэтому его наличие " Хорошая вещь [Тм] "

...