使用存储过程从数据表插入参数
本文关键字:插入 参数 数据表 存储过程 | 更新日期: 2023-09-27 18:07:03
我正在尝试使用具有两个表的存储过程插入数据。第一个表的数据是通过文本框,第二个数据是通过一个网格,我存储在数据库中,并传递到插入。问题是,当读取数据表并插入它时,有太多的参数恰好添加到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;
我假设从代码中您将添加到一个主表和子表中。对于这种情况,您需要将流程分为两个:
- 在主表 中添加数据
- 循环添加子数据
注意:添加新集前需要清除参数,或不添加新参数,更改已有参数 的值
EDIT: Using Transaction
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();
在循环的每次迭代中都在command
中添加参数。在第一次迭代之后,您尝试在参数集合中添加相同的parameter
名称。您可能需要使用SqlParameterCollection.Clear在每次迭代中清除参数集合。执行命令(In循环体)后清除参数收集。
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呼叫。这篇文章将告诉你如何做到这一点。
对于您想要插入的每一行,您必须调用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();
}
如前所述,如果您想插入网格的记录,则需要在每个循环中使用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是区分大小写的。