MySQL загружает значения NULL из данных CSV - PullRequest
156 голосов
/ 20 апреля 2010

У меня есть файл, который может содержать от 3 до 4 столбцов числовых значений, разделенных запятой. Пустые поля определяются за исключением того, что они находятся в конце строки:

1,2,3,4,5
1,2,3,,5
1,2,3

В MySQL была создана следующая таблица:

+-------+--------+------+-----+---------+-------+
| Field | Type   | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| one   | int(1) | YES  |     | NULL    |       | 
| two   | int(1) | YES  |     | NULL    |       | 
| three | int(1) | YES  |     | NULL    |       | 
| four  | int(1) | YES  |     | NULL    |       | 
| five  | int(1) | YES  |     | NULL    |       | 
+-------+--------+------+-----+---------+-------+

Я пытаюсь загрузить данные с помощью команды MySQL LOAD:

LOAD DATA INFILE '/tmp/testdata.txt' INTO TABLE moo FIELDS 
TERMINATED BY "," LINES TERMINATED BY "\n";

Полученная таблица:

+------+------+-------+------+------+
| one  | two  | three | four | five |
+------+------+-------+------+------+
|    1 |    2 |     3 |    4 |    5 | 
|    1 |    2 |     3 |    0 |    5 | 
|    1 |    2 |     3 | NULL | NULL | 
+------+------+-------+------+------+

Проблема заключается в том, что когда поле в необработанных данных пустое и не определено, MySQL по какой-то причине не использует значение по умолчанию для столбцов (которое равно NULL) и использует ноль. NULL используется правильно, когда поле полностью отсутствует.

К сожалению, я должен уметь различать NULL и 0 на этом этапе, поэтому любая помощь будет оценена.

Спасибо S.

редактировать

Вывод ШОУ ПРЕДУПРЕЖДЕНИЙ:

+---------+------+--------------------------------------------------------+
| Level   | Code | Message                                                |
+---------+------+--------------------------------------------------------+
| Warning | 1366 | Incorrect integer value: '' for column 'four' at row 2 | 
| Warning | 1261 | Row 3 doesn't contain data for all columns             | 
| Warning | 1261 | Row 3 doesn't contain data for all columns             | 
+---------+------+--------------------------------------------------------+

Ответы [ 5 ]

171 голосов
/ 11 мая 2011

Это будет делать то, что вы хотите. Он считывает четвертое поле в локальную переменную и затем устанавливает фактическое значение поля в NULL, если локальная переменная заканчивается пустой строкой:

LOAD DATA infile '/tmp/testdata.txt'
INTO TABLE moo
fields terminated BY ","
lines terminated BY "\n"
(one, two, three, @vfour, five)
SET four = nullif(@vfour,'')
;

Если все они, возможно, пустые, вы бы прочитали их все в переменные и имели бы несколько операторов SET, например:

LOAD DATA infile '/tmp/testdata.txt'
INTO TABLE moo
fields terminated BY ","
lines terminated BY "\n"
(@vone, @vtwo, @vthree, @vfour, @vfive)
SET
one = nullif(@vone,''),
two = nullif(@vtwo,''),
three = nullif(@vthree,''),
four = nullif(@vfour,'')
;
118 голосов
/ 20 апреля 2010

Руководство по MySQL говорит:

При чтении данных с помощью LOAD DATA INFILE, пустые или отсутствующие столбцы обновляется с помощью ''. Если вы хотите NULL значение в столбце, вы должны использовать \ N в файле данных. Буквальное слово «NULL» может также использоваться под некоторыми обстоятельства.

Так что вам нужно заменить заготовки на \ N следующим образом:

1,2,3,4,5
1,2,3,\N,5
1,2,3
5 голосов
/ 22 января 2015

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

mysql> show variables like 'sql_mode';
2 голосов
/ 20 апреля 2010

Предварительно обработайте введенный CSV, чтобы заменить пустые записи на \ N.

Попытка в регулярном выражении: s / ,, /, \ n, / g и s /, $ /, \ N / g

Удачи.

0 голосов
/ 23 марта 2019

Показывать переменные типа "secure_file_priv";

Примечание. Храните CSV-файл в месте, указанном вышеупомянутой командой.

create table assessments (course_code varchar(5),batch_code varchar(7),id_assessment int, assessment_type varchar(10), date int , weight int);

Примечание: здесь столбец 'date' содержит несколько пустых значений в файле csv.

LOAD DATA INFILE 'C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/assessments.csv' 
INTO TABLE assessments
FIELDS TERMINATED BY ',' 
OPTIONALLY ENCLOSED BY '' 
LINES TERMINATED BY '\n' 
IGNORE 1 ROWS 
(course_code,batch_code,id_assessment,assessment_type,@date,weight)
SET date = IF(@date = '', NULL, @date);
...