2016-09-14 37 views
1

我正在使用SQL Server 2014。我有一列中包含文本数据。数据是这样的: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') 

我需要被映射为CN结果的设定值。

我试着用下面的查询来提取数据:

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

但问题是,它需要逗号值的第一个指数。我无法提供正确的长度。

是否有任何简单的查询来获取数据?

+0

它的SQL服务器2014 – Remi

回答

1

下面是一个使用SUBSTRING分裂方式。

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 

样本输出:

enter image description here

+0

如果CN谈到在最后的位置是什么。在最终位置我们没有','分隔符。 – Remi

+0

例如:插入#temp值 ('PN = XYZ,AD = 123,AN = rst,CN = ABCD') – Remi

+0

@remi:只需添加一个case语句,即可处理这种情况。请使用更新的代码。 –

0

字符串操作在SQL Server中很痛苦。有时候我发现OUTER APPLY可以帮助:

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 

当然,这会变得更加复杂,如果CN=不是的字符串中。 + ','用于允许CN元素为字符串的最后一个元素。

0

你也可以试试这个:

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

如果总是用逗号分隔的4个元素,你可以使用这个棘手的查询:

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=%' 

输出:

ABCD 
12 
XYZ 
1234567 
0

在解析器和CROSS APPLY的帮助下,可能有以下

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 

返回

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 

如果需要

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

我想你要插入什么解析器是这样的:

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