c# - 数据表始终返回 0

标签 c#

我的查询返回结果,但由于某种原因,我的 DataTable 始终显示 0。我唯一改变的是我向 C# 语法添加了参数(尽管如果我手动运行存储过程,它会返回结果)。这是我的语法,有人发现其中有语法错误吗?

protected void btnPress1464()
{
    RunSQLStoredProc();
    DataTable tableA = ebdb.Tables[0];
    if (this.dtgAttendanceTracker.Items.Count == 0)
    {
        this.gvwTest.DataSource = tableA
        this.gvwTest.DataBind();
    }
}

public DataSet RunSQLStoredProc()
{
    ebdb = new DataSet(); 
    SqlQueryBuilder = new StringBuilder();
    SqlQueryBuilder.Append("exec alphadawg ");
    ebdb = DoThis(SqlQueryBuilder.ToString());
    return ebdb;
}

public DataSet DoThis(string sqlQuery, int employeeid, DateTime hiredate, DateTime terminationdate)
{
    try
    {
        System.Configuration.ConnectionStringSettings connstring = System.Configuration.ConfigurationManager.ConnectionStrings["SQLServer1"];

        using (SqlConnection conn = new SqlConnection(connstring.ConnectionString))
        {
            using (SqlCommand cmd = new SqlCommand())
            {
                cmd.CommandText = sqlQuery;
                cmd.Connection = conn;
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@employeeid", employeeid.ToString());
                cmd.Parameters.AddWithValue("@hiredate", hiredate.ToShortDateString());
                cmd.Parameters.AddWithValue("@terminationdate", terminationdate.ToShortDateString());
                conn.Open();
                SqlDataAdapter adapter = new SqlDataAdapter(cmd);                    
                adapter.Fill(ebdb);
                conn.Close();
            }                
        }
        return ebdb;
    }
    catch (Exception exception) { throw exception; }
}

最佳答案

如果命令的 CommandTypeStoredProcedure,则 CommandText 应仅包含存储过程名称,而不应包含 exec >。 StringBuilder 也是多余的。

我还认为,使用错误类型的 AddWithValue 的方式可能会导致此问题(请查看我答案的最后一段):

所以不是

SqlQueryBuilder = new StringBuilder();
SqlQueryBuilder.Append("exec alphadawg ");
ebdb = DoThis(SqlQueryBuilder.ToString());

但是

ebdb = DoThis("alphadawg", otherParamaters...);

将 sql 字符串传递给执行它的方法也是一种不好的做法,这通常会引入 sql 注入(inject)问题。您不应该使用 DoThis 方法,而是使用 GetAlphaDawg 方法来封装 sql 查询并仅传递参数值。

除此之外,如果您返回的实际上是类中的一个字段,为什么还要从方法中返回 DataSet 呢?相反,在方法中初始化并填充它,这样更清晰,并且还可以防止加载已填充的数据集时出现问题(默认情况下会附加数据)。

这将是一个可能的实现。请注意,您不应使用 AddWithValue,也不应将 String 用于 DateTime,但始终使用正确的类型 ,如果您使用需要从值推断类型的 AddWithValue ,则更是如此:

public DataSet GetAlphaDawg(int employeeid, DateTime hiredate, DateTime terminationdate)
{
    DataSet dsAlpha = new DataSet();
    try
    {
        System.Configuration.ConnectionStringSettings connstring = System.Configuration.ConfigurationManager.ConnectionStrings["SQLServer1"];

        using (var conn = new SqlConnection(connstring.ConnectionString))
        {
            using (var da = new SqlDataAdapter("alphadawg", conn))
            {
                da.SelectCommand.CommandType = CommandType.StoredProcedure;
                var parameter = da.SelectCommand.Parameters;
                parameter.Add("@employeeid", SqlDbType.Int).Value = employeeid;
                parameter.Add("@hiredate", SqlDbType.Date).Value = hiredate;
                parameter.Add("@terminationdate", SqlDbType.Date).Value = terminationdate;
                da.Fill(dsAlpha); // Open/Close not needed with Fill
                return dsAlpha;
            }
        }
    } catch (Exception) { throw; }
}

由于您使用了ToShortDateString,如果您确实想删除DateTime的时间部分,请使用DateTime.Date,例如:

parameter.Add("@hiredate", SqlDbType.Date).Value = hiredate.Date;

关于c# - 数据表始终返回 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34337372/

相关文章:

c# - Azure 服务总线队列如何在 HTTPs 模式下将消息传递到客户端

c# - 在 C# 中查找多个列表中的公共(public)项

c# - 更新时从 GridView 内的下拉列表中获取选定的值

c# - 在 VS 2012 中声明常量的最佳实践

c# - Azure 函数 - function.json 它位于何处?

c# - 如何从实现页面访问自定义控件中存在的按钮?

c# - MvvmCross android 链接器终止绑定(bind)

c# - .NET CultureInfo 本地化显示名称

C# 高效的图像绘制和移动

c# - 在事件目录底层对象上使用 linq