如何在某些单词后提取Substring

时间:2016-10-08 13:55:12

标签: sql sql-server tsql

我有一个包含以下值的列:

Row1: "Storage system. Drive Model: BCD1000EFG disk has failed at port 1."
Row2: "Server model Blade. Disk Drive Model: NDH450TSH HDD has failed at bay 2 enclosure 1."

我想在Drive Model:

之后提取值
BCD1000EFG
NDH450TSH

使用SQL Server 2012。

3 个答案:

答案 0 :(得分:1)

根据你的问题,这可能是你需要的......

  

将此查询设为store_procedure,并在需要时调用。

尝试相应地修改它。

DECLARE @LOOP_1 INT=1,@NAME NVARCHAR (MAX),@LEFT NVARCHAR(MAX),@loop_2 int=0
SET @NAME='Server model Blade. Disk Drive Model: NDH450TSH HDD has failed at bay 2 enclosure 1.'

-- First loop started to find where 'Drive Model: ' is located
WHILE @LOOP_1!=(SELECT LEN(@NAME))
BEGIN

SET @LEFT=(LEFT(@NAME,@LOOP_1))
IF @LEFT LIKE '%Drive Model: ' BEGIN
set @NAME=(right(@NAME,len(@name)-@LOOP_1))

-- Second loop started to find where ' ' is located after 'Drive Model: '
WHILE @loop_2!=(SELECT LEN(@NAME))
BEGIN

SET @LEFT=(LEFT(@NAME,@loop_2))
IF @LEFT LIKE '% ' BEGIN
SELECT left(@name,@loop_2-1)
set @loop_2=(SELECT LEN(@NAME)-1)
END
SET @loop_2=@loop_2+1
END

END
SET @LOOP_1=@LOOP_1+1

END

答案 1 :(得分:0)

这样的字符串操作在SQL Server中并不好玩,因为内置的字符串处理功能不是很强大。一种方法是将整个事物转换为XML,并使用XML处理原语。

这是一种可以使用字符串修改的方法:

select t.*, val2.drive_model
from t outer apply
     (values (stuff(col, 1, charindex('Drive Model: ', col) + 13, ''))
     ) val1(col1_1) outer apply
     (values (left(col1_1, charindex(' '))
     ) val2(drive_model);

如果您的驱动器型号不在字符串中,则在执行操作之前,您需要额外的逻辑来验证字符串。那看起来像是:

from t outer apply
     (values (case when col like '%Drive Model: %'
                   then stuff(col, 1, charindex('Drive Model: ', col) + 13, ''))
              end)
     ) val1(col1_1) . . .

答案 2 :(得分:0)

另一种选择是使用解析器。我假设关键是型号:

Declare @YourTable table (SomeField varchar(max))
Insert into @YourTable values
('Storage system. Drive Model: BCD1000EFG disk has failed at port 1.'),
('Server model Blade. Disk Drive Model: NDH450TSH HDD has failed at bay 2 enclosure 1.')

    Select A.*
          ,B.Model
     From @YourTable A
     Cross Apply (Select Model=Substring(RetVal,1,CharIndex(' ',RetVal)) From [dbo].[udf-Str-Parse](A.SomeField,'Model:') Where RetSeq=2 ) B

返回

SomeField                                               Model
Storage system. Drive Model: BCD1000EFG disk...         BCD1000EFG
Server model Blade. Disk Drive Model: NDH450TSH HDD...  NDH450TSH

如果需要,该功能。 我应该注意,如果您不能使用TVF,逻辑可以很容易地移植到Cross Apply

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table 
As
Return (  
    Select RetSeq = Row_Number() over (Order By (Select null))
          ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
    From (Select x = Cast('<x>'+ Replace(@String,@Delimiter,'</x><x>')+'</x>' as xml).query('.')) as A 
    Cross Apply x.nodes('x') AS B(i)
);
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')