2

C# で記述されたアプリケーションで、SQL クエリを記述しています。以下はクエリです

SELECT [Resource No_] where [Resource No_] In (@resources) 

@resourcesその文字列を 1 つ以上持つユーザー入力パラメータです。

エラーが表示されずにクエリが失敗する

私によると、@resources次のパラメーターが渡されているため、クエリが失敗しています

"'123,'124','125'"

(最初と最後に 2 つの逆コンマがあり、クエリに失敗しています)。

[Resource No_]NVARCHARはデータベースの型です。

[Resource No_] グーグルの後、このトピックに関するいくつかのヘルプを見つけましたが、タイプの場合はすべて適用できますInteger

4

3 に答える 3

5

「重複した質問」に対して選択された回答(またはトリッキーな回答の多く)には同意しませんが、次の推奨事項と非常によく似たアプローチを示す回答を次に示します。

(埋もれていたとしても、そのような回答があるため、この質問を重複として閉じることに投票しました。)


特定のプレースホルダーにバインドできるSQL 値は1 つだけです。

すべてのデータを「1 つの値」として送信する方法はありますが、プレースホルダーを動的に作成することをお勧めします。これはシンプルでクリーンで、ほとんどの場合確実に機能します。

このことを考慮:

ICollection<string> resources = GetResources();

if (!resources.Any()) {
    // "[Resource No_] IN ()" doesn't make sense
    throw new Exception("Whoops, have to use different query!");
}

// If there is 1 resource, the result would be "@res0" ..
// If there were 3 resources, the result would be "@res0,@res1,@res2" .. etc
var resourceParams = string.Join(",",
    resources.Select((r, i) => "@res" + i));

// This is NOT vulnerable to classic SQL Injection because resourceParams
// does NOT contain user data; only the parameter names.
// However, a large number of items in resources could result in degenerate
// or "too many parameter" queries so limit guards should be used.
var sql = string.Format("SELECT [Resource No_] where [Resource No_] In ({0})",
    resourceParams);

var cmd = conn.CreateCommand();
cmd.CommandText = sql;

// Assign values to placeholders, using the same naming scheme.
// Parameters prevent SQL Injection (accidental or malicious).
int i = 0;
foreach (var r in resources) {
   cmd.Parameters.AddWithValue("@res" + i, r);
   i++;
}
于 2013-12-23T08:40:06.590 に答える
1

ユーザー定義のテーブル タイプを使用してパラメータを受け入れ、次に選択で JOIN 句を使用して結果セットを制限します。http://social.msdn.microsoft.com/Forums/en-US/2f466c93-43cd-436d-8a7c-e458feae71a0/how-to-use-user-defined-table-typesを参照してください。

于 2013-12-23T08:33:40.830 に答える
0

次のようなことをします

resources.Aggregate(r1, r2 => r1 + "', '" + r2 + "'") 

リストを 1 つの文字列で渡します。

于 2013-12-23T08:35:31.563 に答える