我正在尝试使用具有两个表的存储过程插入数据。第一个表是数据是通过文本框,第二个数据是通过网格存储在数据库中并传递给要插入的。问题是当读取数据并插入它时说有太多的参数恰好在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;
答案 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表中。对于这种情况,您需要将流程分为两个:
编辑:使用交易
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区分大小写。