Функция sql для возврата таблицы имен и значений с учетом строки запроса - PullRequest
1 голос
/ 16 апреля 2009

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

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

foo=bar&baz=qux&x=y

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

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

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

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

Ответы [ 3 ]

3 голосов
/ 26 мая 2012
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')
1 голос
/ 16 апреля 2009

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

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

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

Или это .

Или это .

0 голосов
/ 16 апреля 2009

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

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

...