533 Stimmen

Wie teile ich einen abgegrenzten String auf, um auf einzelne Elemente zugreifen zu können?

Mit SQL Server, wie kann ich einen String aufteilen, um auf Element x zugreifen zu können?

Nehmen wir einen String "Hallo John Smith". Wie kann ich den String nach Leerzeichen aufteilen und auf das Element an Index 1 zugreifen, das "John" zurückgeben sollte?

3 Stimmen

5 Stimmen

Die höchsten Antworten hier sind - zumindest für mich - ziemlich altmodisch und eher veraltet. Prozedurale Logik, Schleifen, Rekursionen, CLR, Funktionen, viele Codezeilen... Es könnte interessant sein, die "aktiven" Antworten zu lesen, um aktuellere Ansätze zu finden.

0 Stimmen

Ich habe eine neue Antwort mit einem aktuelleren Ansatz hinzugefügt: stackoverflow.com/a/49669994/632604

0voto

uzr Punkte 1150

Ein moderner Ansatz mit STRING_SPLIT erfordert SQL Server 2016 und höher.

DECLARE @string varchar(100) = 'Hello John Smith'

SELECT
    ROW_NUMBER() OVER (ORDER BY value) AS RowNr,
    value
FROM string_split(@string, ' ')

Ergebnis:

RowNr   value
1       Hello
2       John
3       Smith

Jetzt ist es möglich, das nth Element aus der Zeilennummer zu erhalten.

2 Stimmen

STRING_SPLIT garantiert nicht die Rückkehr der gleichen Reihenfolge. Aber OPENJSON tut dies (siehe meine Antwort (Update Bereich))

0voto

Andrew Hill Punkte 1852

Ähnlich wie die xml-basierte Antwort von josejuan habe ich festgestellt, dass die Verarbeitung des XML-Pfads nur einmal und dann das Pivoting etwas effizienter war:

select ID,
    [3] as PathProvidingID,
    [4] as PathProvider,
    [5] as ComponentProvidingID,
    [6] as ComponentProviding,
    [7] as InputRecievingID,
    [8] as InputRecieving,
    [9] as RowsPassed,
    [10] as InputRecieving2
    from
    (
    select id,message,d.* from sysssislog cross apply       ( 
          SELECT Item = y.i.value('(./text())[1]', 'varchar(200)'),
              row_number() over(order by y.i) as rn
          FROM 
          ( 
             SELECT x = CONVERT(XML, '' + REPLACE(Message, ':', '') + '').query('.')
          ) AS a CROSS APPLY x.nodes('i') AS y(i)
       ) d
       WHERE event
       = 
       'OnPipelineRowsSent'
    ) as tokens 
    pivot 
    ( max(item) for [rn] in ([3],[4],[5],[6],[7],[8],[9],[10]) 
    ) as data

lief in 8:30

select id,
tokens.value('(/n[3])', 'varchar(100)')as PathProvidingID,
tokens.value('(/n[4])', 'varchar(100)') as PathProvider,
tokens.value('(/n[5])', 'varchar(100)') as ComponentProvidingID,
tokens.value('(/n[6])', 'varchar(100)') as ComponentProviding,
tokens.value('(/n[7])', 'varchar(100)') as InputRecievingID,
tokens.value('(/n[8])', 'varchar(100)') as InputRecieving,
tokens.value('(/n[9])', 'varchar(100)') as RowsPassed
 from
(
    select id, Convert(xml,''+Replace(message,'.','')+'') tokens
         from sysssislog 
       WHERE event
       = 
       'OnPipelineRowsSent'
    ) as data

lief in 9:20

0voto

zipppy Punkte 49

Die Antwort von Aaron Bertrand ist großartig, aber fehlerhaft. Es bearbeitet nicht korrekt ein Leerzeichen als Trennzeichen (wie im Beispiel in der Originalfrage), da die Längenfunktion führende Leerzeichen entfernt.

Im Folgenden ist sein Code mit einer kleinen Anpassung, um ein Leerzeichen als Trennzeichen zuzulassen:

CREATE FUNCTION [dbo].[SplitString]
(
    @List NVARCHAR(MAX),
    @Delim VARCHAR(255)
)
RETURNS TABLE
AS
    RETURN ( SELECT [Value] FROM 
      ( 
        SELECT 
          [Value] = LTRIM(RTRIM(SUBSTRING(@List, [Number],
          CHARINDEX(@Delim, @List + @Delim, [Number]) - [Number])))
        FROM (SELECT Number = ROW_NUMBER() OVER (ORDER BY name)
          FROM sys.all_objects) AS x
          WHERE Number <= LEN(@List)
          AND SUBSTRING(@Delim + @List, [Number], LEN(@Delim+'x')-1) = @Delim
      ) AS y
    );

0voto

Sam K Punkte 299

EINFACHE LÖSUNG ZUM PARSEN VON VOR- UND NACHNAMEN

DECLARE @Name varchar(10) = 'John Smith'

-- Holen Sie den Vornamen
SELECT SUBSTRING(@Name, 0, (SELECT CHARINDEX(' ', @Name)))

-- Holen Sie den Nachnamen
SELECT SUBSTRING(@Name, (SELECT CHARINDEX(' ', @Name)) + 1, LEN(@Name))

In meinem Fall (und anscheinend auch bei vielen anderen...) habe ich eine Liste von Vor- und Nachnamen, die durch einen einfachen Leerschritt getrennt sind. Dies kann direkt in einer SELECT-Anweisung verwendet werden, um Vor- und Nachnamen zu parsen.

-- z.B. Holen Sie Vor- und Nachnamen aus einer Tabelle mit vollen Namen
SELECT SUBSTRING(FullName, 0, (SELECT CHARINDEX(' ', FullName))) as FirstName,
SUBSTRING(FullName, (SELECT CHARINDEX(' ', FullName)) + 1, LEN(FullName)) as LastName,
From FullNameTable

0voto

GGadde Punkte 393

Ich weiß, es ist spät, aber ich hatte kürzlich diese Anforderung und bin mit dem folgenden Code gekommen. Ich habe keine Wahl, benutzerdefinierte Funktionen zu verwenden. Hoffentlich hilft das.

SELECT 
    SUBSTRING(
                SUBSTRING('Hello John Smith' ,0,CHARINDEX(' ','Hello John Smith',CHARINDEX(' ','Hello John Smith')+1)
                        ),CHARINDEX(' ','Hello John Smith'),LEN('Hello John Smith')
            )

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X