即使出现错误也执行插入

时间:2018-06-05 21:55:43

标签: c# asp.net

我从文本框和gridview中将数据插入到2个表中;但是,当我收到错误时,数据仍然被插入其中一个表中。我想要的是,一旦我收到错误,那么数据就不应该插入。

using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
    using (SqlCommand cmd = new SqlCommand("PP_CreateSheet", connection))
    {
        cmd.CommandType = CommandType.StoredProcedure;

        foreach (DataRow dr in dt.Rows)
        {
            cmd.Parameters.AddWithValue("@loadSheetNum", lblSheet.Text);
            cmd.Parameters.AddWithValue("@invoiceNum", dr["Invoice #"]);
            cmd.Parameters.AddWithValue("@invoiceQty", dr["Invoice Qty"]);
            cmd.Parameters.AddWithValue("@custName", dr["Customer Name"]);
            cmd.Parameters.AddWithValue("@invoiceWeight", dr["Total Invoice Weight"]);
            cmd.Parameters.Add("@status", SqlDbType.NVarChar).Value = 1;
        }
        cmd.ExecuteNonQuery();
    }
    using (SqlCommand comm = new SqlCommand("PP_CreateNumber", connection))
    {
        for (int i = 0; i < ContentPlaceHolder1.Controls.Count; i++)
        {

            Control ctrl = ContentPlaceHolder1.Controls[i];
            if (ctrl is TextBox)
            {
                TextBox txt = (TextBox)ctrl;

                //txt.TextMode = System.Web.UI.WebControls.TextBoxMode.Number;
                value = txt.Text;
                int parsedValue;
                if (!int.TryParse(value, out parsedValue))
                {
                    lblError.Text = "Please enter only numeric values for number";
                    return;
                }
                else
                {
                    comm.CommandType = CommandType.StoredProcedure;

                    comm.Parameters.AddWithValue("@loadSheetNum", lblSheet.Text);
                    comm.Parameters.Add("@Number", SqlDbType.NVarChar).Value = value;
                }
            }
            comm.ExecuteNonQuery();
        }
    }
}

2 个答案:

答案 0 :(得分:2)

您的代码中存在许多问题。第一个是for循环中的AddWithValue。通过这种方式,您可以在每个循环中继续向命令添加参数,但只会使用存储过程所需的第一组参数,从而在每个循环中插入相同的值。

所以你应该改变两个循环来以这种方式处理参数:

using (SqlConnection connection = new SqlConnection(...))
{
    connection.Open();
    using (SqlCommand cmd = new SqlCommand("PP_CreateSheet", connection))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("@loadSheetNum", SqlDbType.NVarChar);
        ... add all the other parameters, but don't give them a value
        foreach (DataRow dr in dt.Rows)
        {
            cmd.Parameters["@loadSheetNum"].Value = lblSheet.Text; 
            ... set the value to all other parameters
            cmd.ExecuteNonQuery();
        }
    }

您应该对其他命令执行相同操作,但是当您确定要插入的值时,请立即调用ExecuteNonQuery

using (SqlCommand comm = new SqlCommand("PP_CreateNumber", connection))
{
      comm.CommandType = CommandType.StoredProcedure;
      // This never changes inside the loop so keep it outside
      comm.Parameters.Add("@loadSheetNum", SqlDbType.NVarChar).Value = lblSheet.Text);

      // This changes inside the loop so set the value inside the loop
      comm.Parameters.Add("@Number", SqlDbType.NVarChar)
      for (int i = 0; i < ContentPlaceHolder1.Controls.Count; i++)
      {
            Control ctrl = ContentPlaceHolder1.Controls[i];
            if (ctrl is TextBox)
            {
                TextBox txt = (TextBox)ctrl;
                value = txt.Text;
                int parsedValue;
                if (!int.TryParse(value, out parsedValue))
                {
                    lblError.Text = "Please enter only numeric values for number";
                    return;
                }
                else
                {
                     comm.Parameters["@Number"] = value;
                     comm.ExecuteNonQuery();
                }
           }
      }
}

如果您的输入中包含无效数字,则需要知道是否要避免使用整个插入代码。在这种情况下,您需要对插入应用事务并在出现错误时确认或回滚插入

只需添加此

即可
using (SqlConnection connection = new SqlConnection(...))
{
    connection.Open();
    using (SqlTransaction ts = connection.BeginTransaction())
    {
        using (SqlCommand cmd = new SqlCommand("PP_CreateSheet", connection, ts))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            .......
        }
        using (SqlCommand comm = new SqlCommand("PP_CreateNumber", connection, ts))
        {
            .....
            if (!int.TryParse(value, out parsedValue))
            {
                lblError.Text = "Please enter only numeric values for number";
                 ts.Rollback();
                 return;
            }
            .....
        }
        // Before exiting from the SqlConnection using block call the 
        ts.Confirm();
    }
}

答案 1 :(得分:0)

当你的第二个命令通过使用交易出现问题时,你可以完成不从第一个命令提交更改。

以下是一个例子:

using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
    connection.Open();
    using (SqlTransaction transaction = connection.BeginTransaction())
    {
        using (SqlCommand cmd = new SqlCommand("PP_CreateSheet", connection, transaction))
        {
            // First command
        }
        using (SqlCommand comm = new SqlCommand("PP_CreateNumber", connection, transaction))
        {
            // Second command
            // .. omitted
            if(!int.TryParse(value, out parsedValue)){
                lblError.Text = "Please enter only numeric values for number";
                return; // Since we haven't committed the transaction, it will be rolled back when disposed.
            }
            // .. omitted
        }
        transaction.Commit(); // Both commands execute without error, commit the transaction.
    }
}