使用存储过程从DataTable插入参数

时间:2013-04-01 06:53:38

标签: c# sql sql-server stored-procedures

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

CODE:

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 个答案:

答案 0 :(得分: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中拆分并插入它们。它将保存db调用。这个post将展示你如何做到这一点。

答案 1 :(得分:1)

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

  1. 添加主表
  2. 中的数据
  3. 循环添加子数据
    注意:您需要在添加新集之前清除参数, OR 而不是添加新参数,更改现有参数的值
  4. 编辑:使用交易

    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();
    

答案 2 :(得分: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();

}

答案 3 :(得分:0)

如前所述,如果要插入网格记录,则需要在每个循环内部使用ExecuteNonQuery。

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

请检查this链接。

修改

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

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区分大小写。