中带有的C#SQL参数查询
本文关键字:参数 查询 C#SQL | 更新日期: 2023-09-27 18:12:05
可能重复:
参数化SQL IN子句?
我有以下代码:
var myCommand = new SqlCommand();
myCommand.Parameters.Add("@username", SqlDbType.NVarChar);
myCommand.Parameters["@username"].Value = username;
return _dbConnection.ExecuteQuery("Select * from customer where username = @username");
现在我需要调整查询以获得更多值。我想做这样的事情:
var myCommand = new SqlCommand();
foreach (string username in usernames){
myCommand.Parameters.Add("@username", SqlDbType.NVarChar);
myCommand.Parameters["@username"].Value = username;
}
return _dbConnection.ExecuteQuery("Select * from customer where username in @username");
这可能吗?怎样
谢谢!
BR Stefan
每个参数都必须是唯一的:
var paramNames = new List<string>();
var myCommand = new SqlCommand();
foreach (string username in usernames){
var paramName = "@user" + paramNames.Count;
myCommand.Parameters.Add(paramName, SqlDbType.NVarChar);
myCommand.Parameters[paramName].Value = username;
paramNames.Add(paramName);
}
return _dbConnection.ExecuteQuery("Select * from customer where username in (" + string.Join(",", paramNames) + ")");
你会得到这样的sql:
SELECT * from customer where username in (@user0, @user1, @user2)
从查询计划缓存的角度来看,这并没有多大帮助,但您将获得不易受到sql注入攻击的好处。
将代码更改为此
var myCommand = new SqlCommand();
int i = 0;
string param = string.Empty;
foreach (string username in usernames)
{
string paramName = string.Format("@username{0}", i);
myCommand.Parameters.Add(paramName, SqlDbType.NVarChar);
myCommand.Parameters[paramName].Value = username;
param += string.Format(" (username={0}) or", paramName);
i++;
}
param = param.Substring(0, param.Length - 2);
return _dbConnection.ExecuteQuery("Select * from customer where " + param);
我喜欢用两种方法做这样的事情。
public void ReadDatabase(string[] values)
{
foreach (var value in values)
{
using (var rd = GetData(value))
{
if (!rd.Read())
throw new OMGException("FAILED!");
Console.WriteLine(rd["UserId"].ToString());
}
}
}
public IDataReader GetData(string value)
{
using(var cm = _connectionWhatever.CreateCommand())
{
cm.CommandText = @"
Select UserId
From MyTable
Where UserName = @User
";
cm.CommandType = CommandType.Text;
cm.Parameters.AddWithValue("User", value);
return cm.ExecuteReader();
}
}
这只是给你一些想法。希望这会有所帮助。
这可以通过将XML数据类型传递给Query并在其中进行搜索来实现。
declare @x xml
set @x = '<IDs><ID>1</ID><ID>2</ID></IDs>'
SELECT ID.value('.', 'int') AS ID
FROM @x.nodes('/IDs/ID') as IDS(ID)
所以在这种情况下,你可以做:
var myCommand = new SqlCommand();
myCommand.Parameters.Add("@usernames", SqlDbType.Xml);
string usernames = "<Usernames>"
foreach (string username in usernames){
usernames+= String.Format("<username>{0}</username>", username);
}
usernames += "</Usernames>"
myCommand.Parameters["@usernames"].Value = usernames;
return _dbConnection.ExecuteQuery("Select * from customer where username in (SELECT
username.value('.', 'nvarchar') AS Username
FROM @x.nodes('/Usernames/Username') as Usernames(Username))");
但是,语法可能需要检查
你不能完全按照你对循环的想法来做,因为你会用不同的值多次添加同一个参数,但这可能会有所帮助:
http://support.microsoft.com/kb/555266(它在VB中,但你可能会找到一个c#示例或翻译(
我自己解决这个问题的方法是将其作为一种良好的做法(如增加安全性、效率、代码重用等(,将其作为存储过程,然后让您的过程接受XML参数。在C#应用程序中,将Usernames集合转换为XML,然后将其传递到SP中。
如果你真的想这样做,你可以完全通过字符串操作来完成。
string sql = "Select * from customer where username in (";
string comma = "";
foreach(string s in usernames)
{
sql += comma + "'" + CleanSqlParameter(s) + "'";
comma = ", ";
}
return _dbConnection.ExecuteQuery(sql);
这会很乱!但是,如果你觉得你需要完全用C#构建查询,这里有一种方法。我已经成功地使用了这种方法。