感谢这里的一些提示和提醒,我从这个混乱的混乱中更改了我的代码:
try
{
DataSet dsUsage = new DataSet();
SqlConnection conn = new SqlConnection("SERVER=PROSQL05;DATABASE=platypusdata;UID=duckbill;PWD=poisonToe42;Connection Timeout=0");
SqlDataAdapter da = new SqlDataAdapter();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = String.Format("Exec sp_ViewProductUsage_MappingRS '{0}', '{1}', '{2}'", mammal, dateBegin, dateEnd);
da.SelectCommand = cmd;
conn.Open();
da.Fill(dsUsage);
conn.Close();
DataTable dtUsage = dsUsage.Tables[0];
if (dtUsage.Rows.Count > 0)
{
foreach (DataRow productUsageByMonthDataRow in dtUsage.Rows)
{
. . .
...对此:
try
{
SqlDataAdapter da = new SqlDataAdapter();
DataSet dsUsage = new DataSet();
using (SqlConnection conn = new SqlConnection(UsageRptConstsAndUtils.PlatypusConnStr))
{
using (SqlCommand cmd = new SqlCommand("sp_ViewProductUsage_MappingRS", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@Unit", SqlDbType.VarChar).Value = _unit;
cmd.Parameters.Add("@BegDate", SqlDbType.DateTime).Value = dtBegin;
cmd.Parameters.Add("@EndDate", SqlDbType.DateTime).Value = dtEnd;
da.SelectCommand = cmd;
conn.Open();
//cmd.ExecuteReader(); <- Is this even necessary?
da.Fill(dsUsage);
}
}
DataTable dtUsage = dsUsage.Tables[0];
if (dtUsage.Rows.Count > 0)
{
// Populate the cells
foreach (DataRow productUsageByMonthDataRow in dtUsage.Rows)
{
. . .
请注意,我已经在新代码SqlCommand
中ExecuteReader
注释掉了,因为SqlDataAdapter
提供了SqlCommand
. 它工作正常。那么:我假设我可以cmd.ExecuteReader()
完全删除是否正确?保留它有什么好处,还是完全多余并为流程创造“忙碌的工作”?
更新
因此,要传递一个 SqlParameter 数组(传递给 MethodMan 答案中的 ExecuteDataSet 方法),我认为我首先必须执行以下操作:
SqlParameter sqlp = new SqlParameter();
sqlp.ParameterName = "Unit";
sqlp.Value = _unit;
cmd.Parameters.Add(sqlp);
...ETC。(然后将它们添加到数组中 - 或者,可能更好的是 SqlParameter 的通用列表)。
更新 2
我只是第一次遇到这个问题:如果您使用 MethodMan 的示例(我这样做)并且使用无参数查询,则需要绕过参数添加循环,如下所示:
if (null != parameters)
{
foreach (var item in parameters)
{
cmd.Parameters.Add(item);
}
}