【问题标题】:Simultaneously Insert Multiple Rows Into Database同时将多行插入数据库
【发布时间】:2011-08-31 00:44:23
【问题描述】:

每个调查都有多个问题 (10),每个问题都有自己的评分。目前我只能为每个问题一次插入一个评分。我正在尝试创建一个表单,以便我可以同时为每个问题添加评分。

我遇到的问题是表单只输入第一个问题的评分,并在第二个实例中遇到错误:'throw new ApplicationException("Data error.");'

每个问题都需要保留选定的调查 ID,以识别它属于哪个调查。

===== 代码背后=====

        protected void AddRatingBTN_Click(object sender, EventArgs e)
        {

            if (DropDownListSurvey.SelectedValue == "Select")
            {
                //Label1.Text = "hi";
                return;
            }

            string connectionString = WebConfigurationManager.ConnectionStrings["DBConnectionString1"].ConnectionString;


            SqlConnection con = new SqlConnection(connectionString);
            SqlCommand cmd = new SqlCommand("InsertRating", con);
            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.Add(new SqlParameter("@Rating_ID", SqlDbType.Int, 7));
            cmd.Parameters["@Rating_ID"].Direction = ParameterDirection.Output;


            cmd.Parameters.Add(new SqlParameter("@Question_ID", SqlDbType.Int));
            cmd.Parameters["@Question_ID"].Value = 1000;

            cmd.Parameters.Add(new SqlParameter("@Survey_ID", SqlDbType.Int));
            cmd.Parameters["@Survey_ID"].Value = Convert.ToInt32(DropDownListSurvey.SelectedValue.ToString());

            cmd.Parameters.Add(new SqlParameter("@Score", SqlDbType.Char, 5));
            cmd.Parameters["@Score"].Value = Question_1.Text;

            try
            {
                con.Open();
                cmd.ExecuteNonQuery();
               // txtRating_ID.Text = Convert.ToString(cmd.Parameters["@Rating_ID"].Value);

            }
            catch (SqlException err)
            {
                // Replace the error with something less specific.
                // You could also log the error now.
                throw new ApplicationException("Data error.");
            }
            finally
            {
                con.Close();
            }

            cmd.Parameters.Add(new SqlParameter("@Rating_ID", SqlDbType.Int, 7));
            cmd.Parameters["@Rating_ID"].Direction = ParameterDirection.Output;

            cmd.Parameters.Add(new SqlParameter("@Question_ID", SqlDbType.Int));
            cmd.Parameters["@Question_ID"].Value = 1001;

            cmd.Parameters.Add(new SqlParameter("@Score", SqlDbType.Char, 5));
            cmd.Parameters["@Score"].Value = Question_2.Text;

            try
            {
                con.Open();
                cmd.ExecuteNonQuery();
                // txtRating_ID.Text = Convert.ToString(cmd.Parameters["@Rating_ID"].Value);

            }
            catch (SqlException err)
            {
                // Replace the error with something less specific.
                // You could also log the error now.
                throw new ApplicationException("Data error.");
            }
            finally
            {
                con.Close();
            }

            cmd.Parameters.Add(new SqlParameter("@Rating_ID", SqlDbType.Int, 7));
            cmd.Parameters["@Rating_ID"].Direction = ParameterDirection.Output;

            cmd.Parameters.Add(new SqlParameter("@Question_ID", SqlDbType.Int));
            cmd.Parameters["@Question_ID"].Value = 1002;

            cmd.Parameters.Add(new SqlParameter("@Score", SqlDbType.Char, 5));
            cmd.Parameters["@Score"].Value = Question_3.Text;

            try
            {
                con.Open();
                cmd.ExecuteNonQuery();
                // txtRating_ID.Text = Convert.ToString(cmd.Parameters["@Rating_ID"].Value);

            }
            catch (SqlException err)
            {
                // Replace the error with something less specific.
                // You could also log the error now.
                throw new ApplicationException("Data error.");
            }
            finally
            {
                Response.Redirect(Request.RawUrl);
                con.Close();
            }
        }
    }
}

【问题讨论】:

  • 代码太不干了,原则上我会拒绝回答...

标签: c# asp.net sql ms-access


【解决方案1】:

这段代码带回了一些旧的记忆,不幸的是不是很好的记忆。无论如何,我认为问题在于您将参数多次添加到同一个命令对象。您的第一次执行有效,因为您拥有正确数量的参数。在准备第二次运行时,您再次添加它们,但 cmd 仍然有旧参数。如果您在第一次之后删除 .Add 调用,它应该可以工作。

您应该研究更现代的方式来处理数据访问。至少检查一下 LINQ-to-SQL。

我还将添加一些设计指南。根据您保存的数据,您可能希望将插入包装在单个事务中,这非常简单。您还应该避免关闭和重新打开语句之间的连接(无论如何这在有用的事务中是不可能的)。您只需要在第一次调用时打开连接,并在最后一次调用后关闭。最后,你应该把最后一个 close 放在 Redirect 之前,因为 Redirect(string) 会中止线程。

【讨论】:

  • 成功了!让我直截了当地说,'cmd.Parameters.Add' 是在表中添加参数(列),而 cmd.Parameter 是添加要插入的变量?如:INSERT INTO Table_1 (Parameter_1, Parameter_2) 值('Variable_1', 'Variable_2')。
  • 有点像。调用 .Add 会向 Parameter 集合添加一个 Parameter,该集合基本上是一个在存储过程调用期间被检查的数组。默认情况下,它在您使用的版本中没有任何价值,因此您必须使用以下行进行设置。该元素不会消失,因此每次执行命令时都会发送它。由于它仍然存在,您可以通过拉出该参数并更改其值来更改值。
【解决方案2】:

如果你的数据库支持,你可以使用

INSERT INTO tablename(field1,field2) VALUES(
 SELECT value1, value2
 UNION ALL
 SELECT value1, value2
 ...
 )

您可以考虑以下想法:

DbTransaction trans = null;
trans = Con.BeginTransaction();
cmd.Transaction = trans;
... // execute your individual insert statements
cmd.ExecuteNonQuery();
trans.Commit();

万一出错

trans.RollBack();

【讨论】:

    【解决方案3】:

    有很多方法可以实现你的目标,这篇文章有几个例子:

    Multiple Ways to do Multiple Inserts

    【讨论】:

      【解决方案4】:

      我做了一些与您的问题类似的工作,但我在数据库本身中使用了存储过程。我所做的是设置问卷主模板。例如,每个调查有 20 个问题,用户必须从每个问题的 1 到 4 中选择一个评分。所以我有两张桌子。

      表格

      Header (SurveyID, ...) 
      
      Detail (SurveyID, LineID, AnswerID, ...) 
      

      然后我创建一个存储过程。调用此过程时,它将使用

      将数据从模板复制到事务表
      CREATE PROC ....
      AS
      
      BEGIN TRAN 
      INSERT INTO DETAIL
      (...) 
      SELECT ... FROM Master_Detail
      
      INSERT INTO HEADER
      (...) 
      SELECT ... FROM Master_Header
      COMMIT TRAN
      

      我在标题和细节之间也有外键链接。希望这能有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-13
        • 2021-08-24
        • 1970-01-01
        • 1970-01-01
        • 2018-09-10
        相关资源
        最近更新 更多