1

我正在尝试使用具有两个表的存储过程插入数据。第一个表是通过文本框的数据,第二个数据是通过我存储在数据库中并传递以插入的网格。问题是当读取数据表并插入它时说有太多的参数恰好添加到 for 循环中。有什么建议如何作为 SP 处理吗?提前致谢。

代码:

try
{
  SqlConnection conn = new SqlConnection();
  conn.ConnectionString = strConnection;
  SqlCommand cmd = new SqlCommand();
  cmd.Connection = conn;
  cmd.CommandTimeout = 120;
  cmd.CommandType = CommandType.StoredProcedure;
  cmd.CommandText = "insFamilyDetails";
  cmd.Parameters.AddWithValue("@strHusbandName", strHusbandName);
  cmd.Parameters.AddWithValue("@strRelation", strRelation);
  ....
  ....
   // Child Details
  for (int i = 0; i < strChildredDetails.Rows.Count; i++)
  {
    cmd.Parameters.AddWithValue("@strChildName", strChildredDetails.Rows[i][0].ToString());
    cmd.Parameters.AddWithValue("@strDOB", strChildredDetails.Rows[i][1]);
    cmd.Parameters.AddWithValue("@strBaptisedon", strChildredDetails.Rows[i][2]);
    cmd.Parameters.AddWithValue("@strFirstComOn", strChildredDetails.Rows[i][3]);
    cmd.Parameters.AddWithValue("@strConfirmedOn", strChildredDetails.Rows[i][4]);
    cmd.Parameters.AddWithValue("@strMarried", "0");
    cmd.Parameters.AddWithValue("@strAlive", "1");
  }
  conn.Open();
  ReturnValue = Convert.ToBoolean(cmd.ExecuteNonQuery());
  conn.Close();
}
catch (Exception e)
{
 DL_LogAppErrors(e.ToString(), System.Reflection.MethodBase.GetCurrentMethod().Name, "Insert Family Details");
 return ReturnValue;
}

return ReturnValue;
4

4 回答 4

1

command在循环的每次迭代中添加参数。第一次迭代后,您尝试parameter在参数集合中添加相同的名称。您可能需要使用SqlParameterCollection.Clear清除每次迭代的参数集合。执行命令后清除参数集合(在循环体中)。

conn.Open();
for (int i = 0; i < strChildredDetails.Rows.Count; i++)
{
    cmd.Parameters.AddWithValue("@strChildName", strChildredDetails.Rows[i][0].ToString());
    cmd.Parameters.AddWithValue("@strDOB", strChildredDetails.Rows[i][2]);
    cmd.Parameters.AddWithValue("@strBaptisedon", strChildredDetails.Rows[i][2]);
    cmd.Parameters.AddWithValue("@strFirstComOn", strChildredDetails.Rows[i][3]);
    cmd.Parameters.AddWithValue("@strConfirmedOn", strChildredDetails.Rows[i][4]);
    cmd.Parameters.AddWithValue("@strMarried", "0");
    cmd.Parameters.AddWithValue("@strAlive", "1");
    ReturnValue = Convert.ToBoolean(cmd.ExecuteNonQuery());
    cmd.Parameters.Clear();
}
conn.Close();

如果要在表中插入许多记录,则可以在 SP 中发送逗号分隔值,然后在 SP 中拆分并插入它们。它将保存数据库调用。这篇文章将展示你如何做到这一点。

于 2013-04-01T06:55:43.490 回答
1

我从代码中假设您将添加到主表和子表中。对于这种情况,您需要将流程分成两部分:

  1. 在主表中添加数据
  2. 循环添加子数据
    注意:添加新集合前需要清除参数,或者不添加新参数,而是更改现有参数的值

编辑:使用事务

con.Open();
SqlTransaction trans = con.BeginTransaction();

try {
    // Execute the SP here
    // After all SP executed, call the commit method
    trans.Commit();
} catch (Exception ex) {
    // An error happened, rollback
    trans.RollBack();
}
con.Close();
于 2013-04-01T07:03:37.880 回答
0

对于要插入的每一行,您必须调用 ExecuteNonQuery() 函数,即,它应该在 for 循环内,然后在循环结束时清除参数集合。

  conn.Open();
// Child Details
  for (int i = 0; i < strChildredDetails.Rows.Count; i++)
  {
   cmd.Parameters.AddWithValue("@strHusbandName", strHusbandName);
   cmd.Parameters.AddWithValue("@strRelation", strRelation);
  ....
  ....
    cmd.Parameters.AddWithValue("@strChildName", strChildredDetails.Rows[i][0].ToString());
    cmd.Parameters.AddWithValue("@strDOB", strChildredDetails.Rows[i][1]);
    cmd.Parameters.AddWithValue("@strBaptisedon", strChildredDetails.Rows[i][2]);
    cmd.Parameters.AddWithValue("@strFirstComOn", strChildredDetails.Rows[i][3]);
    cmd.Parameters.AddWithValue("@strConfirmedOn", strChildredDetails.Rows[i][4]);
    cmd.Parameters.AddWithValue("@strMarried", "0");
    cmd.Parameters.AddWithValue("@strAlive", "1");
  ReturnValue = Convert.ToBoolean(cmd.ExecuteNonQuery());
cmd.Parameters.Clear();

}
于 2013-04-01T06:59:40.847 回答
0

如前所述,如果要插入网格的记录,则需要在每个循环中都有 ExecuteNonQuery。

如果您使用的是 SQL Server 2008,替代选项是使用表值参数,这将使生活更轻松,您不必为 gridview 的每条记录进行往返。只需传递数据表。

请检查链接。

编辑:

对于 SQL Server 2005,您可能希望使用 XML。请检查链接。

public string SerializeObject<T>(T Obj)
{
string strxml = string.Empty;
using (StringWriter sw = new StringWriter())
{
    XmlSerializer xs = new XmlSerializer(typeof(T));
    xs.Serialize(sw, Obj);
    strxml = sw.ToString();
}
return strxml;
}

链接包含上述函数,将您的数据表传递给此函数,检查生成的 XML 并在存储过程中为 XML 中的元素使用相同的大小写,因为 XML 区分大小写。

于 2013-04-01T07:05:55.523 回答