use*_*588 4 sql t-sql sql-server
我找不到一个好的方法来做到这一点,并且由于一些限制,它必须是不使用变量的编码,但我可以调用一个函数.无论如何,我需要从Select查询返回一个结果集,其中一行是一个管道分隔的字符串.
所以,它将返回如下内容:
id| Name | Message |
---------------------
1 | Some Name | 'Here is my | delimited | message'
Run Code Online (Sandbox Code Playgroud)
我需要它
id| Name | Message1 | Message2 | Message3
------------------------------------------------------
1 | Some Name | 'Here is my' | 'delimited' | 'message'
Run Code Online (Sandbox Code Playgroud)
我想的是Parsename('','|',1),你可以在哪里传递分隔符而不是它总是一段时间,但我不知道实现这一目标的最佳方法.
编辑:我尝试过这种变化但当然很混乱.可能有4个或更多
SELECT Field1,
Field2 AS Originalvalue,
--1
SUBSTRING(Field2,0,CHARINDEX('|',Field2)) AS Msg1,
--2
LEFT(SUBSTRING(Field2,CHARINDEX('|',Field2)+1 ,LEN(Field2)),CHARINDEX('|',SUBSTRING(Field2,CHARINDEX('|',Field2)+1 ,LEN(Field2)))-1)
AS ExtractedValue
FROM Table1 T1 JOIN Table2 T2
ON T1.Id = T2.Id
WHERE T1.Id = 12
Run Code Online (Sandbox Code Playgroud)
您可以按如下方式编写sql函数.
create Function dbo.fn_Parsename(@Message Varchar(1000), @delimiter char(1), @index int )
Returns Varchar(1000)
As
Begin
Declare
@curIndex int = 0,
@pos int = 1,
@prevPos int = 0,
@result varchar(1000)
while @pos > 0
Begin
set @pos = CHARINDEX(@delimiter, @Message, @prevPos);
if(@pos > 0)
begin-- get the chars between the prev position to next delimiter pos
set @result = SUBSTRING(@message, @prevPos, @pos-@prevPos)
end
else
begin--get last delim message
set @result = SUBSTRING(@message, @prevPos, LEN(@message))
end
if(@index = @curIndex)
begin
return @result
end
set @prevPos = @pos + 1
set @curIndex = @curIndex + 1;
end
return ''--not found
End
Run Code Online (Sandbox Code Playgroud)
你可以这样称呼它:
select dbo.fn_Parsename('Here is my | delimited | message','|', 0)
select dbo.fn_Parsename('Here is my | delimited | message','|', 1)
select dbo.fn_Parsename('Here is my | delimited | message','|', 2)
Run Code Online (Sandbox Code Playgroud)