迭代的参数化查询

Posted

技术标签:

【中文标题】迭代的参数化查询【英文标题】:Parameterized queries on iteration 【发布时间】:2010-07-28 21:19:48 【问题描述】:

我正在将 Web 表单插入数据库,因此使用参数化查询。我有一个 CheckBoxList。如何迭代 CheckBoxList,为每个检查的事物(多对多)创建一个插入语句,并保持此参数化并一举执行?

我现在有这个:

string query = "INSERT INTO resources (url, submitted_by, author_name) VALUES (@url, @submitted_by, @author_name);";
foreach (ListItem li in CheckBoxList1.Items)
    
        if (li.Selected = true)
        
            query += "; INSERT INTO ";
        
    
    SqlCommand cmd = new SqlCommand(query, conn);
    cmd.Parameters.AddWithValue("@url", TextBox1.Text);
    cmd.Parameters.AddWithValue("@submitted_by", TextBox2.Text);
    cmd.Parameters.AddWithValue("@author_name", TextBox3.Text);

    try
    
        conn.Open();
        cmd.ExecuteNonQuery();
        Label1.Text = "Added to database.";
    

如您所见,它尚未完成。有什么建议吗?

【问题讨论】:

每个勾选的项目需要为一组url, submitted, author生成插入? @tzaman:不,每个选中的项目都需要创建一个这样的 INSERT 语句:INSERT INTO phones_resources (phone_id, resource_id) VALUES (@phone_id, @resource_id); 好的。那么,给定一个ListItem,你从哪里得到相关的phone_id, resource_id 啊,实际上我没有意识到 resource_id 会是第一次插入的结果,所以无论如何我都必须先执行那个。我想我只需要为这些创建一个独特的 SQLCommand。谢谢。 嗯,你还是可以一口气搞定所有的ListItem,我来写点东西。 【参考方案1】:

您可以使用 LINQ 为集合中的每个项目生成唯一的命名参数,然后在稍后添加关联的值:

var builder = new StringBuilder();
var listParams = CheckBoxList1.Items
                     .Where(li => li.Selected)
                     .Select(li, idx => new 
                     
                         PhoneString = String.Format("@phone_id0", idx),
                         PhoneValue = GetPhoneId(li),
                         ResourceString = String.Format("@resource_id0", idx),
                         ResourceValue = GetResourceId(li)
                     ;
foreach (var param in listParams)

    builder.AppendFormat("INSERT INTO phones_resources (phone_id, resource_id) 
                          VALUES (0, 1);", 
                          param.PhoneString, param.ResourceString);

SqlCommand cmd = new SqlCommand(builder.ToString(), conn);
foreach (var param in listParams)

    cmd.Parameters.AddWithValue(param.PhoneString, param.PhoneValue);
    cmd.Parameters.AddWithValue(param.ResourceString, param.ResourceValue);

我假设您有某种方法可以从任何给定的 ListItem 获取关联的 phone_id, resource_id - 您可以将其插入我放置占位符 Get___ 函数的位置。

注意:切换到StringBuilder - 这比使用重复的+= 构建字符串要好得多。

【讨论】:

谢谢。我正在使用 .NET 2.0,但我已经对其进行了调整以适应。我希望我不必以这种方式做事,但结果很好,在你的鼓励下也没有那么糟糕。 LINQ 语句是一个很好的参考,当我有机会使用较新的 .NET 框架(实际上可能是 Mono)时,我会尽量记住检查它。 @cookiecaper - 不客气!我自己最近也面临着类似的情况;我最终通过在SqlParameterCollection 上添加一个名为AddFromDict 的扩展方法来概括这种方法,该方法采用参数名称/值的Dictionary<string, object> 并将它们全部添加。所以现在我只填充一个parameters dict,然后调用cmd.Parameters.AddFromDict(parameters); :)

以上是关于迭代的参数化查询的主要内容,如果未能解决你的问题,请参考以下文章

UFT参数化

LoadRunner参数化功能详解

PDO 参数化与非参数化查询速度

JMeter笔记9 | JMeter参数化

参数个数错误(参数化查询)

什么是参数化查询?