【问题标题】:query to sum a field from access database with int datatype查询以对具有 int 数据类型的 access 数据库中的字段求和
【发布时间】:2018-08-10 19:58:25
【问题描述】:

有一个名为qty 的字段。我想对具有相同发票编号的多行求和。

String sql = "select sum(qty) from pur_invo_tran where invo_no='"+dataGridView1.Rows[i].Cells[1].Value+"' and doi=#"+Convert.ToDateTime(dataGridView1.Rows[i].Cells[0].Value.ToString())+"#";

OleDbConnection con = new OleDbConnection();
con.ConnectionString = constr;
OleDbCommand cmd = new OleDbCommand(sql, con);
OleDbDataReader Reader = null;

try
{
    con.Open();
    int b = (int)cmd.ExecuteScalar();

    dataGridView1.Rows[i].Cells[2].Value = b.ToString("## ## ## ###.##").Trim().Replace(" ", ",");
    con.Close();
}
catch (Exception ee)
{
    MessageBox.Show("Error..." + ee.Message);
}

【问题讨论】:

  • 我的发票号码是56'; drop table pur_invo_tran; --
  • 另外,当您运行刚刚粘贴的代码时会发生什么?我认为它除了给你你想要的总和之外还有其他的作用。
  • ExecuteNonQuery 返回受影响的行数,这绝对不是发票的总和,也可能不是您想要将网格单元格值设置为的值。
  • 使用参数... 您的查询的当前版本使用日期,但未指定格式。可能invo_no(使用字符串分隔符)或该日期格式错误。

标签: c# sql ms-access


【解决方案1】:

解决方案:ExecuteNonQuery 更改为ExecuteScalar 以将总和放入b。如果qty 不是int,您可能需要更改b 的类型(以及分配它时的强制转换)以使用该类型。

解释: ExecuteNonQuery 用于诸如 INSERT、UPDATE 和 DELETE 之类的内容:因此是“非查询”。 SELECT 通常与ExecuteReader 一起使用,但有一种特殊情况,您只需要第一行的第一个值:ExecuteScalar,这在这种情况下是有意义的,因为您将所有一组值相加成一个单总。

其他提示...

  1. OleDbConnection、OleDbCommand 和 OleDbDataReader(未使用,但在我提出这一点时...)都是 IDisposable,因此每个都应位于 using 块中。完成后,您无需在连接上调用 Close,因为隐式 Dispose 将为您调用 Close。
  2. 您的代码容易受到 SQL 注入攻击(这是 SamIAm 在评论中提出的观点)。通过避免字符串连接来创建查询来避免这种情况:使用 SQL 参数。
  3. b.ToString("## ## ## ###.##").Trim().Replace(" ", ","); Trim 是多余的,因为您刚刚指定了格式,它不会以空格开头或结尾。而不是做Replace,为什么不首先正确地格式化它,在格式字符串中放置逗号而不是空格。或者更进一步,考虑使用 N2C2standard format string(因为它是货币金额),这将为应用程序的当前文化使用标准数字或货币格式。

【讨论】:

  • 即使在将 ExecuteNonQuery 更改为 ExecuteScalar 之后,它也会抛出“指定的强制转换无效”异常
  • @Sachin ExecuteScalar 返回一个对象,因此移除强制转换,并将b 更改为object 而不是int。在该行之后放置一个断点,然后运行代码以命中该断点,并使用调试器查看 b actually 是什么类型。您会发现它与 int 的类型不同...如果是这样,则将 b 更改为该类型,然后重新输入。
【解决方案2】:

如果Cells[0] 包含文本,则:

doi=#"+Convert.ToDateTime(dataGridView1.Rows[i].Cells[0].Value).ToString("yyyy'/'MM'/'dd")+"#"

如果它包含 DateTime 值,则只需要格式化:

doi=#"+dataGridView1.Rows[i].Cells[0].Value.ToString("yyyy'/'MM'/'dd")+"#"

如果invo_no 是数字,则没有引号:

invo_no="+dataGridView1.Rows[i].Cells[1].Value+"

【讨论】:

    猜你喜欢
    • 2016-11-19
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多