Обработка данных в предложении IN с параметрами SQL? - PullRequest
10 голосов
/ 18 сентября 2008

Все мы знаем, что подготовленные операторы являются одним из лучших способов защиты от атак SQL-инъекций. Каков наилучший способ создания подготовленного оператора с предложением «IN». Есть ли простой способ сделать это с неопределенным количеством значений? Возьмите следующий запрос для примера.

SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (1,2,3)

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

SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (@IDVAL_1,@IDVAL_2,@IDVAL_3)

Можно ли использовать просто передать массив в качестве значения параметра запроса и использовать запрос следующим образом?

SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (@IDArray)

Если это важно, я работаю с SQL Server 2000, в VB.Net

Ответы [ 6 ]

5 голосов
/ 18 сентября 2008

Вот, пожалуйста, сначала создайте следующую функцию ...

Create Function [dbo].[SeparateValues]
(
    @data VARCHAR(MAX),
    @delimiter VARCHAR(10) 
) 
    RETURNS @tbldata TABLE(col VARCHAR(10))
As
Begin
    DECLARE @pos INT
    DECLARE @prevpos INT

    SET @pos = 1 
    SET @prevpos = 0

    WHILE @pos > 0 
        BEGIN

        SET @pos = CHARINDEX(@delimiter, @data, @prevpos+1)

        if @pos > 0 
        INSERT INTO @tbldata(col) VALUES(LTRIM(RTRIM(SUBSTRING(@data, @prevpos+1, @pos-@prevpos-1))))

        else

        INSERT INTO @tbldata(col) VALUES(LTRIM(RTRIM(SUBSTRING(@data, @prevpos+1, len(@data)-@prevpos))))

        SET @prevpos = @pos 
    End

    RETURN

END

затем используйте следующее ...

Declare @CommaSeparated varchar(50)
Set @CommaSeparated = '112,112,122'
SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (select col FROM [SeparateValues](@CommaSeparated, ','))

Я думаю, что SQL Server 2008 будет разрешать табличные функции.

UPDATE

Вы увеличите производительность, используя следующий синтаксис ...

SELECT ID,Column1,Column2 FROM MyTable
Cross Apply [SeparateValues](@CommaSeparated, ',') s
Where MyTable.id = s.col

Поскольку предыдущий синтаксис заставляет SQL Server выполнить дополнительную команду «Сортировка» с помощью предложения «IN». Плюс - на мой взгляд это выглядит лучше: D!

1 голос
/ 18 сентября 2008

Если вы хотите передать массив, вам понадобится функция в sql, которая может превратить этот массив в суб-выбор.

Эти функции очень распространены, и большинство домашних систем используют их в своих интересах.

Большинство коммерческих или, вернее, профессиональных ORM делают вклады, выполняя кучу переменных, поэтому, если у вас это работает, я думаю, это стандартный метод.

0 голосов
/ 28 сентября 2008

Перейти с решением, опубликованным Digiguru. Это отличное многоразовое решение, и мы используем ту же технику. Новые члены команды любят это, поскольку это экономит время и сохраняет наши хранимые процедуры согласованными. Решение также хорошо работает с отчетами SQL, поскольку параметры, передаваемые хранимым процедурам для создания наборов записей, передаются в varchar (8000). Вы просто подключаете его и уходите.

0 голосов
/ 19 сентября 2008

Вы можете создать временную таблицу TempTable с одним столбцом VALUE и вставить все идентификаторы. Тогда вы можете сделать это с помощью подвыбора:

SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (SELECT VALUE FROM TempTable)
0 голосов
/ 18 сентября 2008

Вот одна техника, которую я использую

ALTER   Procedure GetProductsBySearchString
@SearchString varchar(1000),
as
set nocount on
declare @sqlstring varchar(6000)
select @sqlstring = 'set nocount on
select a.productid, count(a.productid) as SumOf, sum(a.relevence) as CountOf 
 from productkeywords a 
 where rtrim(ltrim(a.term)) in (''' + Replace(@SearchString,' ', ''',''') + ''')
 group by a.productid order by SumOf desc, CountOf desc'

exec(@sqlstring)
0 голосов
/ 18 сентября 2008

В SQL Server 2008 они наконец-то нашли решение этой классической проблемы, добавив новый тип данных «таблица». По-видимому, это позволяет передавать массив значений, который можно использовать в дополнительном выборе, чтобы выполнить то же самое, что и оператор IN.

Если вы используете SQL Server 2008, вы можете посмотреть на это.

...