Ich habe eine SQL Server 2008 R2-Spalte mit einer Zeichenfolge, die ich durch ein Komma teilen muss. Ich habe viele Antworten auf StackOverflow gesehen, aber keine davon funktioniert in R2. Ich habe sichergestellt, dass ich ausgewählte Berechtigungen für Beispiele für geteilte Funktionen habe. Jede Hilfe sehr geschätzt.
sql
sql-server
tsql
sql-server-2008
split
Lee Grindon
quelle
quelle
mdq.RegexSplit
Add-On "Stammdatendienste" enthält eine Funktion, die möglicherweise hilfreich ist. Auf jeden Fall eine Untersuchung wert .Antworten:
Ich habe diese SQL verwendet, die für Sie möglicherweise funktioniert: -
und um es zu benutzen: -
quelle
Hat jemand anstelle von rekursiven CTEs und while-Schleifen einen satzbasierten Ansatz in Betracht gezogen? Beachten Sie, dass diese Funktion für die Frage geschrieben wurde, die auf SQL Server 2008 und Komma als Trennzeichen basierte . In SQL Server 2016 und höher (und in Kompatibilitätsstufe 130 und höher)
STRING_SPLIT()
ist dies eine bessere Option .Wenn Sie vermeiden möchten, dass die Länge der Zeichenfolge <= die Anzahl der Zeilen in
sys.all_columns
(9.980 inmodel
in SQL Server 2017; viel höher in Ihren eigenen Benutzerdatenbanken) ist, können Sie andere Ansätze zum Ableiten der Zahlen verwenden, z Erstellen Sie Ihre eigene Zahlentabelle . Sie können auch einen rekursiven CTE verwenden, wenn Sie keine Systemtabellen verwenden oder keine eigenen erstellen können:Sie müssen jedoch an die äußere Abfrage anhängen
OPTION (MAXRECURSION 0)
(oderMAXRECURSION <longest possible string length if < 32768>
), um Fehler bei der Rekursion für Zeichenfolgen> 100 Zeichen zu vermeiden. Wenn das auch keine gute Alternative ist, dann sehen Sie diese Antwort wie in den Kommentaren angegeben.(Auch das Trennzeichen muss sein
NCHAR(<=1228)
. Ich recherchiere immer noch warum.)Weitere Informationen zu Teilungsfunktionen, warum (und beweisen Sie dies), während Schleifen und rekursive CTEs nicht skaliert werden, und bessere Alternativen, wenn Zeichenfolgen aus der Anwendungsschicht aufgeteilt werden:
quelle
sys.all_objects
geringer ist als die Anzahl der Zeichen in der Eingabezeichenfolge, wird die Zeichenfolge abgeschnitten und die Werte gehen verloren. Da diessys.all_objects
nur als Hack zum Generieren von Zeilen verwendet wird, gibt es bessere Möglichkeiten, dies zu tun, z . B. diese Antwort .Endlich ist das Warten in SQL Server 2016 vorbei. Sie haben die Split-String-Funktion eingeführt:
STRING_SPLIT
Alle anderen Methoden zum Teilen von Zeichenfolgen wie XML, Tally-Tabelle, while-Schleife usw. wurden dadurch weggeblasen
STRING_SPLIT
Funktion .Hier ist ein ausgezeichneter Artikel mit Leistungsvergleich: Leistungsüberraschungen und Annahmen: STRING_SPLIT
quelle
Der einfachste Weg, dies zu tun, ist die Verwendung von
XML
Formats.1. Konvertieren von Zeichenfolgen in Zeilen ohne Tabelle
ABFRAGE
ERGEBNIS
2. Konvertieren in Zeilen aus einer Tabelle, die eine ID für jede CSV-Zeile haben
QUELLENTABELLE
ABFRAGE
ERGEBNIS
quelle
@String
verbotene Zeichen enthält ... Ich habe gerade eine Antwort gepostet , um dieses Problem zu beheben.Ich brauchte einen schnellen Weg , um von der zu befreien
+4
von einem Postleitzahl .Kein Prozess ... kein UDF ... nur ein kleiner kleiner Inline-Befehl, der das tut, was er muss. Nicht schick, nicht elegant.
Ändern Sie das Trennzeichen nach Bedarf usw., und es funktioniert für alles.
quelle
wenn Sie ersetzen
mit
Sie können diese letzte Einfügung nach der while-Schleife entfernen!
quelle
+1
anSELECT @pos = LEN(@stringToSplit)
scheint dieses Problem zu beheben. DasSELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
wird jedoch zurückgegeben,Invalid length parameter passed to the LEFT or SUBSTRING function
sofern Sie nicht auch+1
den dritten Parameter von SUBSTRING hinzufügen . oder Sie könnten diese Aufgabe durchSET @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, 4000) --MAX len of nvarchar is 4000
Alle Funktionen zum Teilen von Zeichenfolgen, die eine Art Schleifen (Iterationen) verwenden, weisen eine schlechte Leistung auf. Sie sollten durch eine satzbasierte Lösung ersetzt werden.
Dieser Code wird ausgezeichnet ausgeführt.
quelle
@List
verbotene Zeichen enthält ... Ich habe gerade eine Antwort gepostet , um dieses Problem zu beheben.Der häufig verwendete Ansatz mit XML-Elementen bricht bei verbotenen Zeichen ab. Dies ist ein Ansatz, um diese Methode mit jeder Art von Zeichen zu verwenden, auch mit dem Semikolon als Trennzeichen.
Der Trick besteht darin, zuerst
SELECT SomeString AS [*] FOR XML PATH('')
alle verbotenen Zeichen richtig zu entkommen. Das ist der Grund, warum ich das Trennzeichen durch einen magischen Wert ersetze , um Probleme mit;
dem Trennzeichen zu vermeiden .Das Ergebnis
quelle
Ich musste kürzlich so etwas schreiben. Hier ist die Lösung, die ich gefunden habe. Es ist für jede Trennzeichenfolge verallgemeinert und ich denke, es würde etwas besser funktionieren:
quelle
Eine Lösung mit einem CTE, falls jemand das brauchen sollte (abgesehen von mir, der es offensichtlich getan hat, habe ich es deshalb geschrieben).
quelle
Dies ist enger zugeschnitten. Wenn ich dies tue, habe ich normalerweise eine durch Kommas getrennte Liste eindeutiger IDs (INT oder BIGINT), die ich als Tabelle umwandeln möchte, um sie als innere Verknüpfung zu einer anderen Tabelle mit dem Primärschlüssel INT oder BIGINT zu verwenden. Ich möchte, dass eine Inline-Tabellenwertfunktion zurückgegeben wird, damit ich den effizientesten Join habe.
Beispielnutzung wäre:
Ich habe die Idee von http://sqlrecords.blogspot.com/2012/11/converting-delimited-list-to-table.html gestohlen und sie so geändert, dass sie als Inline-Tabelle bewertet und als INT umgewandelt wird.
quelle
Es gibt hier eine korrekte Version, aber ich dachte, es wäre schön, ein wenig Fehlertoleranz hinzuzufügen, falls sie ein nachfolgendes Komma haben, und es so zu machen, dass Sie es nicht als Funktion, sondern als Teil eines größeren Codeteils verwenden können . Nur für den Fall, dass Sie es nur einmal verwenden und keine Funktion benötigen. Dies gilt auch für Ganzzahlen (wofür ich sie benötigt habe), sodass Sie möglicherweise Ihre Datentypen ändern müssen.
quelle
SET @StringToSeperate = @StringToSeperate+','
unmittelbar vor derWHILE
Schleife wären, könnten Sie möglicherweise den Block "letzten Wert hinzufügen" entfernen. Siehe auch mein Sol'n auf GithubIch habe die Funktion von + Andy Robinson ein wenig modifiziert. Jetzt können Sie nur das erforderliche Teil aus der Rückgabetabelle auswählen:
SELECT Name FROM dbo.splitstring('ELIS.YD.CRP1.1.CBA.MDSP.T389.BT') WHERE numOrder=5
quelle
Wenn Sie eine schnelle Ad-hoc-Lösung für häufige Fälle mit minimalem Code benötigen, ist dieser rekursive CTE-Zweiliner genau das Richtige für Sie:
Verwenden Sie dies entweder als eigenständige Anweisung oder fügen Sie einfach die oben genannten CTEs zu einer Ihrer Abfragen hinzu, und Sie können die resultierende Tabelle
b
mit anderen verknüpfen, um sie in weiteren Ausdrücken zu verwenden.bearbeiten (von Shnugo)
Wenn Sie einen Zähler hinzufügen, erhalten Sie zusammen mit der Liste einen Positionsindex:
Das Ergebnis:
quelle
Ich gehe die XML-Route, indem ich die Werte in Elemente einbinde (M, aber alles funktioniert):
quelle
Hier ist eine Version, die mithilfe von Patindex, einer einfachen Anpassung des obigen Beitrags, nach einem Muster aufgeteilt werden kann. Ich hatte einen Fall, in dem ich eine Zeichenfolge teilen musste, die mehrere Trennzeichen enthielt.
Ergebnis sieht so aus
stringa stringb x y z
quelle
Persönlich benutze ich diese Funktion:
quelle
Ich habe ein Doppel Splitter (Dauert zwei geteilte Zeichen) entwickelt wie gewünscht hier . Könnte in diesem Thread von Wert sein, da er für Abfragen im Zusammenhang mit der Aufteilung von Zeichenfolgen am häufigsten verwendet wird.
Verwendung:
Mögliche Verwendung (Ermitteln Sie den zweiten Wert für jeden Split):
quelle
Hier ist ein Beispiel, das Sie als Funktion verwenden können, oder Sie können dieselbe Logik in die Prozedur einfügen. --SELECT * from [dbo] .fn_SplitString;
quelle
@vCSV
verbotene Zeichen enthält ... Ich habe gerade eine Antwort gepostet , um dieses Problem zu beheben.Eine rekursive cte-basierte Lösung
quelle
Dies basiert auf der Antwort von Andy Robertson. Ich brauchte ein anderes Trennzeichen als Komma.
Und um es zu benutzen:
(Getestet auf SQL Server 2008 R2)
BEARBEITEN: korrekter Testcode
quelle
/ *
Testfälle: Siehe URL, auf die oben als "erweiterte Funktionalität" verwiesen wird
SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,,b')
SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,,')
SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,, ')
SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,, c ')
* /
quelle
quelle
Sie können diese Funktion verwenden:
quelle
Bei allem Respekt vor @AviG ist dies die fehlerfreie Version der Funktion, die er entwickelt hat, um alle Token vollständig zurückzugeben.
quelle
Der einfachste Weg:
Es funktioniert sogar in der Express Edition :).
quelle