我尝试将数组参数传递给C#中的SQL commnd,如下所示,但它不起作用。以前有人见过它吗?
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(',');
发布于 2015-09-04 19:20:15
如果您使用的是MS SQL Server2008及更高版本,则可以使用此处所述的表值参数http://www.sommarskog.se/arrays-in-sql-2008.html。
1.为要使用的每个参数类型创建一个表类型
以下命令为整数创建一个表类型:
create type int32_id_list as table (id int not null primary key)
2.实现帮助器方法
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.像这样使用它
cmd.CommandText = "select * from TableA where Age in (select id from @age)";
cmd.AddParameter("@age", new [] {1,2,3,4,5});
发布于 2018-12-14 21:18:30
我想提出另一种方法,如何用IN运算符解决限制。
例如,我们有以下查询
select *
from Users U
WHERE U.ID in (@ids)
我们想要传递几个ID来过滤用户。不幸的是,用C#不可能以简单的方式做到这一点。但是我已经通过使用"string_split“函数找到了解决方法。我们需要将我们的查询重写为以下内容。
declare @ids nvarchar(max) = '1,2,3'
SELECT *
FROM Users as U
CROSS APPLY string_split(@ids, ',') as UIDS
WHERE U.ID = UIDS.value
现在我们可以很容易地传递逗号分隔的值的一个参数枚举。
发布于 2018-01-17 03:55:53
由于查询将采用WHERE Age IN ("11, 13, 14, 16")
的形式,因此将项目数组作为折叠参数传递给WHERE..IN子句将失败。
但是您可以将参数作为序列化为XML或JSON的数组进行传递:
使用nodes()
方法:
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
方法:
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+):
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+的兼容级别。
https://stackoverflow.com/questions/2377506
复制相似问题