【问题标题】:ExecuteNonQuery is returning a -1 when the query is selecting records. Why?当查询选择记录时,ExecuteNonQuery 返回 -1。为什么?
【发布时间】:2016-03-27 14:41:15
【问题描述】:

我在一个按钮点击中有如下代码:

private void button7_Click(object sender, EventArgs e)
{
     using (SqlConnection connect = new SqlConnection(PubVars.connStr))
     {
        string query = "SELECT * FROM Users WHERE username = '" + comboBox1.SelectedValue.ToString() + "' AND password = '" + txtDelUsrPassword.Text + "'";
        using (SqlCommand cmd = new SqlCommand(query, connect))
        {
           connect.Open();
           DataRow[] foundRow = cmd.ExecuteNonQuery();
           connect.Close();
        }
     }
}

在我输入该行之后

DataRow[] foundRow = cmd.ExecuteNonQuery();

在 cmd.ExecuteNonQuery 下有一条红色波浪线。因此,当我尝试保存并运行它时,错误消息:

无法将类型“int”隐式转换为“System.Data.DataRow[]”。

当查询是标准 SQL 选择时,这是什么原因?

【问题讨论】:

  • 阅读ExecuteNonQuery的REMARKS部分的最后一个逗号
  • 你使用了错误的方法来检索数据,你真的应该去查一下。
  • 你想执行一个 SQL 查询,所以你打电话给ExecuteNonQuery...你认为会发生什么?
  • 另外,您很容易受到 SQL 注入攻击,并且将密码存储为纯文本。

标签: c# sqlcommand


【解决方案1】:

因为documented;

对于 UPDATE、INSERT 和 DELETE 语句,返回值为 受命令影响的行数。当触发器存在于 正在插入或更新的表,返回值包括数字 受插入或更新操作和数量影响的行数 受触发器或触发器影响的行数。 对于所有其他类型的 语句,返回值为-1。如果发生回滚,则返回 值也是 -1。

如果您想获得所有结果并将它们放入 DataRow 数组中,您应该使用 SqlDataAdapter 和返回 DataTable.SelectDataTable.Select 方法。

var dt = new DataTable();
using(var adapter = new SqlDataAdapter(cmd))
{
   adapter.Fill(dt);
   DataRow[] rows = dt.Select();
}

此外,您应该始终使用parameterized statements。这种字符串连接对SQL Injection 攻击开放。并且不要将您的密码存储为纯文本。阅读:Best way to store password in database

顺便说一句,目前尚不清楚您将如何处理这个DataRow[],但如果您只是想根据WHERE 子句中的条件检查有多少结果,您可以将您的查询更改为SELECT count(*) 并使用ExecuteScalar 方法获取它。

【讨论】:

  • 好的,知道了。谢谢。我是 C# 新手,我想我知道我哪里出错了。
  • 我会推荐一个数据适配器,而不是使用阅读器并手动构建行。
  • @siride 你是对的。在这种情况下,SqlDataAdapter 是一种更好的方法。基于此更新了我的答案。谢谢。
  • 我使用 ADO 已经有一段时间了,但这不会抛出 NRE,因为 dt 为空?
  • @DavidG 应该是因为我把它改成了var dt = new DataTable(); :) 但是我现在没有编译器所以..
猜你喜欢
  • 1970-01-01
  • 2011-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-01
  • 2014-11-19
  • 2016-02-28
相关资源
最近更新 更多