Подтвердить что ты не робот

Массовая вставка, SQL Server 2000, unix linebreaks

Я пытаюсь вставить CSV файл в базу данных с развязками unix. Команда, которую я запускаю:

BULK INSERT table_name
FROM 'C:\file.csv' 
WITH 
( 
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = '\n' 
) 

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

4b9b3361

Ответ 1

Я был вынужден внести свой вклад, поскольку у меня была одна и та же проблема, и мне нужно читать по 2 файла UNIX из SAP по крайней мере пару раз в день. Поэтому вместо использования unix2dos мне нужно что-то с меньшим ручным вмешательством и более автоматическим с помощью программирования.

Как отмечено, Char (10) работает внутри строки sql. Я не хотел использовать строку sql, поэтому я использовал '' '' '+ Char (10) +' '' ', но по какой-то причине это не скомпилировалось.

Что работало очень сильно: с (ROWTERMINATOR = '0x0a')

Проблема решена с помощью Hex!

Надеюсь, это поможет кому-то.

Ответ 2

Спасибо всем, кто ответил, но я нашел свое предпочтительное решение.

Когда вы указываете SQL Server ROWTERMINATOR = '\n', он интерпретирует это как значение терминатора строк по умолчанию в Windows, которое на самом деле является "\ r\n" (с использованием нотации C/С++). Если ваш ограничитель строк действительно просто "\n", вам нужно будет использовать динамический SQL, показанный ниже.

DECLARE @bulk_cmd varchar(1000)
SET @bulk_cmd = 'BULK INSERT table_name
FROM ''C:\file.csv''
WITH (FIELDTERMINATOR = '','', ROWTERMINATOR = '''+CHAR(10)+''')'
EXEC (@bulk_cmd)

Почему вы не можете сказать BULK INSERT... (ROWTERMINATOR = CHAR (10)) находится вне меня. Не похоже, что вы можете оценить любые выражения в разделе WITH команды.

Что это выше, это создать строку команды и выполнить ее. Аккуратно обойти необходимость создания дополнительного файла или выполнения дополнительных шагов.

Ответ 3

Я подтверждаю, что синтаксис

ROWTERMINATOR = '''+CHAR(10)+'''

работает при использовании команды EXEC.

Если у вас несколько символов ROWTERMINATOR (например, pipe и unix linefeed), синтаксис для этого:

ROWTERMINATOR = '''+CHAR(124)+''+CHAR(10)+'''

Ответ 4

Это немного сложнее! Когда вы указываете SQL Server ROWTERMINATOR = '\n', он интерпретирует это как значение терминатора строк по умолчанию в Windows, которое на самом деле является "\ r\n" (с использованием нотации C/С++). Если ваш ограничитель строк действительно просто "\n", вам придется использовать динамический SQL, показанный выше. Я потратил большую часть часа на выяснение, почему \n на самом деле не означает \n при использовании с BULK INSERT!

Ответ 5

Один вариант - использовать bcp и настроить файл управления с '\n' как символ разрыва строки.

Несмотря на то, что вы указали, что предпочли бы не делать этого, другим вариантом было бы использовать unix2dos для предварительной обработки файла в один с разрывами строк '\r\n'.

Наконец, вы можете использовать опцию FORMATFILE на BULK INSERT. Это будет использовать файл управления bcp для указания формата импорта.

Ответ 6

Посмотрите, есть ли два общих способа, которые можно предпринять: некоторый альтернативный способ прочитать CSV в SQL script или предварительно преобразовать CSV с любым из многочисленных способов, которыми вы можете это сделать (bcp, unix2dos, if это одноразовый король, вы, возможно, даже можете использовать свой редактор кода, чтобы исправить файл для вас).

Но вам нужно будет сделать дополнительный шаг!

Если этот SQL запускается из программы, вам может потребоваться преобразовать окончания строки в этой программе. В этом случае, и вы сами решили закодировать преобразование, вот что вам нужно: 1. Окончание строки может быть \n 2. или \r\n 3. или даже \r (Mac!) 4. Хорошее горе, может быть, что некоторые строки имеют \r\n и другие \n, любая комбинация возможна, если вы не контролируете, где CSV пришел из

ОК, ОК. Возможность 4 надуманна. Это происходит по электронной почте, но это еще одна история.

Ответ 7

Я бы подумал, что "ROWTERMINATOR = '\n" будет работать. Я бы предложил открыть файл в инструменте, который показывает "скрытые символы", чтобы убедиться, что линия завершается так, как вы думаете. Я использую notepad ++ для таких вещей.

Ответ 8

Это сводится к этому. Unix использует LF (ctrl-J), MS-DOS/Windows использует CR/LF (ctrl-M/Ctrl-J).

Когда вы используете '\n' в Unix, он преобразуется в символ LF. В MS-DOS/Windows он переводится в CR/LF. Когда ваш импорт выполняется в форматированном файле Unix, он видит только LF. Следовательно, его часто проще запускать файл через unix2dos. Но, как вы сказали в оригинальном вопросе, вы не хотите этого делать (я полагаю, что есть веская причина, почему вы не можете).

Почему вы не можете сделать:

(ROWTERMINATOR = CHAR(10))

Наверное, потому что, когда код SQL разбирается, он не заменяет символ char (10) символом LF (потому что он уже заключен в одиночные кавычки). Или, возможно, его интерпретируют как:

(ROWTERMINATOR =
     )

Что происходит, когда вы повторяете содержимое @bulk_cmd?