使用SQL参数处理IN子句中的数据?

Kib*_*bee 10 t-sql vb.net language-features sql-injection sql-server-2008

我们都知道准备好的语句是抵御SQL注入攻击的最好方法之一.使用"IN"子句创建预准备语句的最佳方法是什么.是否有一种简单的方法可以使用未指定数量的值来执行此操作?以下面的查询为例.

SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (1,2,3)
Run Code Online (Sandbox Code Playgroud)

目前我正在使用一个循环覆盖我的可能值来构建一个字符串,如.

SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (@IDVAL_1,@IDVAL_2,@IDVAL_3)
Run Code Online (Sandbox Code Playgroud)

是否可以使用只传递数组作为查询参数的值并使用如下查询?

SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (@IDArray)
Run Code Online (Sandbox Code Playgroud)

如果重要的是我在VB.Net中使用SQL Server 2000

dig*_*uru 5

在这里 - 首先创建以下功能...

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
Run Code Online (Sandbox Code Playgroud)

然后使用以下...

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

我认为sql server 2008将允许表函数.

UPDATE

您将使用以下语法挤出一些额外的性能......

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

因为先前的语法导致SQL Server使用"IN"子句运行额外的"排序"命令.另外 - 在我看来它看起来更好:D!


Dev*_*ris 1

如果您想传递一个数组,则需要 sql 中的一个函数来将该数组转换为子选择。

这些功能非常常见,大多数本土系统都利用它们。

大多数商业的,或者更确切地说,专业的 ORM 都是通过做一堆变量来完成的,所以如果你能做到这一点,我认为这是标准方法。