我需要在两个字符串之间输出一个字符串。问题是有时会丢失两个参考字符串之一。如果第一个参考字符串不丢失,而第二个参考字符串丢失,我想从第一个参考字符串输出到字符串末尾。如果缺少第一个参考字符串,我想输出null或空白。
我看到了类似的帖子,但其中包含了参考字符串。就我而言,我不想包含参考字符串。
SELECT SUBSTRING(@Text, CHARINDEX('1stRefStr', @Text)
, CHARINDEX('2ndRefStr',@text) - CHARINDEX('1stRefStr', @Text) + Len('2ndRefStr'))
Example:
Patient: A Date: 1/1/1 Message: Hi Message Sent To: B
1st string reference is "Message:"
2nd string reference is "Message Sent To:"
Expected Result:
Hi
答案 0 :(得分:1)
如果您不介意辅助功能。
作为TVF,如果您的数据在表中,则很容易合并到CROSS APPLY中。
我修改了一个split / parse函数以接受两个非相似的距离计。
示例
Declare @Text varchar(max) = 'Patient: A Date: 1/1/1 Message: Hi Message Sent To: B'
Select *
From [dbo].[tvf-Str-Extract](@Text,'Message:','Message Sent') A
返回
RetSeq RetVal
1 Hi
功能
CREATE FUNCTION [dbo].[tvf-Str-Extract] (@String varchar(max),@Delim1 varchar(100),@Delim2 varchar(100))
Returns Table
As
Return (
Select RetSeq = row_number() over (order by RetSeq)
,RetVal = left(RetVal,charindex(@Delim2,RetVal)-1)
From (
Select RetSeq = row_number() over (order by 1/0)
,RetVal = ltrim(rtrim(B.i.value('(./text())[1]', 'varchar(max)')))
From ( values (convert(xml,'<x>' + replace((Select replace(@String,@Delim1,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>').query('.'))) as A(XMLData)
Cross Apply XMLData.nodes('x') AS B(i)
) C1
Where charindex(@Delim2,RetVal)>1
)
作为交叉申请书进行更新
Declare @YourTable table (ID int,SomeCol varchar(max))
Insert Into @YourTable values
(1,'Patient: A Date: 1/1/1 Message: Hi Message Sent To: B')
Select A.ID
,B.*
From @YourTable A
Cross Apply (
Select RetSeq = row_number() over (order by RetSeq)
,RetVal = left(RetVal,charindex('Message Sent',RetVal)-1)
From (
Select RetSeq = row_number() over (order by 1/0)
,RetVal = ltrim(rtrim(B.i.value('(./text())[1]', 'varchar(max)')))
From ( values (convert(xml,'<x>' + replace((Select replace(SomeCol,'Message:','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>').query('.'))) as A(XMLData)
Cross Apply XMLData.nodes('x') AS B(i)
) C1
Where charindex('Message Sent',RetVal)>1
) B