首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在SqlCommand中传递数组参数

在SqlCommand中传递数组参数
EN

Stack Overflow用户
提问于 2010-03-04 15:28:10
回答 7查看 169.1K关注 0票数 167

我尝试将数组参数传递给C#中的SQL commnd,如下所示,但它不起作用。以前有人见过它吗?

代码语言:javascript
复制
string sqlCommand = "SELECT * from TableA WHERE Age IN (@Age)";
SqlConnection sqlCon = new SqlConnection(connectString);
SqlCommand sqlComm = new SqlCommand();
sqlComm.Connection = sqlCon;
sqlComm.CommandType = System.Data.CommandType.Text;
sqlComm.CommandText = sqlCommand;
sqlComm.CommandTimeout = 300;
sqlComm.Parameters.Add("@Age", SqlDbType.NVarChar);
StringBuilder sb = new StringBuilder();
foreach (ListItem item in ddlAge.Items)
{
     if (item.Selected)
     {
         sb.Append(item.Text + ",");
     }
}

sqlComm.Parameters["@Age"].Value = sb.ToString().TrimEnd(',');
EN

回答 7

Stack Overflow用户

发布于 2015-09-04 19:20:15

如果您使用的是MS SQL Server2008及更高版本,则可以使用此处所述的表值参数http://www.sommarskog.se/arrays-in-sql-2008.html

1.为要使用的每个参数类型创建一个表类型

以下命令为整数创建一个表类型:

代码语言:javascript
复制
create type int32_id_list as table (id int not null primary key)

2.实现帮助器方法

代码语言:javascript
复制
public static SqlCommand AddParameter<T>(this SqlCommand command, string name, IEnumerable<T> ids)
{
  var parameter = command.CreateParameter();      

  parameter.ParameterName = name;
  parameter.TypeName = typeof(T).Name.ToLowerInvariant() + "_id_list";
  parameter.SqlDbType = SqlDbType.Structured;
  parameter.Direction = ParameterDirection.Input;

  parameter.Value = CreateIdList(ids);

  command.Parameters.Add(parameter);
  return command;
}

private static DataTable CreateIdList<T>(IEnumerable<T> ids)
{
  var table = new DataTable();
  table.Columns.Add("id", typeof (T));

  foreach (var id in ids)
  {
    table.Rows.Add(id);
  }

  return table;
}

3.像这样使用它

代码语言:javascript
复制
cmd.CommandText = "select * from TableA where Age in (select id from @age)"; 
cmd.AddParameter("@age", new [] {1,2,3,4,5});
票数 20
EN

Stack Overflow用户

发布于 2018-12-14 21:18:30

我想提出另一种方法,如何用IN运算符解决限制。

例如,我们有以下查询

代码语言:javascript
复制
select *
from Users U
WHERE U.ID in (@ids)

我们想要传递几个ID来过滤用户。不幸的是,用C#不可能以简单的方式做到这一点。但是我已经通过使用"string_split“函数找到了解决方法。我们需要将我们的查询重写为以下内容。

代码语言:javascript
复制
declare @ids nvarchar(max) = '1,2,3'

SELECT *
FROM Users as U
CROSS APPLY string_split(@ids, ',') as UIDS
WHERE U.ID = UIDS.value

现在我们可以很容易地传递逗号分隔的值的一个参数枚举。

票数 6
EN

Stack Overflow用户

发布于 2018-01-17 03:55:53

由于查询将采用WHERE Age IN ("11, 13, 14, 16")的形式,因此将项目数组作为折叠参数传递给WHERE..IN子句将失败。

但是您可以将参数作为序列化为XML或JSON的数组进行传递:

使用nodes()方法:

代码语言:javascript
复制
StringBuilder sb = new StringBuilder();

foreach (ListItem item in ddlAge.Items)
  if (item.Selected)
    sb.Append("<age>" + item.Text + "</age>"); // actually it's xml-ish

sqlComm.CommandText = @"SELECT * from TableA WHERE Age IN (
    SELECT Tab.col.value('.', 'int') as Age from @Ages.nodes('/age') as Tab(col))";
sqlComm.Parameters.Add("@Ages", SqlDbType.NVarChar);
sqlComm.Parameters["@Ages"].Value = sb.ToString();

使用OPENXML方法:

代码语言:javascript
复制
using System.Xml.Linq;
...
XElement xml = new XElement("Ages");

foreach (ListItem item in ddlAge.Items)
  if (item.Selected)
    xml.Add(new XElement("age", item.Text);

sqlComm.CommandText = @"DECLARE @idoc int;
    EXEC sp_xml_preparedocument @idoc OUTPUT, @Ages;
    SELECT * from TableA WHERE Age IN (
    SELECT Age from OPENXML(@idoc, '/Ages/age') with (Age int 'text()')
    EXEC sp_xml_removedocument @idoc";
sqlComm.Parameters.Add("@Ages", SqlDbType.Xml);
sqlComm.Parameters["@Ages"].Value = xml.ToString();

这在SQL端要多一点,并且您需要一个适当的XML (带根)。

使用OPENJSON方法(SQL Server 2016+):

代码语言:javascript
复制
using Newtonsoft.Json;
...
List<string> ages = new List<string>();

foreach (ListItem item in ddlAge.Items)
  if (item.Selected)
    ages.Add(item.Text);

sqlComm.CommandText = @"SELECT * from TableA WHERE Age IN (
    select value from OPENJSON(@Ages))";
sqlComm.Parameters.Add("@Ages", SqlDbType.NVarChar);
sqlComm.Parameters["@Ages"].Value = JsonConvert.SerializeObject(ages);

请注意,对于最后一种方法,您还需要具有130+的兼容级别。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2377506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档