从分号分隔列表中选择特定字符串

时间:2016-08-16 14:56:15

标签: sql-server tsql parsing split delimited-text

我想提取一个以分号作为分隔符的字符串。我尝试使用Substring,Charindex和Left函数。但是我无法获得理想的结果。以下是我的选择声明。输出结果必须是"不确定如何执行任务。在测试之前,仪表在办公室读了10个"。感谢

Declare @string Varchar(max)='Sampling:45;Traveling:30;CalibratedNo;uncalibratedReason:: ' +
                             'Unsure how to perform task.  Meter read 10 in office before ' +
                             'testing.;pH1:6.5;pH2:6.5;Dis.Oxygen1:7.4'

Select SubString(@string, (CHARINDEX('uncalibratedReason:', @string, 0) + 19), 
  (CharIndex('uncalibratedReason:', LEFT(@string, (LEN(@string) -
  (CharIndex(';', @string, 0)))), 0) - 0)) As New

2 个答案:

答案 0 :(得分:3)

试试这样:

Declare @string Varchar(max) = 'Sampling:45;Traveling:30;CalibratedNo;uncalibratedReason:Unsure how to perform task.  Meter read 10 in office before testing.;pH1:6.5;pH2:6.5;Dis.Oxygen1:7.4';

SELECT CAST('<x>' + REPLACE(@string,';','</x><x>') + '</x>' AS XML).value('x[4]','nvarchar(max)')

结果是:

uncalibratedReason:Unsure how to perform task.  Meter read 10 in office before testing.

如果您需要uncalibratedReason:,只需SUBSTRINGCHARINDEX即可取走:。{/ p>

更新

以下是完整代码:

DECLARE @result NVARCHAR(MAX)=
(SELECT CAST('<x>' + REPLACE(@string,';','</x><x>') + '</x>' AS XML).value('x[4]','nvarchar(max)'));

SELECT SUBSTRING(@result,CHARINDEX(':',@result)+1,10000)

更新2:通过开始字符串

来查找位置
DECLARE @result NVARCHAR(MAX)=
(SELECT CAST('<x>' + REPLACE(@string,';','</x><x>') + '</x>' AS XML).value('(x[substring(.,1,string-length("uncalibratedReason:")) eq "uncalibratedReason:"])[1]','nvarchar(max)'));

SELECT SUBSTRING(@result,CHARINDEX(':',@result)+1,10000)

更新3最终解决方案: - )

Declare @string Varchar(max) = 'Sampling:45;Traveling:30;CalibratedNo;uncalibratedReason:Unsure how to perform task.  Meter read 10 in office before testing.;pH1:6.5;pH2:6.5;Dis.Oxygen1:7.4';


WITH Casted(ThePart) AS
(
    SELECT Node.value('.','nvarchar(max)')
    FROM
    (
    SELECT CAST('<x>' + REPLACE(@string,';','</x><x>') + '</x>' AS XML)
    ) AS tbl(AsXML)
    CROSS APPLY AsXML.nodes('/x') AS The(Node)
)
,Splitted(SpecificPart) AS
(
    SELECT CAST('<x>' + REPLACE(ThePart,':','</x><x>') + '</x>'  AS XML) 
    FROM Casted
)
SELECT SpecificPart.value('x[1]','nvarchar(max)') AS Caption
      ,SpecificPart.value('x[2]','nvarchar(max)') AS Data
FROM Splitted

结果

Caption             Data
CalibratedNo        NULL
Dis.Oxygen1         7.4
pH1                 6.5
pH2                 6.5
Sampling            45
Traveling           30
uncalibratedReason  Unsure how to perform task.  Meter read 10 in office before testing.

答案 1 :(得分:2)

Shnugo anwser非常酷。 (给予好评)

但是,此UDF Parser返回序列和值

Declare @string Varchar(max)='Sampling:45;Traveling:30;CalibratedNo;uncalibratedReason:: ' +
                             'Unsure how to perform task.  Meter read 10 in office before ' +
                             'testing.;pH1:6.5;pH2:6.5;Dis.Oxygen1:7.4'

Select * from [dbo].[udf-Str-Parse](@String,';')
  --Where Key_PS = 5
  --Where Key_Value Like '%:%'
  --Where Key_Value Like 'pH1%'

返回

Key_PS  Key_Value
1       Sampling:45
2       Traveling:30
3       CalibratedNo
4       uncalibratedReason:: Unsure how to perform task.  Meter read 10 in office before testing.
5       pH1:6.5
6       pH2:6.5
7       Dis.Oxygen1:7.4

UDF

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
相关问题