Prenez une chaîne multi-délimitée dans MySQL et convertir à plusieurs enregistrements
-
11-10-2019 - |
Question
Je suis un vieux jeu de données en train de convertir dans une nouvelle base de données structurée. À l'heure actuelle, ils ont des données dans ce format:
[quantity int]~[var1 string]|[var2 string optional]|[var3 string optional];(etc);
[quantity]~[var1]|[var2]|[var3]
où plusieurs motifs sont délimités par des points virgules premier, puis par tildes, et enfin par des caractères de tuyau à l'intérieur du même champ (pas de supports) dans la base de données existante. Par exemple:
3~S|Red|Top;1~S|Blue|Top; ... etc ... ;20~XL|Green|Left
Je veux prendre cette chaîne dans chaque enregistrement et procédez comme suit:
- Créer un nouvel enregistrement dans une table existante en fonction de chaque split-virgule
- Séparer chaque jeton à nouveau par le tilde, en mettant la première pièce dans une zone et la seconde dans un champ séparé (Je ne se soucie pas de fractionnement par la conduite) dans le même enregistrement
Je ne sais pas s'il est encore possible, mais j'espère que ce soit. J'espère aussi avoir que faire une fois, le nouveau système se chargera de créer toute cette merde automatiquement. Mon sproc-fu est assez terrible dans MySQL, de sorte que toute aide est très appréciée.
Merci beaucoup!
La solution
Cela semble être une chose assez grossière à faire dans SQL, mais voici un script de preuve de concept.
Si l'apparence de sortie droit de vous, remplacer la commande SELECT avec une instruction INSERT appropriée et il devrait vous obtenir ce que vous voulez.
delimiter ;;
drop procedure if exists load_crazy_stuff;;
create procedure load_crazy_stuff(in s longtext)
begin
declare pos int;
declare record longtext;
declare leftpart int;
declare rightpart longtext;
set s = concat(s,';');
while length(s)>0 DO
set pos = instr(s,';');
set record = left(s,pos-1);
set s = substr(s,pos+1);
set pos = instr(record,'~');
set leftpart = left(record,pos-1);
set rightpart = substr(record,pos+1);
select leftpart, rightpart;
end while;
end;;
call load_crazy_stuff('3~S|Red|Top;1~S|Blue|Top;20~XL|Green|Left');;
Autres conseils
La façon non brute de le faire est la suivante:
load data infile '/tmp/your-data-file' into table yourtable fields terminated by '~' lines terminated by ';';