【问题标题】:ADO.NET ExecuteReader Returns No ResultsADO.NET ExecuteReader 不返回任何结果
【发布时间】:2014-07-16 19:12:22
【问题描述】:

我正在更新一些旧的遗留代码,但遇到了问题 SqlCommand.ExecuteReader() 方法。问题是它没有返回任何 结果。但是,使用 SqlDataAdapter.Fill(),我从 数据库。我究竟做错了什么?如何使用数据获取结果 读者?

var connectionString = ConfigurationManager.ConnectionStrings["MyConnectionString"].ToString();

using (var sqlConnection = new SqlConnection(connectionString))
{
    using (var sqlCommand = new SqlCommand())
    {
        sqlCommand.Connection = sqlConnection;
        sqlCommand.CommandType = CommandType.Text;
        sqlCommand.CommandText = "SELECT * FROM MyTable WHERE ID = 1";
        sqlConnection.Open();

        // This code works.
        //var dataTable = new DataTable();
        //using (var sqlDataAdapter = new SqlDataAdapter(sqlCommand))
        //{
        //  sqlDataAdapter.Fill(dataTable);
        //}

        // This code is not working.
        using (var sqlDataReader = sqlCommand.ExecuteReader())
        {
            while (sqlDataReader.Read())
            {
                // This fails because the data reader has no results.
                var id = sqlDataReader.GetInt32(0);
            }
        }
    }
}

【问题讨论】:

  • 你试过sqlDataReader.GetValue(0) 吗?这会返回数据吗?
  • 究竟是什么失败了——什么是错误信息?
  • 第一个字段是 int 吗?您可以发布查询检索到的数据吗?那行肯定有数据,但问题是,它长什么样子?
  • 第一个字段是不可为空的整数并且是主键,第二和第三个字段是不可为空的十进制类型。 GetValue(0) 方法有效。奇怪的是 GetInt32(0) 没有。
  • 如果 GetValue(0) 有效,那么它不会因为没有结果而失败。错误是什么?

标签: c# sql sql-server tsql ado.net


【解决方案1】:

你的结果中可能没有Int32 吗?

var id = sqlDataReader.GetInt32(0); // <-- this might not be an Int32

要么尝试:

var id = sqlDataReader.GetValue(0);

或者转换为正确的类型(BIGINT 例如是Int64),如果没有看到你的数据就不确定。

【讨论】:

  • 表中的列是(PK,int,not null),所以GetInt32应该可以工作。 GetValue 有效,但我必须将其转换为整数。
  • @Halcyon 转换为int 与调用GetInt32() 不同,如果它不是一个精确的类型匹配,将一个short 转换为一个int 是可以的。 GetInt32()调用的时候会抛出异常吗?
  • 抛出了一个错误,所以你是对的。
【解决方案2】:

试试这个..

var id = 0;

using (var sqlDataReader = sqlCommand.ExecuteReader())
        {
            while (sqlDataReader.Read())
            {
                id = sqlDataReader.GetInt32(sqlDataReader.GetOrdinal("ColName"));
            }
        }

我已将变量移到阅读器代码之外,否则该变量只能在该范围内访问。我会避免在代码中指定序数,以防有人更改了数据库中的列。

另外,在 SQL 语句中指定列...SELECT ColName FROM ... 并在查询中使用params

【讨论】:

    【解决方案3】:

    如果你到达那条线,那么它有结果
    不代表值不为空
    而且你不应该使用 SELECT *
    如果隐式转换可能有问题
    试试 Int32

    try
    {
        if(sqlDataReader.IsDBNull(0))
        {
           // deal with null
        }
        else  
        {
          Int32 id = sqlDataReader.GetInt32(0);
        }
    }
    catch (SQLexception Ex) 
    {
        Debug.WriteLine(Ex.message);
    }
    

    【讨论】:

      【解决方案4】:
      var connectionString = ConfigurationManager.ConnectionStrings["MyConnectionString"].ToString();
      
      using (var sqlConnection = new SqlConnection(connectionString))
      {
          sqlConnection.Open();
          string sql = "SELECT * FROM MyTable WHERE ID = 1";
      
          using (var sqlCommand = new SqlCommand(sql, sqlConnection))
          {
              using (var sqlDataReader = sqlCommand.ExecuteReader())
              {
                  while (sqlDataReader.Read())
                  {
                      // This fails because the data reader has no results.
                      var id = sqlDataReader.GetInt32(0);
                  }
              }
          }
      }
      

      【讨论】:

      • 这里有什么区别?
      • 打开的连接被传递给 SQLCommand,这段代码 100% 工作,所以由于原始代码没有捕获任何异常,我假设第一列不是整数,通常它是一个不好的做法选择 *
      • OP 已经在这样做了,sqlCommand.Connection = sqlConnection; & sqlConnection.Open();
      • 然后由于转换为int而失败。
      • 我只是说你给出的答案本质上与 OP 遇到问题的代码相同......但我没有 -1!
      猜你喜欢
      • 2011-06-23
      • 2019-10-27
      • 2020-11-17
      • 1970-01-01
      • 2017-12-28
      • 2017-12-09
      • 2020-10-03
      • 2017-03-19
      • 2017-05-20
      相关资源
      最近更新 更多