Beste Möglichkeit, Segmente / Werte aus dem VARCHAR-Feld in SET-basiertem SQL zu extrahieren

Nehmen Sie die folgenden Beispieldaten:

SELECT 'HelpDesk Call Reference F0012345, Call Update, 40111' AS [Subject]
UNION ALL
SELECT 'HelpDesk Call Reference F0012346, Call Resolved, 40112' AS [Subject]
UNION ALL
SELECT 'HelpDesk Call Reference F0012347, New call logged, 40113' AS [Subject]

Ich möchte diese Daten wie folgt extrahieren:

Wie Sie sehen, muss ich Ref, Type & OurRef als separate Spalten extrahieren, um ein effizientes setbasiertes SQL bei der Verarbeitung der resultierenden E-Mails zu gewährleisten.

Normalerweise würde ich für dieses Szenario eine Funktion wie diese verwenden:

CREATE FUNCTION dbo.fnParseString (
    @Section SMALLINT ,
    @Delimiter CHAR ,
    @Text VARCHAR(MAX)
)
RETURNS VARCHAR(8000)
AS 
    BEGIN
        DECLARE @NextPos SMALLINT;
        DECLARE @LastPos SMALLINT;
        DECLARE @Found SMALLINT;

        SELECT  @NextPos = CHARINDEX(@Delimiter, @Text, 1) ,
                @LastPos = 0 ,
                @Found = 1

        WHILE @NextPos > 0
            AND ABS(@Section) <> @Found 
            SELECT  @LastPos = @NextPos ,
                    @NextPos = CHARINDEX(@Delimiter, @Text, @NextPos + 1) ,
                    @Found = @Found + 1

        RETURN LTRIM(RTRIM(CASE
            WHEN @Found <> ABS(@Section) OR @Section = 0 THEN NULL
            WHEN @Section > 0 THEN SUBSTRING(@Text, @LastPos + 1, CASE WHEN @NextPos = 0 THEN DATALENGTH(@Text) - @LastPos ELSE @NextPos - @LastPos - 1 END)
            ELSE SUBSTRING(@Text, @LastPos + 1, CASE WHEN @NextPos = 0 THEN DATALENGTH(@Text) - @LastPos ELSE @NextPos - @LastPos - 1 END)
        END))
    END

Zum Beispiel ersetze ich dann den Leerraum vor dem Verweis durch ein Komma und teile ihn wie folgt auf:

WITH    ExampleData
          AS ( SELECT   'HelpDesk Call Reference F0012345, Call Update, 40111' AS [Subject]
               UNION ALL
               SELECT   'HelpDesk Call Reference F0012346, Call Resolved, 40112'
               UNION ALL
               SELECT   'HelpDesk Call Reference F0012347, New call logged, 40113'
             )
    SELECT  dbo.fnParseString(2, ',', REPLACE([Subject], 'HelpDesk Call Reference ', 'HelpDesk Call Reference, ')) AS [Ref] ,
            dbo.fnParseString(3, ',', REPLACE([Subject], 'HelpDesk Call Reference ', 'HelpDesk Call Reference, ')) AS [Type] ,
            dbo.fnParseString(4, ',', REPLACE([Subject], 'HelpDesk Call Reference ', 'HelpDesk Call Reference, ')) AS [OurRef]
    FROM    ExampleData

Wie Sie sehen können, habe ich eine Lösung, die das Endergebnis erhält, nach dem ich bin, aber die Verwendung eines chaotischen udf ist nicht ideal und ich habe mich gefragt, obSQL Server hat eine bessere Möglichkeit, solche Dinge zu tun - vielleicht reguläre Inline-Ausdrücke? Das heißt Meiner Ansicht nachPATINDEX() akzeptiert reguläre Ausdrücke als Suchzeichenfolge - dies in Verbindung mitSUBSTRING() könnte tun, was ich brauche, aber ich weiß nicht wirklich, wo ich anfangen soll?

Bearbeiten: Bitte beachten Sie, dass dies ein vereinfachtes Beispiel ist, das Thema variabel ist und ich die gleiche Technik anpassen werde, um den Körper zu analysieren. Der Körper wird 8 Datenelemente haben, die ich mit einer Vielzahl von Begrenzungszeichen auswerten muss schließt die Verwendung von ausParseName() da es nur 4 Teile erlaubt und ich keine feste Länge verwenden kann (d. h.substring()Da die Länge sehr unterschiedlich sein wird (vor allem, wenn verschiedene Helpdesks betroffen sind (und es sich um solche handelt), habe ich nach dem Vorbild vonPATINDEX() & SUBSTRING()

Antworten auf die Frage(3)

Ihre Antwort auf die Frage