SQL Server - замена одинарных кавычек и использование IN - PullRequest
0 голосов
/ 23 октября 2009

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

Когда я выполняю следующую хранимую процедуру:

exec dbo.myStoredProcedure @myFilter=N'1, 2, 3, 4'

Я получаю следующую ошибку:

"Conversion failed when converting the varchar value '1, 2, 3, 4' to data type int."

Моя хранимая процедура довольно проста. Это выглядит так:

CREATE PROCEDURE [dbo].[myStoredProcedure]
    @myFilter nvarchar(512) = NULL
AS
SET NOCOUNT ON
BEGIN
    -- Remove the quote marks so the filter will work with the "IN" statement
    SELECT @myFilter = REPLACE(@myFilter, '''', '')

    -- Execute the query
    SELECT
        t.ID,
        t.Name      
    FROM
        MyTable t
    WHERE
        t.ID IN (@myFilter)
    ORDER BY
        t.Name
END

Как использовать параметр в выражении SQL, как описано выше? Спасибо!

Ответы [ 6 ]

4 голосов
/ 23 октября 2009

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

Если вы работаете со списками или массивами в SQL Server, я рекомендую вам прочитать замечательные материалы Erland Sommarskogs:

Массивы и списки в SQL Server 2005

3 голосов
/ 23 октября 2009

Вам нужно разбить строку и вывести ее во временную таблицу. Затем вы присоединяетесь к временному столу.

Есть много примеров этого, вот один случайный.

http://blogs.microsoft.co.il/blogs/itai/archive/2009/02/01/t-sql-split-function.aspx

2 голосов
/ 23 октября 2009

Отсутствует функция разделения, что-то вроде этого:

CREATE PROCEDURE [dbo].[myStoredProcedure]
    @myFilter varchar(512) = NULL -- don't use NVARCHAR for a list of INTs
AS
SET NOCOUNT ON
BEGIN
    SELECT
        t.ID,
        t.Name          
    FROM
        MyTable t
    WHERE
        CHARINDEX(','+CONVERT(VARCHAR,t.ID)+',',@myFilter) > 0
    ORDER BY
        t.Name
END

Производительность будет плохой. Сканирование таблицы каждый раз. Лучше использовать функцию разделения. Смотри: http://www.sommarskog.se/arrays-in-sql.html

0 голосов
/ 23 октября 2009

У меня также есть пара постов в блоге, с множеством интересных комментариев и диалогов:

Подробнее о разделении списков

Обработка списка целых чисел

0 голосов
/ 23 октября 2009

Я нашел милый способ сделать это - но он немного пахнет.

declare @delimitedlist varchar(8000)
set @delimitedlist = '|1|2|33|11|3134|'

select * from mytable where @delimitedlist like '%|' + cast(id as varchar) + '|%'

Итак ... это вернет все записи с идентификатором, равным 1, 2, 33, 11 или 3134.

EDIT : Я также добавил бы, что это не уязвимо для внедрения SQL-кода (в то время как динамический SQL использует ваши методы внесения в белый / черный список, чтобы гарантировать, что он не уязвим). Это может сказаться на производительности больших наборов данных, но это работает и безопасно.

0 голосов
/ 23 октября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...