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()