Функция sql для возврата таблицы имен и значений с учетом строки запроса

У кого-нибудь есть функция t-sql, которая берет строку запроса из URL-адреса и возвращает таблицу пар имя / значение?

например, у меня есть такое значение, хранящееся в моей базе данных:

foo=bar&baz=qux&x=y

и я хочу создать таблицу с двумя столбцами (ключ и значение) (с 3 строками в этом примере), например:

name  | value
-------------
foo   | bar
baz   | qux
x     | y

ОБНОВЛЕНИЕ: есть причина, по которой мне это нужно в функции t-sql; Я не могу сделать это в коде приложения. Возможно, я мог бы использовать код CLR в функции, но я бы предпочел этого не делать.

ОБНОВЛЕНИЕ: под «строкой запроса» я подразумеваю часть URL-адреса после «?». Я не имею в виду, что часть запроса будет в URL-адресе; строка запроса используется только как данные.


person Rory    schedule 16.04.2009    source источник


Ответы (3)


create function dbo.fn_splitQuerystring(@querystring nvarchar(4000))
returns table 
as
/*
 * Splits a querystring-formatted string into a table of name-value pairs
 * Example Usage:
        select * from dbo.fn_splitQueryString('foo=bar&baz=qux&x=y&y&abc=')
 */
return ( 
    select  'name' = SUBSTRING(s,1,case when charindex('=',s)=0 then LEN(s) else charindex('=',s)-1 end) 
        ,   'value' = case when charindex('=',s)=0 then '' else SUBSTRING(s,charindex('=',s)+1,4000) end    
    from dbo.fn_split('&',@querystring)
)
go

Что использует эту функцию разделения общего назначения:

create function dbo.fn_split(@sep nchar(1), @s nvarchar(4000))
returns table
/*
 * From https://stackoverflow.com/questions/314824/
 * Splits a string into a table of values, with single-char delimiter.
 * Example Usage:
        select * from dbo.fn_split(',', '1,2,5,2,,dggsfdsg,456,df,1,2,5,2,,dggsfdsg,456,df,1,2,5,2,,')
 */
AS
RETURN (
    WITH Pieces(pn, start, stop) AS (
      SELECT 1, 1, CHARINDEX(@sep, @s)
      UNION ALL
      SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
      FROM Pieces
      WHERE stop > 0
    )
    SELECT pn,
      SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 4000 END) AS s
    FROM Pieces
  )
go

В конечном итоге позволяя вам делать что-то вроде этого:

select name, value
from dbo.fn_splitQuerystring('foo=bar&baz=something&x=y&y&abc=&=whatever')
person Rory    schedule 26.05.2012

Я уверен, что TSQL можно заставить перепрыгнуть через эту обруч для вас, но почему бы не проанализировать строку запроса в коде вашего приложения, где она, скорее всего, должна быть?

Затем вы можете посмотреть этот ответ, что сделали другие для синтаксического анализа строк запроса в name / пары значений.

Или этот ответ.

Или это.

Или это.

person Ed Guiness    schedule 16.04.2009
comment
Есть причины, по которым в моем случае мне нужно делать это на уровне базы данных, к сожалению, поскольку очевидно, что было бы намного проще использовать код .NET согласно этим ссылкам. - person Rory; 16.04.2009

Пожалуйста, не кодируйте строки запроса непосредственно в URL-адресах из соображений безопасности: любой может легко заменить любой старый запрос, чтобы получить доступ к информации, которой у него не должно быть - или, что еще хуже, "DROP DATABASE;". Проверка на подозрительные "ключевые слова" или такие вещи, как символы кавычек, не решение - творческие хакеры будут обходить эти меры, и вы будете раздражать всех, чья фамилия "О'Рейли".

Исключения: только внутренние серверы или общедоступные https URL-адреса. Но даже в этом случае нет причин, по которым вы не можете создать SQL-запрос на стороне клиента и отправить его оттуда.

person j_random_hacker    schedule 16.04.2009
comment
спасибо, но я имел в виду "строку запроса", как в части URL-адреса после?. Я не имею в виду, что части запроса будут в URL-адресе. - person Rory; 16.04.2009
comment
@ Рори: Да, я тоже об этом. - person j_random_hacker; 16.04.2009
comment
хорошо, в этом случае ваш ответ не является ответом на мой вопрос: у меня есть данные в моей базе данных, и я хочу превратить их в таблицу пар имя / значение. Я не помещаю запросы в строку запроса. - person Rory; 22.04.2009
comment
@Rory: Ах, я неправильно понял, извините (на самом деле три раза ...) Итак, вы имеете в виду, что у вас есть URL-адрес типа mysite.com/xyz?foo=bar;baz=qux;x=y, и вы хотите создать таблицу с двумя столбцами (ключ и значение) (с тремя строками в этом пример)? Я уверен, что это можно сделать, но, к сожалению, не знаю, как это сделать. - person j_random_hacker; 22.04.2009
comment
Да, точно. не беспокойтесь - я думаю, это показывает, что я должен писать свои вопросы яснее. Спасибо, в любом случае. - person Rory; 22.04.2009