【问题标题】:Pass string array as parameter in SQL query in C# [duplicate]在 C# 中的 SQL 查询中传递字符串数组作为参数 [重复]
【发布时间】:2014-01-11 10:30:56
【问题描述】:

在我用 C# 编写的应用程序中,我正在编写一个 SQL 查询。以下是查询

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

@resources 是具有一个或多个字符串的用户输入参数。

我的查询失败没有显示错误

据我说,查询失败是因为在@resources 中传递了以下参数

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

(开头和结尾有 2 个引号,我的查询失败了)。

[Resource No_] 在数据库中属于NVARCHAR 类型。

在谷歌搜索之后,我找到了一些关于这个主题的帮助,但是当 [Resource No_] 的类型为 Integer 时,所有这些都适用

【问题讨论】:

  • 向我们展示您是如何创建此查询的。
  • 不可能创建动态字符串,因为我不知道用户传递的参数数量。
  • @Simon Whitehead :: SqlCommand cmd = new SqlCommand (SELECT [Resource No_] where [Resource No_] In (@resources) , conn)

标签: c# sql-server sqlcommand sqlcommandbuilder


【解决方案1】:

虽然我不同意“重复问题”的选定答案(或许多棘手的答案),但here is an answer to it 显示的方法与我的以下建议非常相似。

(我已投票决定将此问题作为重复问题结束,因为有这样的答案,即使被埋没了。)


只有一个 SQL 值可以绑定到任何给定的占位符。

虽然有办法将所有数据作为“一个值”发送,但我建议动态创建 占位符:它简单、干净,并且在大多数情况下都能可靠地工作。

考虑一下:

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++;
}

【讨论】:

  • 这不是问题。你的答案是如何创建一个新的 SQL 语句;当你有几千个条目时不好。
  • @fcm 我不认为你理解答案,这是关于当你有未知数量的参数时如何参数化查询。
【解决方案2】:

使用用户定义的表类型来接受您的参数,然后在您的选择中使用 JOIN 子句来限制结果集。见http://social.msdn.microsoft.com/Forums/en-US/2f466c93-43cd-436d-8a7c-e458feae71a0/how-to-use-user-defined-table-types

【讨论】:

    【解决方案3】:

    做类似的事情

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

    并在一个字符串中传递列表。

    【讨论】:

      猜你喜欢
      • 2017-11-19
      • 2018-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-27
      • 2022-11-01
      • 1970-01-01
      相关资源
      最近更新 更多