SQL Серверная массовая вставка не распознает двойные кавычки как полевые кавычки - PullRequest
0 голосов
/ 03 марта 2020

Я пытаюсь массово вставить файл в SQL Server 2017 14.0.1000.169 . Я хотел бы взять файл точно по мере его поступления, сохранить его в нужном месте и затем выполнить запрос массовой вставки без необходимости вообще изменять файл . У меня возникают трудности с тем, чтобы скрипт распознавал и игнорировал двойные кавычки в текстовом файле, если я не изменил окончание строк вручную с Unix на Windows. Я прочитал довольно много тем здесь и вне SO, обсуждая темы, близкие к этой, увы, ни одна из которых не дала мне ответ на мой вопрос:

Как мне массово вставить свой файл с Unix окончаниями строк и не заканчивающийся двойными кавычками?

My file выглядит так:

"Report Name","Daily Extract (ID: 111111)"
"Date/Time Generated(UTC)","01-Mar-2020 15:08:51"
"Workspace Name","Company (ID: 22222)"
"Account Name","Client Account"
"Date Range","01-Jan-2019 - 29-Feb-2020"

"Dimension 1","Dimension 2","Dimension 3","Dimension 4","Dimension 5","Dimension 6","Dimension 7","Dimension 8","Dimension 9","Dimension 10","Dimension 11","Dimension 12","Dimension 13","Dimension 14","Dimension 15","Dimension 16","Dimension 17","Metric 1","Metric 2","Metric 3","Metric 4","Metric 5","Metric 6","Metric 7","Metric 8","Metric 9","Metric 10","Metric 11","Metric 12"
"string","string","date as string","string","string","string","string","string","string","string","string","string","string","string","string","string","string","bigint","bigint","decimal","decimal","decimal","bigint","decimal","decimal","bigint","decimal","bigint","bigint"

The query Я использую следующее:

DROP TABLE IF EXISTS Table
GO

CREATE TABLE [dbo].[Table](
    [Dimension 1] [varchar] (255) NULL,
    [Dimension 2] [varchar] (255) NULL,
    [Dimension 3] [varchar] (255) NULL,
    [Dimension 4] [varchar]  (255) NULL,
    [Dimension 5] [varchar] (255),
    [Dimension 6] [varchar] (255) NULL,
    [Dimension 7] [varchar] (255) NULL,
    [Dimension 8] [varchar] (255) NULL,
    [Dimension 9] [varchar] (1000) NULL,
    [Dimension 10] [varchar] (255) NULL,
    [Dimension 11] [varchar] (255) NULL,
    [Dimension 12] [varchar] (255) NULL,
    [Dimension 13] [varchar] (1000) NULL,
    [Dimension 14] [varchar] (1000) NULL,
    [Dimension 15] [varchar] (1000) NULL,
    [Dimension 16] [varchar] (1000) NULL,
    [Dimension 17] [varchar] (1000) NULL,
    [Metric 1] [varchar] (50) NULL,
    [Metric 2] [varchar] (50) NULL,
    [Metric 3] [varchar] (50) NULL,
    [Metric 4] [varchar] (50) NULL,
    [Metric 5] [varchar] (50) NULL,
    [Metric 6] [varchar] (50) NULL,
    [Metric 7] [varchar] (50) NULL,
    [Metric 8] [varchar] (50) NULL,
    [Metric 9] [varchar] (50) NULL,
    [Metric 10] [varchar] (255) NULL,
    [Metric 11] [varchar] (50) NULL,
    [Metric 12] [varchar] (50) NULL
) ON [PRIMARY]
GO

BULK
INSERT Table
FROM 'C:\Users\username\Folder\File.csv'
WITH
(
--FORMAT = 'CSV',
DATAFILETYPE = 'char',
FIELDTERMINATOR = ',',
--ROWTERMINATOR = '\n',
ROWTERMINATOR = '0x0a',
FIRSTROW = 7,
--FIELDQUOTE = '"'
FIELDQUOTE = '0x22'
)
;

Как вы можете видеть выше, я импортирую все как varchar. Первоначально я использовал это только для одной метри c (из-за проблем с качеством данных в конце поставки), так как я полностью намереваюсь исправить каждую blemi sh после того, как файл уже был загружен. Однако, столкнувшись с трудностями, я установил все метрики на varchar, так что, по крайней мере, файл загрузился бы, и я мог видеть, как он выглядит, и копать дальше.

Пока я пытался следующее:

  • открыть файл в Sublime, удалить первые 7 строк, изменить строку, заканчивающуюся на Windows и сохранить - это работает со строками, которые я закомментировал, т.е. FORMAT вместо DATAFILETYPE, \ n вместо 0x0a и с параметром FIELDQUOTE, равным "
  • , оставьте файл без изменений и запустите приведенный выше сценарий с двойной кавычкой вместо 0x22 - это также работает, но в конечном итоге каждое значение равно двойному кавычки

  • оставьте файл без изменений и запустите приведенный выше скрипт как есть (т.е. используя 0x22 для FIELDQUOTE) - опять же, работает, но везде с двойными кавычками

Любая другая попытка, которую я до сих пор пробовал, приводила к различным ошибкам, которые приводили к одним и тем же двум вещам: либо я не могу использовать FORMAT = 'CSV' (если я оставляю конец строки Unix в), или в тот момент, когда я пытаюсь загрузить метрики в формате с плавающей запятой, происходит ошибка из-за двойных кавычек.

В настоящее время у меня есть обходной путь (я могу удалить двойные кавычки и преобразовать поля после того, как вещь загрузилась), я, однако, задаюсь вопросом, могу ли я интегрировать этот шаг в массовую вставку (как я делал, когда загружал файл с Windows окончаниями).

NB Я знаю, что FIELDQUOTE не имеет не было слишком долго, однако это должно относиться к моей сборке, согласно Microsoft:

"FIELDQUOTE = 'field_quote' Относится к: SQL Server 2017 (14.x) ОСАГО 1.1. Указывает символ, который будет использоваться в качестве символа кавычки в файле CSV. Если не указано, символ кавычки (") будет использоваться в качестве символа кавычки, как определено в стандарте РФ C 4180."

Я забыл раскрыть что-нибудь? Если нет, есть идеи, что я мог упустить из виду?

Заранее спасибо!

1 Ответ

0 голосов
/ 03 марта 2020

OK. Самая большая проблема здесь - ваш файл. Во-первых, файл не RF C 4180 из-за строк в верхней части. Это делает для головной боли.

Далее следует важный предостережение при FIRSTROW:

При пропуске строк серверная база данных SQL Engine смотрит только на поле терминаторы и не проверяет данные в полях пропущенных строк.

Обратите внимание, это говорит терминаторы полей не терминаторы строк. Это вторая проблема. Для ваших данных у вас есть это в начале:

"Report Name","Daily Extract (ID: 111111)"
"Date/Time Generated(UTC)","01-Mar-2020 15:08:51"
"Workspace Name","Company (ID: 22222)"
"Account Name","Client Account"
"Date Range","01-Jan-2019 - 29-Feb-2020"
<-- Blank Line -->

Это 6 разделителей полей и 6 разделителей строк.

Далее у вас есть больше столбцов в файл CSV, чем в таблице Table. Table не имеет столбца Dimension 17.

После добавления этого пропущенного столбца мне удалось добиться того, чтобы это работало для результатов, которые, как я полагаю, вам нужны, с помощью следующего:

BULK INSERT [Table]
FROM '/tmp/YourFile2.txt'
WITH (FIELDTERMINATOR = ',',
      ROWTERMINATOR = '\n',
      FIRSTROW = 2,
      FORMAT = 'CSV',
      FIELDQUOTE = '"');

Это вставило 1 строку в таблицу.

...