中带有的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

中带有的C#SQL参数查询

每个参数都必须是唯一的:

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#构建查询,这里有一种方法。我已经成功地使用了这种方法。