web-dev-qa-db-fra.com

MySQL charge des valeurs NULL à partir de données CSV

J'ai un fichier qui peut contenir de 3 à 4 colonnes de valeurs numériques séparées par une virgule. Les champs vides sont définis avec l'exception lorsqu'ils se trouvent à la fin de la ligne:

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

Le tableau suivant a été créé dans MySQL:

 + ------- + -------- + ------ + ----- + --------- + ---- --- + 
 | Domaine | Type | Null | Clé | Par défaut | Extra | 
 + ------- + -------- + ------ + ----- + --------- + - ----- + 
 | un | int (1) | OUI | NULL | | 
 | deux | int (1) | OUI | NULL | | 
 | trois | int (1) | OUI | NULL | | 
 | quatre | int (1) | OUI | NULL | | 
 | cinq | int (1) | OUI | NULL | | 
 + ------- + -------- + ------ + ----- + --------- + ---- --- + 

J'essaie de charger les données en utilisant la commande MySQL LOAD:

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

La table résultante:

 + ------ + ------ + ------- + ------ + ------ + 
 | un | deux | trois | quatre | cinq | 
 + ------ + ------ + ------- + ------ + ------ + 
 | 1 | 2 | 3 | 4 | 5 | 
 | 1 | 2 | 3 | 0 | 5 | 
 | 1 | 2 | 3 | NULL | NULL | 
 + ------ + ------ + ------- + ------ + ------ + 

Le problème réside dans le fait que lorsqu'un champ est vide dans les données brutes et qu'il n'est pas défini, pour une raison quelconque, MySQL n'utilise pas la valeur par défaut de la colonne (qui est NULL) et utilise zéro. NULL est utilisé correctement lorsque le champ manque complètement.

Malheureusement, je dois être capable de faire la distinction entre NULL et 0 à ce stade, donc toute aide serait la bienvenue.

Merci S.

modifier

La sortie de SHOW WARNINGS:

 + --------- + ------ + --------------------------- ----------------------------- + 
 | Niveau | Code | Message | 
 + --------- + ------ + ------------------------- ------------------------------- + 
 | Avertissement | 1366 | Valeur entière incorrecte: '' pour la colonne 'quatre' à la ligne 2 | 
 | Avertissement | 1261 | La ligne 3 ne contient pas de données pour toutes les colonnes | 
 | Avertissement | 1261 | La ligne 3 ne contient pas de données pour toutes les colonnes | 
 + --------- + ------ + --------------------------- ----------------------------- + 
157
Spiros

Cela fera ce que vous voulez. Il lit le quatrième champ dans une variable locale, puis définit la valeur réelle du champ sur NULL, si la variable locale contient finalement une chaîne vide:

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,'')
;

Si elles sont toutes éventuellement vides, vous les liriez toutes dans des variables et disposerez de plusieurs instructions SET, comme ceci:

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,'')
;
175
Duncan Lock

manuel MySQL dit:

Lors de la lecture de données avec LOAD DATA INFILE, les colonnes vides ou manquantes sont mises à jour avec ''. Si vous voulez une valeur NULL dans une colonne, vous devez utiliser\N dans le fichier de données. Le mot littéral "NULL" peut également être utilisé dans certaines circonstances.

Il faut donc remplacer les blancs par\N comme ceci:

1,2,3,4,5
1,2,3,\N,5
1,2,3
122
Janci

Le comportement est différent selon la configuration de la base de données. En mode strict, cela jetterait une erreur sinon un avertissement. La requête suivante peut être utilisée pour identifier la configuration de la base de données.

mysql> show variables like 'sql_mode';
6
Dobi

Prétraitez votre fichier CSV d'entrée pour remplacer les entrées vides par\N.

Tentative d’expression rationnelle: s/, /,\n,/g et s /, $ /,\N/g

Bonne chance.

2
Sam Goldman