2016-05-09 9 views
5

Ich habe String asdasdwdfef,rgrgtggt,weef und i ausgegeben werden soll wie im Tabellenformat unterMySQL String Trennung durch Komma-Operator

id  decription 
1  asdasdwdfef 
2  rgrgtggt 
3  weef 

Dazu, wie ich eine Prozedur hier erstellt gezeigt ist mein Verfahren

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 

Aber wenn ich es mit dem folgenden Befehl ausfühle

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

gibt es mir die folgende Ausgabe:

id  decription 
1  NULL 
2  NULL 
3  NULL 

Bitte lassen Sie mich wissen, wie Sie dieses Problem beheben. Ich verwende MySQL.

+0

Kann es nicht auf sqlfiddle arbeiten, aber sollten Sie nicht einfach die _data in Ihrer insert-Anweisung verlieren? IE INSERT INTORtnValue (Beschreibung) SELECT LTRIM (RTRIM (SUBSTRING (_RowData, 1, _FoundIndex - 1))); – user1515791

+1

@ user1515791 Ich deklariere meine _data "DECLARE _Data varchar (255);" und Fehler ist out, aber die Ausgabe ist NULL. – user3441151

+1

@ user1515791 Ich aktualisiere nur meine Post bitte überprüfen Sie es noch einmal. – user3441151

Antwort

2

bekam ich die Antwort

Erstellen Sie zunächst neue Funktion

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

Dann gespeicherte Prozedur erstellen

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 

Danach, wenn ich es durch call Split('asas,d,sddf,dfd'); nennen es gibt mir die Ausgabe, was ich will.

Danke für jeden Vorschlag.

1

Anforderungen: Split eine 'begrenzt' -Spalte in Zeilen (a-Tabelle).

Warum? Sie können alle SQL-Aggregatfunktionen zum Verarbeiten der Zeilen verwenden.

Working SQLFiddle

Verwandte Fragen, die diesen Code verwenden:

wählte ich zu verwenden:

  • Tabelle ganzer Zahlen (integersequence), die, wenn ‚innere verbunden‘ oder ‚Kreuz verbunden‘ (gleiche) zu einem anderen Tabellenzeilen erzeugen wird, die aus 1. Starten einer eindeutigen Sequenznummer haben, sind nur bestimmte Dies wird unter Verwendung von was RDBMS-Engines tun müssen.

  • warum eine Tabelle ganzer Zahlen ?: Es ist klein und wird in den Cache geladen bekommen. Es ist leicht zu verstehen.

  • Anstatt viel Code in der Abfrage, die verdunkelt, was es tatsächlich tut. Ich benutze Funktionen, die einen Job machen. Es vereinfacht die Hauptabfrage und kann separat getestet und überprüft werden. Ich bin nur um eine einfache Wartung und Verständnis an dieser Stelle.

Das Beispiel hier ist für eine Zeichenfolge. Allerdings kann es leicht zu einer Tabelle von begrenzten Zeichenfolge in verschiedenen Größen erweitert werden. Der 'cross join' erstellt alle möglichen Optionen des Indexes beginnend mit 1 beim Beitritt zu integersequence (ich brauche wirklich einen anderen Namen: - /).

also die Abfrage:

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

Der Ausgang:

PositionOfString, CountOfCommaDelimitedStrings, StringAtThatPosition 

1     3        asdasdwdfef 
2     3        rgrgtggt 
3     3        weef 
Jetzt

, wie bekommen wir diese Werte:

Ich wählte zwei Funktionen zu nutzen:

Die Namen beziehen sich auf die mysql Funktion 'FIND_IN_SET'.

1) Die Funktion COUNT_IN_SET: gibt den Zählerstand character delimited items in der Spalte zurück.

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) Die VALUE_IN_SET Funktion: delimited list behandelt die als one based array und gibt den Wert an dem gegebenen 'Index'.

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$$ 

Die intereseries Tabelle - siehe (Tally Tabellen)

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

Danke für Ihren Beitrag, aber ich habe die Antwort bekommen. – user3441151

+0

@ user3441151, ich freue mich, dass Sie eine Antwort erhalten, mit der Sie zufrieden sind. –

+0

Danke für den Bonus. Es wird geschätzt. –