C# SQL参数查询与in

发布于 2024-12-11 01:33:12 字数 828 浏览 1 评论 0原文

可能的重复:
参数化 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斯特凡

Possible Duplicate:
Parameterizing a SQL IN clause?

i have the follwing code:

var myCommand = new SqlCommand();
myCommand.Parameters.Add("@username", SqlDbType.NVarChar);
myCommand.Parameters["@username"].Value = username;
return _dbConnection.ExecuteQuery("Select * from customer where username = @username");

now i need to adapt the query for more values. I want to do something like this:

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");

Is that possible? How?

Thank you!

BR Stefan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

败给现实 2024-12-18 01:33:12

每个参数都需要是唯一的:

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 注入攻击的好处。

Each parameter needs to be unique:

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) + ")");

You will get sql like this:

SELECT * from customer where username in (@user0, @user1, @user2)

It doesn't help much from a query plan caching standpoint, but you will get the benefits of not being vulnerable to sql injection attacks.

兮子 2024-12-18 01:33:12

将代码改为这样

    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);

Change the code to this

    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);
宫墨修音 2024-12-18 01:33:12

我喜欢用两种方法来做这样的事情。

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();
    }
}

这只是为了给您一些想法。希望这会有所帮助。

I like to do stuff like this in two methods.

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();
    }
}

This is just to give you some ideas. Hopefully this will help.

爺獨霸怡葒院 2024-12-18 01:33:12

这可以通过将 XML 数据类型传递给查询并在其中搜索来完成。

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))");

但是,语法可能需要检查

This could be done by passing an XML data type to the Query and searching within that.

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)

So in this instance you could do:

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))");

However, syntax may need checking

不必在意 2024-12-18 01:33:12

您无法完全按照循环的方式进行操作,因为您将使用不同的值多次添加相同的参数,但这可能会有所帮助:

http://support.microsoft.com/kb/555266 (它是用 VB 编写的,但你可能可以找到 c# 示例或翻译)

我自己解决这个问题的方法是将其放入存储过程中只是好的实践(例如增加安全性、效率、代码重用等好处),然后让您的过程接受 XML 参数。在您的 C# 应用程序中,将 Usernames 集合转换为 XML,然后将其传递到 SP。

You cant do it exactly the way you are thinking with the loop because you would be adding the same parameter multiple times with different values, however this may be helpful:

http://support.microsoft.com/kb/555266 (its in VB but you can probably find a c# example or translate)

The way I would solve this myself is to make this into a stored procedure as its just good practice (benefits such as added security, efficiency, code reuse etc), then have your procedure accept a parameter of XML. In your C# application convert the Usernames collection to XML then pass that into the SP.

随波逐流 2024-12-18 01:33:12

好吧,如果你真的愿意,你可以完全通过字符串操作来做到这一点。

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# 构建查询,可以使用以下方法。我用这个方法取得了成功。

Well, if you really want to you could do this entirely through string manipulation.

string sql = "Select * from customer where username in (";

string comma = "";
foreach(string s in usernames)
{
   sql += comma + "'" + CleanSqlParameter(s) + "'";
   comma = ", ";
}

return _dbConnection.ExecuteQuery(sql);

This would be messy! But if you feel like you need to construct the query entirely in C#, here's a way to do it. I've had success with this method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文