10

プリペアド ステートメントが SQL インジェクション攻撃を防御する最良の方法の 1 つであることは誰もが知っています。「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)

重要な場合は、VB.Net で SQL Server 2000 を使用しています。

4

6 に答える 6

6

どうぞ - 最初に次の関数を作成してください...

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 ではテーブル関数が許可されると思います。

アップデート

次の構文を使用して、パフォーマンスをさらに向上させます...

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

前の構文では、SQL Server が "IN" 句を使用して追加の "Sort" コマンドを実行するためです。さらに、私の意見では、見た目が良くなります:D!

于 2008-09-18T14:49:03.470 に答える
1

配列を渡したい場合は、その配列を副選択に変えることができる SQL の関数が必要になります。

これらの機能は非常に一般的であり、ほとんどの自作システムがそれらを利用しています。

ほとんどの商用、またはむしろプロの ORM は、一連の変数を実行することで機能します。そのため、それが機能している場合、それが標準的な方法だと思います。

于 2008-09-18T14:43:08.213 に答える
0

単一の列 VALUE を持つ一時テーブル TempTable を作成し、すべての ID を挿入できます。次に、サブセレクトでそれを行うことができます:

SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (SELECT VALUE FROM TempTable)
于 2008-09-18T21:47:04.980 に答える
0

digiguru によって投稿されたソリューションを使用してください。これは再利用可能な優れたソリューションであり、同じ手法も使用しています。新しいチーム メンバーは、時間を節約し、ストアド プロシージャの一貫性を維持できるため、気に入っています。このソリューションは、レコードセットを作成するためにストアド プロシージャに渡されるパラメーターが varchar(8000) で渡されるため、SQL レポートでもうまく機能します。接続するだけです。

于 2008-09-28T02:18:31.520 に答える
-1

SQL Server 2008 では、新しい「テーブル」データ型を追加することで、この古典的な問題に対処することができました。どうやら、これにより値の配列を渡すことができ、サブセレクトで使用して IN ステートメントと同じことを実現できます。

SQL Server 2008 を使用している場合は、それを調べることができます。

于 2008-09-18T14:46:51.790 に答える
-2

これが私が使用する1つのテクニックです

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)
于 2008-09-18T14:49:51.723 に答える