【问题标题】:How can I run two SQL commands with a single connection?如何通过单个连接运行两个 SQL 命令?
【发布时间】:2020-04-29 17:40:54
【问题描述】:

我需要在一个表中插入数据并使用添加按钮更新第二个表中的 id:

private void addButton_Click(object sender, EventArgs e)
{
    con.Open();
    cmd = new SqlCommand("Insert Into Rent(toolId, customerId, custName, Fee, date, dueDate) Values('" + toolIdComboBx.Text + "', '" + custIdTxtBx.Text + "', '" + custNameTxtBx.Text + "', '" + feeTxtBx.Text + "', '" + dateTimePicker2.Text + "', '" + dateTimePicker1.Text + "')", con);

    dr = cmd.ExecuteReader();

    if (dr.Read())
    {
        con.Close();
        con.Open();

        cmd = new SqlCommand("Update Inventory Set Available = 'No' Where ToolId =  = '" + toolIdComboBx.Text + "' ");

        cmd.ExecuteNonQuery();
    }

    con.Close();
    DisplayData();
}

【问题讨论】:

  • 如果您发布您遇到的任何错误或解释意外行为,这总是有帮助的。另外,请格式化您的代码,以便它实际上是可读的,并且所有这些都是神圣的请 parameterize your queries!!.
  • 您应该只将 ExecuteReader 与 SELECT 一起使用。更新和插入都应该使用 ExecuteNonQuery
  • 您希望通过从 INSERT 检查 dr.Read() 的结果来完成什么?如果插入了一行,您是否只尝试更新?代码的意图不是很清楚。
  • 学习参数化你的 sql 语句 - 以你使用的方式连接对 sql 注入开放。
  • 我想建议使用实体框架。使用它,您将拥有更大的灵活性。

标签: c# sql-server sqlconnection sqlcommand


【解决方案1】:

我可以在这里看到一些问题

  1. 永远、永远、永远使用参数化查询(@broots-waymb 的属性),永远永远不会将用户输入连接到 SQL 命令中
  2. 使用 using 关键字通过 Dispose() 方法自动清理任何对象,其中包括 SqlConnection 和 SqlCommand - 这可确保在出现异常时正确清理;也更容易正确书写
  3. 如果您不希望返回记录集,请使用ExecuteNonQuery()。正如@jdweng 指出的那样,返回记录集的唯一查询是 SELECT 语句(存储过程也可能)。 Read() 的意思是这段代码不清楚,我的猜测是它总是会返回false
  4. 当您的数据库架构包含一个表 (Inventory),其状态依赖于另一表 (Rent) 的状态时,请务必小心。考虑避免这种情况的策略,但如果不能,则应考虑将更新包装到数据库事务中的两个表,以确保系统状态一致

【讨论】:

    【解决方案2】:

    如果连接有一个打开的SqlDataReader,则不能关闭它。

    您为什么阅读INSERT 声明?你期待什么?

    另外,使用参数化查询。

    更新

    INSERT 没有结果值,因此请改用ExecuteNonQuery()。这样,连接就可用于下一个SqlCommand

    【讨论】:

    • 我想在插入完成后更新Inventory表中的Available列
    【解决方案3】:

    谢谢各位!我想通了

    con.Open();

            using (cmd = new SqlCommand("Insert Into Rent(toolId, customerId, custName, 
    

    费用、日期、dueDate) Values('" + toolIdComboBx.Text + "', '" + custIdTxtBx.Text + "', '" +

    custNameTxtBx.Text + "', '" + feeTxtBx.Text + "', '" + dateTimePicker2.Text + "', '" +

    dateTimePicker1.Text + "')", con))

            {
                cmd.ExecuteNonQuery();
            }
    
            using (cmd = new SqlCommand("Update Inventory Set Available = 'No' Where ToolId  = '" + toolIdComboBx.Text + "' ", con))
    
            {
                cmd.ExecuteNonQuery();
            };
    
            con.Close();
    
            DisplayData();
    

    【讨论】:

    • 在使用这样嵌入的文本时要注意。通过不使用参数,您正在为 SQL 注入攻击敞开大门。用户可以在您的文本框中输入“' OR 1=1”并更新所有行。正确的方法是使用参数。 "WHERE ToolId = @ToolId" 和 cmd.Parameters.AddWithValue("@ToolId", toolIdComboBx.Text)
    猜你喜欢
    • 2012-11-20
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2015-02-23
    • 2017-09-08
    相关资源
    最近更新 更多