SqlDataReader can't read data even though it finds something - c#

As, the title says, SqlDataReader can't read the data it finds. I'm querying a particular table for a username to later use in adding data to another table. The reader finds results (Reader.HasRows is true), but can't read them. This is the code:
Connection.Open();
Command = new SqlCommand("SELECT ID FROM Users WHERE Username = #Username", Connection);
Command.Parameters.Add("#Username", TextBox1.Text);
SqlDataReader Reader = Command.ExecuteReader();
if (Reader.HasRows)
{
var ID = Reader[0];
Reader.Close();
Command = new SqlCommand("INSERT INTO Locations (User_ID,Location,Date) VALUES (#User_ID,#Location,GETDATE())", Connection);
Command.Parameters.Add("#User_ID", ID);
Command.Parameters.Add("#Location", TextBox2.Text);
Command.ExecuteNonQuery();
}
else
{
ErrorLabel.Text = "Username could not be found.";
}

You have to call Reader.Read() in order to advance to the next row.
https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader(v=vs.110).aspx

You need to call Read method on reader.
eg.
while (reader.Read())
{
....
}
More info in MSDN.

I Would do this:
while (Reader.HasRows())
{
Reader.Read();
string ID = Reader["ID"].ToString();
...
}

Use if (reader.Read()) instead of if (Reader.HasRows)

Yeah. You never READ.
while (Reader.Read ()) {
}
instead of If hasrows.
You must call Read. Like every tutorial shows.

Related

'No data exists for the row/column.' Oledb Exception

connection.Open();
OleDbCommand command = new OleDbCommand("SELECT [Names] FROM Test",
connection);
OleDbDataReader reader = command.ExecuteReader();
string result = reader.GetValue(0).ToString();
MessageBox.Show(result);
connection.Close();
Could anyone help? I'm getting 'No data exists for the row/column.' this error thrown
You are not calling Read Method
OleDbDataReader reader = command.ExecuteReader();
if(reader.Read())
{
string result = reader.GetValue(0).ToString();
MessageBox.Show(result);
}
connection.Close();
This will just read the first row from the result.If you want all the rows then you will need to write some thing like this
OleDbDataReader reader = command.ExecuteReader();
List<string> data = new List<string>();
while(reader.Read())
{
data.Add(reader.GetValue(0).ToString());
}
connection.Close();

I'm having an error with Identifying if a record is valid

This code is supposed to identify if the record is not existing it will give you the message "Room is invalid!". But when I tried to run the program it would give me the message several times even though the record is already in the database.
con.Open();
cmd = new SqlCommand(#"Select Room_Name From Rooms", con);
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
roomname = rdr["Room_Name"].ToString();
if (txtRoom.Text != roomname)
{
MessageBox.Show("Room is invalid.");
txtRoom.Focus();
}
}
rdr.Close();
con.Close();
You are reading every record in the database and showing an error on the first invalid match. Filter to your query and use an if instead of a loop
con.Open();
cmd = new SqlCommand(#"Select Room_Name From Rooms where room_name = #roomName", con);
cmd.Parameters.Add("#roomName", SqlDbType.NVarChar, -1).Value = txtRoom.Text;
rdr = cmd.ExecuteReader();
if (rdr.Read())
{
roomname = rdr["Room_Name"].ToString();
}
else
{
MessageBox.Show("Room is invalid.");
txtRoom.Focus();
}
rdr.Close();
con.Close();
Also, as an aside, wrap the DB stuff in using statements so resources are properly disposed of.

Read Integer values via Reader.(Sql-server)

con.Open();
cmd = new SqlCommand("USE PRODUCTS SELECT BOUGHT FROM " +
DropDownList1.SelectedItem.Text +
" WHERE ID = #ID", con);
cmd.Parameters.Add("ID", SqlDbType.Int).Value = DropDownList2.SelectedIndex;
int i = cmd.ExecuteReader().GetInt32(0);
con.Close();
I can't read integer values with reader like this. I get runtime error System.InvalidOperationException. What is wrong with my code ? if you can't find the mistake, can you explain how can i read integer values with reader ? By the way this part of code gives the error:
int i = cmd.ExecuteReader().GetInt32(0);
Try this:
int x=0;
using (
SqlConnection connection = new SqlConnection(strCon))
{
SqlCommand command = new SqlCommand(sql_string, connection);
connection.Open();
DataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
x = reader.GetInt32(0);
}
}
reader.Close();
}
You need to initialise a reader and then read it
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read()) // or just rdr.Read() if you know only one row is returned
{
int i = rdr.GetInt32(0);
What I have done to make things a lot easier on my end, since I mainly use SQL all over the place, is make some extensions.
eg
public static Int32 GetInt32(this SqlDataReader rdr, string column)
{
return Convert.ToInt32(rdr[column]);
}

How to retrieve data from database mySQL using MySqlDataReader?

I want to retrieve some specific data from tblBranches based to the choice of the user in the combobox (cboBranch.Text), one is the class_name but when I tried to run the program the messagebox shows MySql.Data.MySqlClient.MySqlDataReader, so how can I properly retrieve the data in my database?
query = "SELECT class_name FROM tblBranches WHERE branch_name=#branch";
MySqlCommand cmd = new MySqlCommand(query, con);
cmd.Parameters.Add("#branch", MySqlDbType.VarChar, 30).Value = _order.cboBranch.Text;
MySqlDataReader dr;
con.Open();
dr = cmd.ExecuteReader();
string class_name = dr.ToString();
MessageBox.Show(class_name);
con.Close();
Rather than call the ToString() method, you need to to call the GetString() method passing the zero-based index of the ordinal position of the column in your query, zero in this case because there is only one column in your query.
Before that, you must call the Read() method to advance the reader onto the first or next record and you also need to check the return value because it will return a bool to indicate if another record was found.
So replace this line...
string class_name = dr.ToString();
With
string class_name = dr.Read() ? dr.GetString(0) : "Nothing Found";
Or if there could be more than one record returned...
string class_names = string.Empty;
while (dr.Read())
class_names = dr.GetString(0) + "\n";
Just an addition: isn't is easier to use ExecuteScalar in case there's only 1 row to expect as a result?
Example:
MySqlCommand cmd = new MySqlCommand(query, con);
cmd.Parameters.Add("#branch", MySqlDbType.VarChar, 30).Value = _order.cboBranch.Text;
var class_name = cmd.ExecuteScalar();
if (class_name != null)
{
//DoSomething with your result here.
}else{
//Item not found, handle it here
}

SQL Data Reader: Invalid attempt to read when no data is present

I am trying to use a SqlDataReader to run a query and then display the results in a messagebox, but I keep getting the error
Invalid attempt to read when no data is present.
Here is my code.
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);
}
}
}
}
That's correct.
When you exit from the while loop the DataReader has reached the end of the loaded data and thus cannot be used to get the value of a non-existant current record.
The Read method advances the SqlDataReader (dr) to the next record and it returns true if there are more rows, otherwise false.
If you have only one record you could use the results variable in this way
MessageBox.Show(results);
Now, this will work because you have a TOP 1 in your sql statement, but, if you have more than one record, it will show only the value of the last record.
Also as noted by marc_s in its comment, if your table is empty, your code doesn't fall inside the while loop, so probably you could initialize the results variable with a message like:
results = "No data found";
EDIT: Seeing your comment below then you should change your code in this way
.....
// 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();
}
}
}
.....
I ran into a similar issue trying to get a GUID I knew was there - I could run the same SQL directly in SQL Management Studio and get my result. So instead of trying to bring it back as a GUID (it was saved in a char(35) field, even though it really was a GUID!), I brought it back as a string, instead:
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();
}

Categories

Resources