Строка синтаксического анализа SQL - PullRequest
4 голосов
/ 28 октября 2011

Я не могу найти хороший способ сделать это, и из-за некоторых ограничений он должен быть закодирован без использования переменных, но я могу вызвать функцию.В любом случае мне нужно вернуть набор результатов из запроса Select, и одна из строк является строкой с разделителями.

Итак, он вернет что-то вроде:

id| Name      | Message |
---------------------
1 | Some Name | 'Here is my | delimited | message'

И мне нужно, чтобы оно было

id| Name      | Message1     | Message2    | Message3
------------------------------------------------------
1 | Some Name | 'Here is my' | 'delimited' | 'message'

Я думал о чем-то вроде 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

1 Ответ

8 голосов
/ 28 октября 2011

Вы можете написать функцию 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

И вы можете назвать это, как показано ниже:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...