1

感谢这里的一些提示和提醒,我从这个混乱的混乱中更改了我的代码:

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)
        {
            . . .

请注意,我已经在新代码SqlCommandExecuteReader注释掉了,因为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);
    }
}
4

1 回答 1

1

我会亲自创建一个 SqlDBHelper 类并使用这样的方法传递调用存储过程

public static class SqlDBHelper
{
    public static DataSet ExecuteDataSet(string sql, CommandType cmdType, params SqlParameter[] parameters)
    {
        using (DataSet ds = new DataSet())
        using (SqlConnection connStr = new SqlConnection(ConfigurationManager.ConnectionStrings["DbConn"].ConnectionString))
        using (SqlCommand cmd = new SqlCommand(sql, connStr))
        {
            cmd.CommandType = cmdType;
            foreach (var item in parameters)
            {
                cmd.Parameters.Add(item);
            }

            try
            {
                cmd.Connection.Open();
                new SqlDataAdapter(cmd).Fill(ds);
            }
            catch (SqlException ex)
            {
                //log to a file or write to Console for example
                Console.WriteLine(ex.Message);
            }
            return ds;
        }
    }
}

如果要返回 DataTable 则更改方法签名中的返回类型并在下面的返回语句中调用以下内容

public static DataTable ExecuteDataSet(string sql, CommandType cmdType, params SqlParameter[] parameters)

return ds.Tables[0];

这是有关如何调用该方法的示例

someDataTable = SqlDBHelper.ExecuteDataSet("sp_ViewProductUsage_MappingRS", CommandType.StoredProcedure,
            new SqlParameter() { ParameterName = "@Unit", SqlDbType = SqlDbType.VarChar, Value = _unit },
            new SqlParameter() { ParameterName = "@BegDate", SqlDbType = SqlDbType.DateTime, Value = dtBegin },
            new SqlParameter() { ParameterName = "@EndDate", SqlDbType = SqlDbType.DateTime, Value = dtEnd }
            );
于 2015-11-23T17:50:53.690 回答