SQL数据读取器:没有数据时读取的尝试无效

我试图使用SqlDataReader运行查询,然后在消息框中显示结果,但我不断收到错误

没有数据时读取的尝试无效。

这是我的代码。

  public void button1_Click(object sender, EventArgs e) { string results = ""; using (SqlConnection cs = new SqlConnection(@"Server=100-nurex-x-001.acds.net;Database=Report;User Id=reports;Password=mypassword")) { cs.Open(); string query = "select stationipaddress from station where stationname = @name"; using (SqlCommand cmd = new SqlCommand(query, cs)) { // Add the parameter and set its value -- cmd.Parameters.AddWithValue("@name", textBox1.Text); using (SqlDataReader dr = cmd.ExecuteReader()) { while (dr.Read()) { label3.Text = dr.GetSqlValue(0).ToString(); results = dr.GetValue(0).ToString(); //MessageBox.Show(dr.GetValue(0).ToString()); //MessageBox.Show(results); } MessageBox.Show(results); } } } } 

那是对的。
当您从while循环退出时,DataReader已到达已加载数据的末尾,因此无法用于获取不存在的当前记录的值。

Read方法将SqlDataReader(dr)前进到下一条记录,如果有更多行则返回true,否则返回false。

如果您只有一条记录,则可以这种方式使用results变量

 MessageBox.Show(results); 

现在,这将起作用,因为你的sql语句中有一个TOP 1,但是,如果你有多个记录,它将只显示最后一条记录的值。

另外正如marc_s在其注释中所指出的,如果你的表是空的,你的代码不会落入while循环中,所以你可能会使用如下消息初始化结果变量:

  results = "No data found"; 

编辑:看到下面的评论,你应该用这种方式改变你的代码

 ..... // Use parameters **ALWAYS** -- **NEVER** cancatenate/substitute strings string query = "select stationipaddress from station where stationname = @name"; using (SqlCommand cmd = new SqlCommand(query, cs)) { // Add the parameter and set its value -- cmd.Parameters.AddWithValue("@name", textBox1.Text); using (SqlDataReader dr = cmd.ExecuteReader()) { while (dr.Read()) { label3.Text = dr.GetSqlValue(0).ToString(); results = dr.GetValue(0).ToString(); } } } ..... 

我遇到了类似的问题,尝试获取我知道的GUID – 我可以直接在SQL Management Studio中运行相同的SQL并获得我的结果。 因此,不是试图将其作为GUID(它保存在char(35)字段中,而是保存在GUID中!),而是将其作为字符串返回,而不是:

  SqlConnection sqlConn = null; string projId = String.Empty; string queryString = "SELECT * FROM project WHERE project_name='My Project'"; try { sqlConn = new SqlConnection(connString); SqlCommand cmd = new SqlCommand(queryString, sqlConn); sqlConn.Open(); SqlDataReader reader = cmd.ExecuteReader(); if (reader.HasRows) { while (reader.Read()) { projId = reader.GetSqlValue(0).ToString(); // <-- safest way I found to get the first column's parameter -- increment the index if it is another column in your result } } reader.Close(); sqlConn.Close(); return projId; } catch (SqlException ex) { // handle error return projId; } catch (Exception ex) { // handle error return projId; } finally { sqlConn.Close(); }