2016-09-14 3 views
1

Ich verwende SQL Server 2014. Ich habe eine Spalte, die Textdaten enthält. Die Daten würden wie folgt aussehen:String-Manipulation in SQL

create table #temp 
(
stringdata varchar(100) NULL 
) 

insert into #temp values 
('CN=ABCD,PN=XYZ,AD=123,AN=rst'), 
('AN=ABC,PN=XYZ,CN=12,AN=rst'), 
('AN=ABC,CN=XYZ,PN=123,AN=rst'), 
('AN=ABC,AN=XYZ,CN=1234567,PN=rst') 

Und ich brauche das Ergebnis gesetzt Wert, der für CN abgebildet wird.

Ich habe versucht, die Daten mit der folgenden Abfrage zu extrahieren:

select substring(stringdata,charindex('CN=',stringdata),charindex(',',stringdata)-1),* 
from #temp 

Aber das Problem ist, dass es den ersten Index des Komma Wert annimmt. Ich konnte die korrekte Länge nicht angeben.

Gibt es eine einfache Abfrage, um die Daten zu erhalten?

+0

seine SQL Server 2014 – Remi

Antwort

1

Hier ist der Weg SUBSTRING aufzuspalten mit .

SELECT SUBSTRING(stringdata,CHARINDEX ('CN=',stringdata)+3 
     ,CASE WHEN CHARINDEX (',',SUBSTRING(stringdata,CHARINDEX ('CN=',stringdata)+3,LEN(stringdata)))=0 THEN LEN(stringdata)-1 
      ELSE CHARINDEX (',',SUBSTRING(stringdata,CHARINDEX ('CN=',stringdata)+3,LEN(stringdata)))-1 END) 
FROM #temp 

Beispielausgabe:

enter image description here

+0

Was passiert, wenn CN an der letzten Position kommt. Wir haben kein ',' Trennzeichen in der Endposition. – Remi

+0

Beispiel: Einfügen in #temp-Werte ('PN = XYZ, AD = 123, AN = erste, CN = ABCD') – Remi

+0

@Remi: fügen Sie einfach eine case-Anweisung hinzu, die diesen Fall behandelt. Bitte benutzen Sie den aktualisierten Code. –

0

String-Operationen sind in SQL Server schmerzhaft. Manchmal finde ich, dass OUTER APPLY helfen:

select t.stringdata, t3.sd2 as cn 
from #temp t outer apply 
    (select stuff(stringdata, 1, charindex('CN=', stringdata), '') as sd1 
    ) t2 outer apply 
    (select left(sd1 + ',', charindex(',', sd1 + ',')) as sd2 
    ) t3 

Natürlich, das wird noch komplizierter, wenn CN= ist nicht in der Zeichenkette. Die + ',' ermöglicht es dem Element CN, das letzte Element der Zeichenfolge zu sein.

0

können Sie auch versuchen, diese ein:

WITH Xmls AS 
(
    SELECT CONVERT(xml,'<a>'+REPLACE(stringdata,',','</a><a>')+'</a>') Col FROM #temp 
) 
SELECT N.value('.', 'varchar(100)') 
FROM Xmls 
CROSS APPLY Col.nodes('a') T(N) 
WHERE N.value('.', 'varchar(100)') LIKE 'CN%' 
1

Wenn es immer 4 Elemente durch Komma getrennt sind, können Sie diese knifflige Abfrage verwenden:

SELECT REPLACE(sdata,'CN=','') 
FROM (
    SELECT PARSENAME(REPLACE(stringdata,',','.'),1) as sdata 
    FROM #temp 
    UNION 
    SELECT PARSENAME(REPLACE(stringdata,',','.'),2) 
    FROM #temp 
    UNION 
    SELECT PARSENAME(REPLACE(stringdata,',','.'),3) 
    FROM #temp 
    UNION 
    SELECT PARSENAME(REPLACE(stringdata,',','.'),4) 
    FROM #temp 
) p 
WHERE sdata LIKE 'CN=%' 

Ausgang:

ABCD 
12 
XYZ 
1234567 
0

Mit Hilfe eines Parsers und eines CROSS APPLY, vielleicht die folgenden

Select A.* 
     ,B.Key_PS 
     ,Key_Value=Replace(B.Key_Value,'CN=','') 
    from #Temp A 
    Cross Apply (Select * From [dbo].[udf-Str-Parse] (A.stringdata,',') Where Key_Value like 'CN=%') B 

Returns

stringdata      Key_PS Key_Value 
CN=ABCD,PN=XYZ,AD=123,AN=rst 1  ABCD 
AN=ABC,PN=XYZ,CN=12,AN=rst  3  12 
AN=ABC,CN=XYZ,PN=123,AN=rst  2  XYZ 
AN=ABC,AN=XYZ,CN=1234567,PN=rst 3  1234567 

Der Parser wenn

benötigt
CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimeter varchar(10)) 
--Usage: Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',') 
--  Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ') 

Returns @ReturnTable Table (Key_PS int IDENTITY(1,1), Key_Value varchar(max)) 
As 
Begin 
    Declare @XML xml;Set @XML = Cast('<x>' + Replace(@String,@Delimeter,'</x><x>')+'</x>' as XML) 
    Insert Into @ReturnTable Select ltrim(rtrim(String.value('.', 'varchar(max)'))) FROM @XML.nodes('x') as T(String) 
    Return 
End 
0

Ich denke, was Sie einfügen wollen, ist wie folgt:

insert into #temp values 
('CN=ABCD','PN=XYZ','AD=123','AN=rst'), 
('AN=ABC','PN=XYZ','CN=12','AN=rst'), 
('AN=ABC','CN=XYZ','PN=123','AN=rst'), 
('AN=ABC','AN=XYZ','CN=1234567','PN=rst')