Чтение файлов CSV с использованием SQL Server 2016 (параметр формата недоступен).
Это файлы crlf/windows, и каждое значение будет заключено в двойные кавычки. Файлы находятся здесь, обратите внимание, что я изменил их на crlf для единообразия.
Время от времени я часто вижу это с числами: когда мы пытаемся выполнить замену (значение, ''', ''), а затем привести к int, это завершится неудачей с ошибкой ниже
Ошибка преобразования при преобразовании значения nvarchar «331877». ' к типу данных int.
Но если мы выполним функцию substring(), она выдаст значение, которое нельзя привести к int.
ИМХО, супер хакерство, потому что вам нужно угадать длину строки с помощью len().
Я проверил, что результаты замены и подстроки выглядят совершенно одинаково, но когда я запускаю
nullif (replace(value, '"', ''), substring(value, 2, len(value)-2))
он утверждает, что они чем-то отличаются. (косит глаза) Они выглядят одинаково... они одного типа... они одинаковые, но Нуллиф понимает, что что-то не так. Мой код ниже. Может быть что-то с коалицией??
bulk insert #tmp
From 'C:\acquisition_samples.csv'
WITH
(
CODEPAGE = '65001'
,FIRSTROW = 2
,FIELDTERMINATOR = ','
,ROWTERMINATOR = '0x0A'
,batchsize=10
,TABLOCK
);
-- DDL
insert into acquisition_sample(fdc_id_of_sample_food, fdc_id_of_acquisition_food) -- UPDATE file name, and columns
select
nullif (REPLACE(t.fdc_id_of_sample_food, '"', ''), substring(t.fdc_id_of_sample_food,2,LEN(t.fdc_id_of_sample_food)-2))
, nullif (REPLACE(t.fdc_id_of_acquisition_food, '"', ''), substring(t.fdc_id_of_acquisition_food,2,LEN(t.fdc_id_of_acquisition_food)-2)) as wtf
, CAST(substring(t.fdc_id_of_sample_food,2,LEN(t.fdc_id_of_sample_food)-2) AS INT)
, t.fdc_id_of_acquisition_food
, CAST(substring(t.fdc_id_of_acquisition_food,2,LEN(t.fdc_id_of_acquisition_food)-3) AS INT)
from #tmp t
По сути, он будет прерываться для любых конечных непечатаемых символов, кроме пробела - даже табуляция, перевод строки и возврат каретки вызовут эту ошибку. Вы также можете проверить процесс преобразования файлов в CR-LF, чтобы узнать, обрабатывает ли он файлы со смешанными разрывами строк.
@AlwaysLearning и @T Н, я думаю, это может быть какой-то странный символ файла, например, возврат каретки. Теперь, когда я смотрю на значение, которое я скопировал в свой вопрос, оно кажется довольно глупым. Дело в том, что в консоли это не печаталось. он печатал пробел на новой строке, что мне показалось странным, но я подумал, что это может быть просто MSSQL, который переводит его на новую строку в целях форматирования.
Звучит как символ возврата каретки или новой строки (перевода строки). Обновленная рабочий пример. SELECT UNICODE(RIGHT(value, 1))
должен идентифицировать персонажа.
Почему бы просто не использовать LTRIM(RTRIM(YourValue))
Я попробовал LTrim(RTrim()), но это не решило проблему, потому что мы не знали, что обрезать, и возврат каретки не удалялся без указания.
Благодаря подсказкам @AlwaysLearning и @T N
Теперь становится очевидным, что причина, по которой мы получаем другое значение, заключается в том, что подстрока удаляла лишний символ, а замена касалась только двойных кавычек, которые я ей передал.
UNICODE(RIGHT(value, 1))
REPLACE(Fieldname, CHAR(13), '')
Теперь становится очевидным, что причина, по которой мы получаем другое значение, заключается в том, что подстрока удаляла лишний символ, а замена касалась только двойных кавычек, которые я ей передал.
Я понял, что причина, по которой текст в конце строки смещается на одну строку вниз в консоли ошибок, заключается в том, что это возврат каретки.
Этот аналогичный ответ также помог. Символ возврата каретки CSV
В опубликованном сообщении об ошибке в конце строки, преобразуемой в
INT
–'331877 '
, отображается пробел или подобный ему символ. Обычный пробел не приведет к ошибке преобразования, но другие символы пробела, такие как неразрывный пробел, будут. См. эту db<>скрипку. Вам нужно выяснить, что это за персонаж, и устранить его до того, как появитсяCAST()
.