2016-05-09 3 views
5

У меня есть строка asdasdwdfef,rgrgtggt,weef и я хочу, чтобы результат, как в виде таблицы, как показано нижеразделение MySQL строки запятой оператора

id  decription 
1  asdasdwdfef 
2  rgrgtggt 
3  weef 

Для этого я создал процедуру здесь моя процедура

DELIMITER ;; 
CREATE Procedure Split(_RowData text, _Delimeter text) 
BEGIN 
    DECLARE _Iterator INT default 1; 
    DECLARE _FoundIndex INT; 
    DECLARE _Data varchar(255); 
    SET _FoundIndex = LOCATE(_Delimeter,_RowData); 
    DROP TABLE IF EXISTS _RtnValue; 
    CREATE temporary TABLE _RtnValue(ID INT AUTO_INCREMENT NOT NULL, description text, primary key(ID)); 
    WHILE _FoundIndex > 1 DO 
     INSERT INTO _RtnValue (description) 
     SELECT 
     _Data = LTRIM(RTRIM(SUBSTRING(_RowData, 1, _FoundIndex - 1))); 
     set _RowData = SUBSTRING(_RowData, _FoundIndex + LENGTH(_Delimeter)/2, LENGTH(_RowData)); 
     SET _Iterator = _Iterator + 1; 
     SET _FoundIndex = LOCATE(_Delimeter, _RowData); 
    END WHILE; 
    INSERT INTO _RtnValue(description) SELECT _Data = LTRIM(RTRIM(_RowData)); 
    select * from _RtnValue; 
END 

Но когда я выполню его, используя следующую команду:

call Split('asdasdwdfef,rgrgtggt,weef', ','); 

дает мне следующий результат:

id  decription 
1  NULL 
2  NULL 
3  NULL 

Пожалуйста, дайте мне знать, как исправить эту проблему. Я использую MySQL.

+0

Не можете заставить его работать на sqlfiddle, но разве вы не просто потеряете _data в своем заявлении insert? IE INSERT INTO _RtnValue (описание) SELECT LTRIM (RTRIM (SUBSTRING (_RowData, 1, _FoundIndex - 1))); – user1515791

+1

@ user1515791 Я объявляю свою _data "DECLARE _Data varchar (255);" и ошибка отсутствует, но выход равен NULL. – user3441151

+1

@ user1515791 Я просто обновляю свой пост, пожалуйста, проверьте его снова. – user3441151

ответ

2

Я получил ответ

Сначала создайте новую функцию

CREATE FUNCTION SPLIT_STR(x VARCHAR(255), delim VARCHAR(12), pos INT) 
RETURNS VARCHAR(255) 
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos), 
LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1), delim, ''); 

Затем создать хранимую процедуру

DELIMITER ;; 
CREATE PROCEDURE Split(in fullstr varchar(255)) 
BEGIN 
    DECLARE a INT Default 0 ; 
    DECLARE str VARCHAR(255); 

    DROP TABLE IF EXISTS my_temp_table; 
    CREATE temporary TABLE my_temp_table(ID INT AUTO_INCREMENT NOT NULL, description text, primary key(ID)); 

    simple_loop: LOOP 
     SET a=a+1; 
     SET str=SPLIT_STR(fullstr,",",a); 
     IF str='' THEN 
      LEAVE simple_loop; 
     END IF; 
     #Do Inserts into temp table here with str going into the row 
     insert into my_temp_table (description) values (str); 
    END LOOP simple_loop; 
    select * from my_temp_table; 
END 

После этого, когда я назову его call Split('asas,d,sddf,dfd');, он дает мне вывод, который я хочу.

Thanx за каждое предложение.

1

Требования: разделить столбец с разделителями на строки (таблицу).

Почему? Вы можете использовать все функции SQL Aggregate для обработки строк.

Working SQLFiddle

Связанные вопросы, которые используют этот код:

Я решил использовать:

  • таблица целых чисел (integersequence), которая при соединении «внутренняя соединенная» или «крест» (одна и та же вещь) с другой таблицей будет генерировать строки, которые, несомненно, будут иметь уникальный порядковый номер, начиная с 1. Это просто используется какие RDBMS-двигатели должны делать.

  • Почему таблица целых чисел ?: Она небольшая и загружается в кеш. Это легко понять.

  • Вместо того, чтобы иметь много кода в запросе, который скрывает то, что он на самом деле делает. Я использую функции, выполняющие одно задание. Он упрощает основной запрос и может быть проверен и проверен отдельно. На данный момент меня беспокоит простота обслуживания и понимания.

Пример здесь для одной строки. Однако его можно легко расширить до таблицы разделенных строк разных размеров. «Cross join» создаст все возможные варианты индекса, начиная с 1 при присоединении к integersequence (мне действительно нужно использовать другое имя: - /).

Таким образом, запрос:

SET @StrToParse = "asdasdwdfef,rgrgtggt,weef"; 

/* example */ 
select integerseries.id, 
     count_in_set(@StrToParse, ','), 
     value_in_set(@StrToParse, ',', integerseries.id) 
from integerseries 
where integerseries.id <= count_in_set(@StrToParse, ','); 

Выход:

PositionOfString, CountOfCommaDelimitedStrings, StringAtThatPosition 

1     3        asdasdwdfef 
2     3        rgrgtggt 
3     3        weef 

Теперь, как мы получаем эти значения:

Я решил использовать две функции:

Имена относятся к функции mysql'FIND_IN_SET'.

1) Функция COUNT_IN_SET: возвращает счет character delimited items в колонке.

CREATE FUNCTION `COUNT_IN_SET`(haystack VARCHAR(1024), 
           delim CHAR(1) 
           ) RETURNS INTEGER 
BEGIN 
     RETURN CHAR_LENGTH(haystack) - CHAR_LENGTH(REPLACE(haystack, delim, '')) + 1; 
END$$ 

2) VALUE_IN_SET функции: рассматривает delimited list как one based array и возвращает значение в данном индексе «».

CREATE FUNCTION `VALUE_IN_SET`(haystack VARCHAR(1024), 
           delim CHAR(1), 
           which INTEGER 
           ) RETURNS VARCHAR(255) CHARSET utf8 COLLATE utf8_unicode_ci 
BEGIN 
     RETURN SUBSTRING_INDEX(SUBSTRING_INDEX(haystack, delim, which), 
        delim, 
        -1); 
END$$ 

intereseries стол - см (таблицы Tally)

CREATE TABLE `integerseries` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=500 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

/*Data for the table `integerseries` */ 

insert into `integerseries`(`id`) values (1); 
insert into `integerseries`(`id`) values (2); 
insert into `integerseries`(`id`) values (3); 
insert into `integerseries`(`id`) values (4); 
insert into `integerseries`(`id`) values (5); 
insert into `integerseries`(`id`) values (6); 
insert into `integerseries`(`id`) values (7); 
insert into `integerseries`(`id`) values (8); 
insert into `integerseries`(`id`) values (9); 
insert into `integerseries`(`id`) values (10); 
+2

thanx для вашего сообщения, но я получил ответ. – user3441151

+0

@ user3441151, я рад, что вы получили ответ, которым вы довольны. –

+0

Спасибо за бонус. Это ценно. –