sqldatareader error - c#

I want to check if the sqldatareader is null or not. So tried the following code:
if (x[k]!= DBNull.Value)
{
box.Text = Convert.ToString(x[k++]);
if ((box.Text) != "")
current[j - 1] = Convert.ToDouble(box.Text);
else current[j - 1] = 0;
box.Enabled = false;
}
However while trying to check the value within the datareader, it throws an error,"invalid attempt to read data when no data is present". How else should i check to see if data is there or not.!! please help. here x is an sqldatareader
SqlDataReader x = cmd.ExecuteReader();
and cmd is a select commnand..

You can use SqlDataReader.HasRows - it is true if at least one row of data is present, alternatively you can read through all results using SqlDataReader.Read();
So for your example:
while(x.Read())
{
//read stuff
}

You can do a null check and Has Row before accessing the DataRows.
like this
if(null != x && x.HasRows)
{
//Your code
}

Related

How to determine a session variable contains data table is null or empty in C#

I have a Session variable Session["tblItems"], The session variable holds a datatable. Please find my code below.
public JsonResult SaveItemToTable(string itemCode, int quantity, int Division)
{
try
{
DataTable dt = new DataTable("tblItems1");
if(!string.IsNullOrEmpty(Session["tblItems"] as string))
{
dt = (DataTable)Session["tblItems"];
DataRow[] i = dt.Select("ItemCode ='" + itemCode + "'");
if (i.Count() > 0)
{
for (int j = dt.Rows.Count - 1; j >= 0; j--)
{
DataRow dr1 = dt.Rows[j];
if (dr1.ItemArray[0].ToString() == itemCode)
{
dr1.Delete();
}
}
}
}
else
{
dt.Columns.Add("ItemCode", typeof(string));
dt.Columns.Add("Quantity", typeof(int));
dt.Columns.Add("Division", typeof(int));
}
DataRow dr;
dr = dt.NewRow();
dr["ItemCode"] = itemCode;
dr["Quantity"] = quantity;
dr["Division"] = Division;
dt.Rows.Add(dr);
Session["tblItems"] = dt;
return Json(1);
}
catch(Exception ex)
{
return Json(0);
}
}
When the Session variable is empty , the code works fine (Only for the first time).
all the times
if(!string.IsNullOrEmpty(Session["tblItems"] as string))
The above code returns false. Even if the session variable contains value.
Your test is returning false because you are using a 'safe cast': as casting will return null if the conversion can't be made (see more on the C# guide here). Since you are trying to cast a datatable to a string, this will always return null, even when your session variable has a value.
To see the true nature of your problem, try converting them like this:
if(!string.IsNullOrEmpty((string)Session["tblItems"]))
This should thrown an exception, because you can't convert a datatable to a string like this. You will need to test for null like this:
if (Session["tblItems"] != null))
Update: having seen your comments, above, I've added a fuller example to explain what need to change. Your code should look more like this:
DataTable dt;
if (Session["tblItems"] != null))
{
dt = (DataTable)Session["tblItems"];
...
}
else
{
dt = new DataTable("tblItems1");
...
}
DataRow dr;
dr = dt.NewRow();
...
Note the changes I've made: initialise dt from session if there is a value, the cast will work in this case, and when it is null, construct a new one. You can then use the value in the section below without issue, because it will always have a value.
In addition, I would also recommend that you don't store your datatable in session at all, but rather just the values that you need.
To check if your Session is null or empty (for DataTable):
private bool IsDataTableNullOrEmpty(object arg) =>
arg == null || ((DatTable)arg).Rows.Count == 0;

Read and Generate New Enumber

Hi i am new here i just want to ask question for this code.
i am making a condition on my new buttom that generate Enumber= Employee Number.
i have database but no data record yet. if i press my new buttom my sql statement will select he last record on my data but i don't have yet data so i am trying to make a condition.
if Enumber is empty in database it should return and give the new Enumber on my textbox = txtEnumber.Text = "100000".
i hope you understand my problem.
con.Open();
cmd = new SqlCommand("SELECT TOP 1 Enumber FROM Employee ORDER BY Enumber DESC ", con);
dr = cmd.ExecuteReader();
dr.Read();
if (dr["Enumber"] == null) // Error: "Invalid attempt to read when no data is present."
{
txtEnumber.Text = "100000";
return;
}
else
{
String a = dr["Enumber"].ToString();
txtEnumber.Text = ("");
for (int i = 0; i < 1; i++)
{
string val = a.Substring(1, a.Length - 1);
int newnumber = Convert.ToInt32(val) + 1;
a = newnumber.ToString("100000");
}
txtEnumber.Text = a;
}
con.Close();
Since you don't have any row in your case, you can't iterate your reader. Instead of that, you can use ExecuteScalar which returns null as an object if there is no data in first column of the first row since your query returns as SELECT TOP 1...
var result = cmd.ExecuteScalar();
if(result == null)
{
txtEnumber.Text = "100000";
}
You should check whether there are rows first. dr.Read() returns whether the DataReader has rows, use it.
Your DataReader returns no results...
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read()) {
// read data for first record here
}
If you have more than one result, use a 'while' loop.
while (dr.Read()) {
// read data for each record here
}
You should use dr.HasRows to check whether there is data or not.
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read()) {
dataTable.Load(dr);
}
If you have more than one result, use a 'foreach' loop.
foreach (DataRow Drow in datatable.Rows)
{
// read data for each record here
}
Try This is Worked..

SqlDataReader - how to discover that column is empty

I try to read the result of the query and discover if some of the columns is empty
This is a way I started:
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
rdr["ColumnName"]; // how do I know if it has a value or empty
}
I thought to do :
dr[4].ToString() == String.Empty
It makes a needed work, but I don`t like this (it is a hack rather than solution)
can you advise me how do I do it correctly and elegantly?
Empty does not exists for int values and what is correct when working with databases is use Null which is the only true "Empty".
SqlDataReader rdr = cmd.ExecuteReader();
int colIndex = read.GetOrdinal("MyColumnName");
while (rdr.Read())
{
// [true | false] your validation goes here!;
if (rdr.IsDBNull(colIndex)){
//value is null
}
}
Please note that if you want use 0, "" or 1/1/1900 as empty values those will require a custom treatment.
This is how I do it
string UserInitialssql = rdr.IsDBNull(2) ? String.Empty : rdr.GetString(2);
If it is Int
Int32? i = rdr.IsDBNull(2) ? (Int32?)null : rdr2.GetInt32(2);
Another possibility is to use nullable types. e.g.:
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
int? someNumber = rdr["ColumnName"] as int?;
if (someNumber == null)
// was NULL in database
else
// use someNumber.Value to get int
}

Get all the rows from query result

I have a stored procedure that returns a boolean. (0 or 1). It returns multiple rows. my question is how to iterate through all the result.
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DBReader"].ConnectionString))
{
using (SqlCommand com = new SqlCommand("Reader.usp_CheckerIsStopped", con))
{
com.CommandType = CommandType.StoredProcedure;
com.Parameters.Add("#fld_UserID", SqlDbType.Int).Value = this.UserID;
con.Open();
SqlDataReader dr = com.ExecuteReader();
if (dr.Read() == 1)
{
return true;
}
else
{
return false;
}
}
}
It has a error in dr.Read() == 1
Error:
Operator == cannot be applied to type bool to int"
My stored procedure returns multiple rows containing 0 or 1,I want to get those values because I want to do a checking if it is equals to true of false (0 or 1)
if (e.Row.RowType == DataControlRowType.DataRow)
{
//if (e.Row.Cells[11].Text == "In Progress")
//{
// System.Web.UI.WebControls.ImageButton StartImageButton = (System.Web.UI.WebControls.ImageButton)e.Row.Cells[1].FindControl("StartImageButton");
// StartImageButton.Visible = false;
//}
gvfunct.UserID = Convert.ToInt32(Session["UserID"]);
gvfunct.CheckIsStopped();
if (gvfunct.CheckIsStopped() == true)
{
System.Web.UI.WebControls.ImageButton StartImageButton = (System.Web.UI.WebControls.ImageButton)e.Row.Cells[2].FindControl("StartImageButton");
StartImageButton.Visible = true;
System.Web.UI.WebControls.ImageButton StopImageButton = (System.Web.UI.WebControls.ImageButton)e.Row.Cells[1].FindControl("StopImageButton");
StopImageButton.Visible = false;
}
else
{
System.Web.UI.WebControls.ImageButton StopImageButton = (System.Web.UI.WebControls.ImageButton)e.Row.Cells[1].FindControl("StopImageButton");
StopImageButton.Visible = true;
System.Web.UI.WebControls.ImageButton StartImageButton = (System.Web.UI.WebControls.ImageButton)e.Row.Cells[2].FindControl("StartImageButton");
StartImageButton.Visible = false;
}
}
You'll need to continue to Read() and do something with those results.
while (dr.Read())
{
}
You see, the Read() method returns a bool. So, now if you wanted to get to the results of each row you might do something like this:
while (dr.Read())
{
var val = dr.GetInt32(0);
}
and that would get the value of the first column, from the row you're currently on in the Read(), and cast it as an int. Of course that line could throw an error if you're trying to cast a string or something. Consider the fact that a DataReader is a read-only, forward-only, buffer of data. It literally only pulls one row of data at a time from the server, thus leaving the connection open during the duration of the Read() operation and until it goes out of scope.
As dr.Read() returns bool thus you are getting error when comparing with int
It will return true if SqlDataReader has rows otherwise false.
So change you code as
return dr.Read();
instead of
if (dr.Read() == 1)
{
return true;
}
else
{
return false;
}
Replace
if (dr.Read() == 1)
{
return true;
}
with
if (dr.Read())
{
return true;
}
you need to explicitly cast it or just use it's proper Boolean type
so instead of if (dr.Read() == 1), you may use if (dr.Read() == true) or if (dr.Read())
there isn't a direct cast that i am aware of, for instance (bool)1 is not going to work, but you may always use Convert.ToBoolean(1) or some other methods to convert it
you may also create your own custom casting method
IntToBool (int bool)
{
if(bool == 1) return true;
return false;
}
It's not really clear what your stored procedure returns, but if the first row and first column contains for example an integer, you could also forget the reader and use SqlCommands ExecuteScalar-method like so:
return com.ExecuteScalar() == 1;
If you need to iterate through all the rows, try this
if(dr.Read()){
if(dr.Read()) return true;
else return false;
}
else return false;
This will read dr twice and return true if it finds 2 rows. False if it finds 0 or 1 row.

Check if a datareader has rows or not in Asp.net

My code:
string sqlQuery1 = "select * from employees where depid=6";
SqlDataReader Dr1 = dbconn.RunQueryReturnDataReader(sqlQuery1);
if(Dr1.read()) { //or if (Dr1["empname"] != DBNull.Value)
while (Dr1.Read())
{
Label1.Text = Dr1["empname"].ToString();
Label2.Text = Dr1["empdes"].ToString();
...
}
Dr1.Close();
}
else {
Label1.text = "defaultValue";
Label2.text = "defaultValue";
...
}
I just want to check SqlDataReader has no records to display. If no records ,the labels should showdefault values preassigned by me or If has record display datareader value on label. (Assume either SqlDataReader has 1 recode or has norecord only)
How can I check first datareader hasRow or not?
I have tried two ways as above code.
if(Dr1.read()) - this way working fine. But after execute If statement ,it has no value to display on labels , since read() will increase the pointer. As a result label1 ,Label2.. Nothing display.
if (Dr1["empname"] != DBNull.Value)
This way generate an exception when Sqldatareader has norows.
error: System.InvalidOperationException: Invalid attempt to read when no data is present
Please help me. tx
try...
if(Dr1.HasRows)
{
//....
}
if (Dr1 == null || !Dr1.HasRows) {
// Do something
}

Categories