【问题标题】:ExecuteScalar always returns 0ExecuteScalar 总是返回 0
【发布时间】:2013-05-24 22:33:53
【问题描述】:

我不确定为什么会这样。我在网上看到了同样的问题,但几乎没有人帮忙纠正它。

当我在 Access 中运行我的查询时,我得到了从 0 到 10 的不同值,但由于某种原因,它不会在我的代码中返回相同的值。

static int OrdersPerHour(string User)
    {
        int? OrdersPerHour = 0;
        OleDbConnection conn = new OleDbConnection(strAccessConn);
        DateTime curTime = DateTime.Now;


        try
        {

            string query = "SELECT COUNT(ControlNumber) FROM Log WHERE DateChanged > #" + curTime.AddHours(-1) + "# AND User = '" + User + "' AND Log.EndStatus in ('Needs Review', 'Check Search', 'Vision Delivery', 'CA Review', '1TSI To Be Delivered');";
            OleDbCommand dbcommand = new OleDbCommand(query, conn);
            dbcommand.Connection.Open();
            dbcommand.CommandType = CommandType.Text;
            dbcommand.CommandText = query;
            OrdersPerHour = (int?)dbcommand.ExecuteScalar();


                      }
        catch (OleDbException ex)
        {

        }
        finally
        {
            conn.Close();
        }
        return OrdersPerHour.Value;

    }

【问题讨论】:

  • 您可能需要编辑以改进 Markdown 的格式。你的意思是在 try{} 中包含一些代码吗?
  • 请使用参数... SQL注入很真实
  • 1.) 请使用Parameterized Queries。 2.) 为什么你有一个空的Try Catch Finally?这只是为了确保连接关闭吗?您应该在 using 声明中包含您的 OleDbConnection

标签: c# oledb executescalar


【解决方案1】:

不要使用字符串连接和 Access 语法来构建你的 sql 命令。
使用像这样的简单参数化查询

string query = "SELECT COUNT(ControlNumber) FROM Log " + 
                "WHERE DateChanged > ? AND [User] = ? AND " + 
                "Log.EndStatus in ('Needs Review', 'Check Search', 'Vision Delivery'," + 
                "'CA Review', '1TSI To Be Delivered');";

  OleDbCommand dbcommand = new OleDbCommand(query, conn);
  dbcommand.Parameters.AddWithValue("@p1", curTime.AddHours(-1));
  dbcommand.Parameters.AddWithValue("@p2", User);
  dbcommand.Connection.Open();
  dbcommand.CommandType = CommandType.Text;
  OrdersPerHour = (int)dbcommand.ExecuteScalar();

通过这种方式,正确解释您的值的负担被传递给框架代码,该代码可以根据您的数据库要求格式化日期、小数和字符串。顺便说一句,这也将防止 Sql Injection

另外,USER 是 Access SQL 中的保留关键字,因此需要用方括号将其封装

【讨论】:

  • 在 C# 中,您可以使用 @ 符号使查询跨越多行,而无需串联。
  • 虽然您对 @ 符号的使用是正确的,但您还应该提到这样一个事实,即这种使用会为构建的字符串添加大量空格(取决于您如何格式化行)。尝试使用 @ 符号打印此字符串的长度。此外,像这样的常量文本的字符串连接在编译时解决,构建一个静态定义的唯一字符串,没有昂贵的字符串连接(查看 IL 代码证实了这一点)
  • 我没有收到“标准表达式中的数据类型不匹配”。运行我的 ExecuteScalar() 时出错
  • 检查 DateChanged 列是否有效为 DateTime 列,User 列是否为文本数据类型
【解决方案2】:

首先也是最重要的:使用参数化查询!

关于你的问题,建议你调试一下代码:

获取“OleDbCommand dbcommand”的命令文本并手动查询以查看是否得到相同的结果。

另外,你应该把你的代码放在 try catch 块中,否则它根本没有意义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-27
    • 2014-03-20
    • 2013-04-13
    • 2013-03-30
    相关资源
    最近更新 更多