Возьмите строку с несколькими разделителями в MySQL и конвертируйте в несколько записей - PullRequest
0 голосов
/ 18 декабря 2010

Я конвертирую старый набор данных в недавно структурированную базу данных. В настоящее время они имеют данные в этом формате:

[quantity int]~[var1 string]|[var2 string optional]|[var3 string optional];(etc);
[quantity]~[var1]|[var2]|[var3]

, где различные шаблоны сначала разделяются точками с запятой, затем тильдами и, наконец, символами канала в том же поле (без скобок) в существующей базе данных. Например:

3~S|Red|Top;1~S|Blue|Top; ... etc ... ;20~XL|Green|Left

Я хочу взять эту строку в каждой записи и сделать следующее:

  1. Создать новую запись в существующей таблице, основанную на каждой точке с запятой
  2. Снова разделите каждый токен тильдой, поместив первый фрагмент в одно поле, а второй - в отдельное поле (меня не интересует разделение по трубам) в одной записи

Я не знаю, возможно ли это вообще, но я надеюсь, что это так. Я также надеюсь, что придется сделать это только один раз, поскольку новая система позаботится о создании всего этого дерьма автоматически. Мой sproc-fu довольно ужасен в MySQL, поэтому любая помощь очень ценится.

Большое спасибо!

Ответы [ 2 ]

1 голос
/ 18 декабря 2010

Не грубый способ сделать это это:

load data infile '/tmp/your-data-file' into table yourtable fields terminated by '~' lines terminated by ';';
1 голос
/ 18 декабря 2010

Это кажется довольно грубым делом в SQL, но вот сценарий проверки концепции.

Если вывод выглядит правильно, замените SELECT соответствующим оператором INSERT, и он долженполучить то, что вы хотите.

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