Error when receiving null from database - c#

When i execute this command on my database i receive sometimes result=null. i want to enter the "else" part when is this happening, but i receive
An unhandled exception of type 'System.FormatException' occurred in mscorlib.dll.
Additional information: Input string was not in a correct format.
DB database = new DB();
int reservedSeats = 0;
using (database.sqlConnection)
{
database.sqlConnection.Open();
string command = "select SUM(nrLocuri) as result from Rezervari where idRand = #idRand and idShow=#idShow";
using (SqlCommand cmd = new SqlCommand(command, database.sqlConnection))
{
cmd.Parameters.Add("#idRand", SqlDbType.Int).Value = idRand;
cmd.Parameters.Add("#idShow", SqlDbType.Int).Value = idShow;
using (SqlDataReader dr = cmd.ExecuteReader())
{
if (dr.Read())
if (dr["result"].ToString() != null)
reservedSeats = Convert.ToInt32(dr["result"].ToString());
else
return totalSeats;
}
}
}
return totalSeats-reservedSeats;

Instead of:
if (dr["result"].ToString() != null)
Do:
if (dr["result"] != DbNull.Value)
When the dr["result"] returns a database null, its value is DbNull.Value - when you try to call Convert.ToInt32 on this value, you get a format exception.

try:
if(!dr.IsDBNull(i)){ //replace i with the column id
//get the data
}

If you want SUM() to return 0.00 in the event no records were found, replace it with:
COALESCE(SUM(...), 0.00)
COALESCE will return the first non-null value passed to it.

try isnull:
string command = "select isnull(SUM(nrLocuri),0.00 )as result from Rezervari where idRand = #idRand and idShow=#idShow";

Related

How to access the first column in SQL and why does this code give me error?

Can someone tell my why my expectedNumber reader throws an error
The name reader does not exist in its current context
As far as I can see all this is doing is reading the first row and first column, don't understand why the reader is throwing a tantrum.
It doesn't like the line:
ExpectedNumber = reader.GetInt16(0);
The query is :
SELECT TOP (1) [ExpectedNumber]
FROM [dbo].[MyDatabase]
WHERE id = '{0}'
Code:
try
{
using (SqlCommand cmd = new SqlCommand(string.Format(Query, id), Connection))
{
Connection.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
// Check is the reader has any rows at all before starting to read.
if (reader.HasRows)
{
int ExpectedNumber = 0;
// Read advances to the next row.
while (reader.Read() == true)
{
// To avoid unexpected bugs access columns by name.
ExpectedNumber = reader.GetInt16(0);
}
Connection.Close();
return ExpectedResult;
}
Assert.Fail("No results returned from expected result query");
return 0;
}
}
}
catch (Exception e)
{
Connection.Close();
throw;
}
You should escape your query parameters, otherwise your code is vulnerable to SQL injection attacks, also, by using command parameters as in the example below you can make sure you are using the right data type (it seems you are trying to pass an int id as a string).
You are just trying to get one value so you don't need to use a reader and can use ExecuteScalar instead.
Finally, you don't need to handle closing the connection if you enclose it in a using block so you can avoid the try catch block as well.
string query = "SELECT TOP (1) [ExpectedNumber] FROM [dbo].[MyDatabase] WHERE id = #id";
using (var connection = new SqlConnection("connStr"))
{
connection.Open();
using (var cmd = new SqlCommand(query, connection))
{
cmd.Parameters.Add("#id", SqlDbType.Int).Value = id;
object result = cmd.ExecuteScalar();
if (result != null && result.GetType() != typeof(DBNull))
{
return (int)result;
}
Assert.Fail("No Results Returned from Expected Result Query");
return 0;
}
}
Note: this code assumes you are using SQL Server, for other systems the format of the parameters in the connection string might change, e.g. for Oracle it should be :id instead of #id.

If the SELECT SQL Server value is null, the query takes 5 minutes C #

I have a very silly problem. I am doing a select, and I want that when the value comes null, return an empty string. When there is value in sql query, the query occurs all ok, but if there is nothing in the query, I have to give a sqlCommand.CommandTimeout greater than 300, and yet sometimes gives timeout. Have a solution for this?
public string TesteMetodo(string codPess)
{
var vp = new Classe.validaPessoa();
string _connection = vp.conString();
string query = String.Format("SELECT COUNT(*) FROM teste cliente WHERE cod_pess = {0}", codPess);
try
{
using (var conn = new SqlConnection(_connection))
{
conn.Open();
using (var cmd = new SqlCommand(query, conn))
{
SqlDataReader dr = cmd.ExecuteReader();
if(dr.HasRows)
return "";
return codPess;
}
}
}
You should probably validate in the UI and pass an integer.
You can combine the usings to a single block. A bit easier to read with fewer indents.
Always use parameters to make the query easier to write and avoid Sql Injection. I had to guess at the SqlDbType so, check your database for the actual type.
Don't open the connection until directly before the .Execute. Since you are only retrieving a single value you can use .ExecuteScalar. .ExecuteScalar returns an Object so must be converted to int.
public string TesteMetodo(string codPess)
{
int codPessNum = 0;
if (!Int32.TryParse(codPess, out codPessNum))
return "codPess is not a number";
var vp = new Classe.validaPessoa();
try
{
using (var conn = new SqlConnection(vp.conString))
using (var cmd = new SqlCommand("SELECT COUNT(*) FROM teste cliente WHERE cod_pess = #cod_pess", conn))
{
cmd.Parameters.Add("#cod_pess", SqlDbType.Int).Value = codPessNum;
conn.Open();
int count = (int)cmd.ExecuteScalar();
if (count > 0)
return "";
return codPess;
}
}
catch (Exception ex)
{
return ex.Message;
}
}

Always getting null value when checking the Database before inserting data

I have created a method to check the database every time data is added to it. The reason for this is to check for duplicate primary keys(manually generated).The problem I'm facing is that the method always returns null value even when the data exists in the database.
Here's my code :
public int checkComRegnumberAvailable(string conRegnumber)
{
using (SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd = con.CreateCommand();
cmd.CommandText = "SELECT RegNumber FROM OtherCompanyData";
con.Open();
//string result = ((string)cmd.ExecuteScalar());
string result = (string)cmd.ExecuteScalar();
cmd.ExecuteNonQuery();
if (result == null)
{
return 0;
}
if (result.Equals(conRegnumber))
{
return 1;
}
else
{
return 2;
}
}
}
You can to use a DataReader in order to retrive informatiom from your database. The link below shows a fine example of how to use it in your code.
https://msdn.microsoft.com/en-us/library/haa3afyz%28v=vs.110%29.aspx

DataReader IndexOutofRangeException was unhandled by user code

I ran into another issue again. I was trying to get data from the database using DataReader but I got the error when i was testing my code. Can anyone help me out? The error occurred at this line:
chkAssess = readAssess[columnName].ToString();
Below is the code snippet:
public string CheckAssess(string emailAddress, string columnName)
{
string chkAssess = "";
SqlDataReader readAssess;
//readAssess = new SqlDataReader();
string MgrAssessQry = "SELECT '"+columnName+"' FROM tblAllUsers";
//MgrAssessQry += " WHERE email ='" + emailAddress + "'";
SqlCommand cmdReadAssess = new SqlCommand(MgrAssessQry, cn);
cn.Open();
readAssess = cmdReadAssess.ExecuteReader();
while(readAssess.Read())
{
// Add the rows
chkAssess = readAssess[columnName].ToString();
}
return chkAssess;
}
try to use column name without ''
select something from table
instead of
select 'something' from table
for security reasons, don't create sql queries in that way (by concatenating strings) - use #parameters instead
2. close the reader at the end
Try this:
public string CheckAssess(string emailAddress, string columnName)
{
string chkAssess = "";
SqlDataReader readAssess;
//readAssess = new SqlDataReader();
string MgrAssessQry = "SELECT #Column_Name FROM tblAllUsers";
SqlCommand cmdReadAssess = new SqlCommand(MgrAssessQry, cn);
cmdReadAssess.Parameters.AddWithValue(new SqlParameter("Column_Name", columnName));
cn.Open();
readAssess = cmdReadAssess.ExecuteReader();
while(readAssess.Read())
{
// Add the rows
chkAssess = readAssess.GetString(0);
}
return chkAssess;
}
You have got several problems here.
Check whether your readAssess has rows like below.
if(readAssess.HasRows)
If it doesn't have rows then trying
chkAssess = readAssess.GetString(0);
would throw this error, as Arrays are index-based.
So your code should be like below
if(readAssess.HasRows)
{
while(readAssess.Read())
{
chkAssess = readAssess.GetString(0);
}
}
Other problem is you need to close both the reader & the connection afterwards.
readAssess.Close();
cn.Close();
Also your code is potentially vulnerable to SQL Injection.
if (reader.HasRows)
{
while (reader.Read())
{
int result = Convert.ToInt32(reader.GetString(0));
Console.WriteLine(result);
}
}
The most important thing is check the query first by executing in SQL Server and see if any result is coming or not.
Secondly based on the type of output you are receiving cast it to that particular data type (important).Mostly everyone is saving the data in varchar so.

ExecuteScalar if DBNull issue

I was trying to handle DbNull exception like this:
string sql_com_sumcastka = "SELECT SUM(price) AS sumprice FROM kliplat WHERE akce='" + zakce.Text + "' AND year=" + year;
SqlCommand sc2 = new SqlCommand(sql_com_sumprice, spojeni);
spojeni.Open();
if (sc2 != DBNull.Value)
{
int result = Convert.ToInt32(sc2.ExecuteScalar());
}
else
{
int result = 0;
}
spojeni.Close();
string sql_com_update_sum = "UPDATE zajezd SET s_prijmy=#s_prijmy WHERE akce='"+zakce.Text+"' AND year="+year;
SqlCommand sc3 = new SqlCommand(sql_com_update_sum,spojeni);
sc3.Parameters.AddWithValue("#s_prijmy", result );
spojeni.Open();
sc3.ExecuteNonQuery();
spojeni.Close();
But as I don't know how to properly handle if result is DBNull I get this erros: Operator '"=' cannot be applied to operands of type system.Data.SqlClient.SqlCommand and System.Dbnull
and
The name 'result' does not exist in the current context
My problem is this line of code:
if (sc2 != DBNull.Value)
{
int result = Convert.ToInt32(sc2.ExecuteScalar());
}
else
{
int result = 0;
}
Thanks for helping.
ExecuteScalar doesn't return DBNull (unless..., please read comments below) but null and you need to test the return value of ExecuteScalar not the SqlCommand that executes the command
int sumOfPrice = 0;
object result = sc2.ExecuteScalar();
if(result != null)
sumOfPrice = Convert.ToInt32(result);
From MSDN
ExecuteScalar returns the first column of the first row in the result
set, or a null reference (Nothing in Visual Basic) if the result set
is empty.
As a side note, do not use string concatenation to build a command text to pass to your database. You risk Sql Injection and parsing erroros. Use instead a parameterized query like this
string sql_com_sumcastka = "SELECT SUM(price) AS sumprice FROM kliplat " +
"WHERE akce=#zak AND year=#year";
SqlCommand sc2 = new SqlCommand(sql_com_sumprice, spojeni);
sc2.Parameters.AddWithValue("#zak", zakce.Text);
sc2.Parameters.AddWithValue("#year", year);
Here is the correct way to do that
var objResult = sc2.ExecuteScalar();
if (objResult != DBNull.Value && objResult != null )
{
int result = (int)objResult; //you can just do a normal cast, "SUM(X)" returns a int.
}
else
{
int result = 0;
}
A SqlCommand can never be compared to DBNull.Value in your example. What it sounds like you want is to check the result of your execute scalar invocation to see if that is null:
var result = sc2.ExecuteScalar();
if(result as DBNull == null)
{
// value is not null, do processing
}
I know the answer is late but this is the simplest answer that I have found
SELECT (SUM(price),0) FROM kliplat
If the result is null it will be replaced with 0

Categories