查询以对具有int数据类型的Access数据库中的字段求和

时间:2018-08-10 19:58:25

标签: c# sql ms-access

有一个名为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);
}

2 个答案:

答案 0 :(得分:1)

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

说明: ExecuteNonQuery用于诸如INSERT,UPDATE和DELETE之类的东西:因此是“非查询”。 SELECT通常与ExecuteReader一起使用,但是在特殊情况下,您只需要第一行中的第一个值:ExecuteScalar,在这种情况下很有意义,因为您要对所有集合求和值合并为一个总数。

其他提示...

  1. OleDbConnection,OleDbCommand和OleDbDataReader(未使用,但在我说明这一点... 时)都是IDisposposable的,因此每个都应放在using块中。完成后,您无需在连接上调用Close,因为隐式Dispose将为您调用Close。
  2. 您的代码容易受到SQL注入攻击的影响(这就是SamIAm在评论中指出的重点)。通过避免使用字符串连接来创建查询来避免这种情况:使用SQL参数。
  3. b.ToString("## ## ## ###.##").Trim().Replace(" ", ","); Trim是多余的,因为您刚刚指定了格式,并且不会以空格开头或结尾。除了使用Replace之外,为什么不首先通过将逗号放在格式字符串而不是空格中来正确地设置其格式。或者更进一步,考虑使用N2的{​​{3}}或什至C2(因为它是货币金额),这将为应用程序的当前区域性使用标准的数字或货币格式。

答案 1 :(得分:0)

如果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+"