I'm performing a simple SELECT statement and I'm trying to return the value from a DateTime column from a SQL Server 2012 table. The problem is that when I return a NULL DateTime value I don't know how to manage this with my code below.
dtTrainingEnd = (DateTime)reader["TrainingEnd"];
I've searched for the last few days on an answer and cannot find something that will help me. I've found similar posts but still I cannot figure out how they can help me. Can you please explain how I can check to see if the datetime value returned from the database is NULL?
SqlConnection connRead = new SqlConnection(connReadString);
SqlCommand comm = new SqlCommand();
SqlDataReader reader;
string sql;
DateTime dtTrainingEnd = DateTime.Now;
int iTrainingSwipeID = 123;
sql = "SELECT TrainingEnd FROM TrainingSwipe WHERE TrainingSwipeID = " + iTrainingSwipeID;
comm.CommandText = sql;
comm.CommandType = CommandType.Text;
comm.Connection = connRead;
connRead.Open();
reader = comm.ExecuteReader();
while (reader.Read())
{
dtTrainingEnd = (DateTime)reader["TrainingEnd"];
}
connRead.Close();
If it might be null, you could use a nullable type... in this case, a DateTime? type:
while (reader.Read())
{
dtTrainingEnd = ((DateTime?)reader["TrainingEnd"]) ?? some_default_date;
}
connRead.Close();
Or just test for null if you'd rather do that:
while (reader.Read())
{
var endDate = reader["TrainingEnd"];
dtTrainingEnd = (endDate == null) ? some_default_date : (DateTime)endDate;
}
connRead.Close();
In both cases above, I assumed you want dtTrainingEnd to contain something if the date is NULL in the database, so some_default_date is some default DateTime.
Or if you want to leave dtTrainingEnd alone if the value is NULL, then just don't set it in that case:
while (reader.Read())
{
if ((reader["TrainingEnd"]) != null)
dtTrainingEnd = (DateTime)reader["TrainingEnd"];
}
connRead.Close();
*** Depending on how you connect to your db, you may have to replace null with DBNull.Value
With SQL you can do SELECT Coalesce(TrainingEnd,0) and if it is null, you would have a 1900-01-01 date...
Related
I have a database with the infos of the buyers of my product, but I would like it to send the value provided by the program to the database, if it is null, how can I do this?
Code:
I have a database with the infos of the buyers of my product, but I would like it to send the value provided by the program to the database, if it is null, how can I do this?
Code:
string comando = "SELECT COUNT(*) FROM tbl_usuario WHERE user=#Usuario AND pw=#Senha AND tipo=1";
var connection = new MySqlConnection(connString);
var cmd = new MySqlCommand(comando, connection);
cmd.Parameters.AddWithValue("#Usuario", usuario);
cmd.Parameters.AddWithValue("#Senha", senha);
var command = connection.CreateCommand();
connection.Open();
MySqlDataReader leitor = cmd.ExecuteReader();
while (leitor.Read())
{
hd_id = leitor["id"].ToString();
}
if (hd_id == null)
{
//Code i need here
}
int retorno = Convert.ToInt32(cmd.ExecuteScalar());
connection.Close();
There is quite a bit that has been lost in translation in this question, but from I think I am reading I think you want the ID from the database to be retrieved. But the query is just running a count command which will not contain that.
string comando = "SELECT COUNT(*) FROM tbl_usuario WHERE user=#Usuario AND pw=#Senha AND tipo=1";
should actually be
string comando = "SELECT id FROM tbl_usuario WHERE user=#Usuario AND pw=#Senha AND tipo=1";
As you are only returning 1 value (or null if no record match) then you do not need to use a reader; and you can read the return directly, and check for null
var sqlReturn = cmd.ExecuteScalar();
if (sqlReturn == null) { /* Code i need here */ }
else { hd_id = (int)sqlReturn; }
If I did not understand the question; please feel free to let me know and we'll see if we can get you fixed up.
C#
cmd.Parameters.AddWithValue("#Usuario", String.IsNullOrEmpty(usuario) ? DBNull.Value : usuario);
cmd.Parameters.AddWithValue("#Senha", String.IsNullOrEmpty(senha) ? DBNull.Value : senha);
I am trying to stop the default value date "01/01/1900"to be entered in the table when the value of the textbox is null.I don't need validation on the form null textbox is ok
Thanks
using (SqlConnection con = new SqlConnection(WebConfigurationManager
.ConnectionStrings["Molecular"].ConnectionString))
{
con.Open();
using (SqlCommand sc = new SqlCommand(#"Insert into ClinicalFollowUp (MBID, Diagnosis,
DateLastSeen, DateofDeath ) values(#MBID, Upper(#Diagnosis),
Convert (date, #DateLastSeen , 103), Convert (date, #DODeath, 103);", con))
{
sc.Parameters.AddWithValue("#MBID", txtMBID1.Text);
sc.Parameters.AddWithValue("#Diagnosis", txtDiagnosis.Text);
// Date Textbox
sc.Parameters.AddWithValue("#DateLastSeen", txtDateLastSeen.Text);
// Date Textbox
sc.Parameters.AddWithValue("#DODeath", txtDateDeath.Text);
}
con.close();
}
I'd do it this way, personally.
static public object ToDbNullableDate(this string s)
{
DateTime d;
var ok = DateTime.TryParse(s, out d);
return ok ? d : DbNull.Value;
}
Then in your code:
sc.Parameters.AddWithValue("#DateLastSeen", txtDateLastSeen.Text.ToDbNullableDate());
You should send the parameters in your command using
The correct data type (NOT as string and do not convert them in Sql Server!)
Specify the data type of the parameter
Specify the length of parameter data types where appropriate. I guessed at your string lengths in the schema, update it accordingly.
Execute the conversion as early as possible in your call stack. Ideally you have a control that is a datetime picker, maybe this can do the conversion for you OR if its a web api then let the serializer deserialize the request to the approriate types.
const string sqlStatement = #"Insert into ClinicalFollowUp (MBID, Diagnosis, DateLastSeen, DateofDeath )
VALUES(#MBID, #Diagnosis , #DateLastSeen, #DODeath);"
using (SqlConnection con = new SqlConnection(WebConfigurationManager.ConnectionStrings["Molecular"].ConnectionString))
using (SqlCommand sc = new SqlCommand( , con))
{
con.Open();
sc.Parameters.Add(new SqlParameter("#MBID", SqlDbType.VarChar, 100){Value = txtMBID1.Text});
sc.Parameters.Add(new SqlParameter("#Diagnosis", SqlDbType.VarChar, 2000){Value = txtDiagnosis.Text.ToUpper()});
// Date Textbox
sc.Parameters.Add(new SqlParameter("#DateLastSeen", SqlDbType.DateTime){Value = getSqlDate(txtDateLastSeen.Text)});
// Date Textbox
sc.Parameters.Add(new SqlParameter("#DODeath", SqlDbType.DateTime){Value = getSqlDate(txtDateDeath.Text)});
sc.ExecuteNonQuery();
}
// TO DO - validate culture information
public static object getSqlDate(string dateTime)
{
DateTime dt;
return !string.IsNullOrEmpty(dateTime) && DateTime.TryParse(dateTime, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt)
? (object) dt
: (object) System.DBNull.Value;
}
try like this:
if (string.IsNullOrWhiteSpace(txtDateLastSeen.Text)
{
sc.Parameters.AddWithValue("#DateLastSeen", DbNull.Value);
}
else
{
sc.Parameters.AddWithValue("#DateLastSeen", txtDateLastSeen.Text);
}
EDIT: IsNullOrWhiteSpace, as suggested, is a bit simpler.
I am trying to determine if a specific value exists in a Oracle database table.
I used a query with "select count(*)", "select count(1)" and select count(<col_name>)" but keep getting the wrong result. When I use SQL Developer and run the query I get zero for the count. However, in the DAL, I get 1. I am guessing it is returning the number of row rather than the count itself. I tried both executeScalar() and ExecuteReader().
public override bool zipExists(string sZipCode)
{
OracleConnection conn = new OracleConnection(this.OraDataConnectionString);
OracleCommand oraCmd = new OracleCommand();
decimal iNumEntries = 0;
string sQuery = "select count(ZIPCODEID) as ZipCount from ZIPCODE where ZIPCODE = :ZipCode";
SetOraCommandType(oraCmd, CommandType.Text, sQuery);
conn.Open();
oraCmd.Connection = conn;
oraCmd.BindByName = true;
AddParamToOraCmd(oraCmd, "ZipCode", OracleDbType.Varchar2, 11, ParameterDirection.Input, sZipCode);
using (OracleConnection cn = new OracleConnection(this.OraDataConnectionString))
{
oraCmd.Connection = cn;
cn.Open();
iNumEntries = (decimal)oraCmd.ExecuteScalar();
}
return iNumEntries > 0;
also tried:
OracleDataReader sqlReader = oraCmd.ExecuteReader();
try
{
if (sqlReader.Read())
{
if (sqlReader["ZipCount"] != DBNull.Value)
iNumEntries = Convert.ToInt16(sqlReader["ZipCount"]);
}
}
}
return iNumEntries > 0;
I try you code on my table but pointing to some column and giving a select count(EN_Qty) as ZipCount from PSLAT.FSDEV.dbo.PS_EN_GEN_INTFC_BI where EN_Qty = '2600' works on my end so where in the code exactly are you experiencing an issue..? fyi I replaced my table with your query and assigned a value to the where clause.. so you query looks right.. however I would do an order by query to see if you perhaps are missing a zipcode..also oraCmd.ExecuteScalar() returns only 1 row so make sure you are not returning more than one row..oracle is funny like that
change your code to the following
object bExists = oraCmd.ExecuteScalar();
var bexists = bExists != DBNull.Value && result != null;
or change your code to check for row.count > 0 if true then you know the zipcode was found. Remember when making changes to Sql scripts or stored procedures in Oracle, you need to Compile the changes otherwise the changes will be visible to you when looking at the code but not to the caller trying to execute the stored proc.
I couldn't find best solution when DateTime value is NULL.
I use this techinque When binding;
_ACTIVATION_DATE = dt.Rows[0]["ACTIVATION_DATE"] == DBNull.Value ? new DateTime(1970, 12, 30) : (DateTime?)dt.Rows[0]["ACTIVATION_DATE"];
When Inserting;
public void Insert()
{
string ad="";
string dd="";
if (ACTIVATION_DATE == null)
ad = "null";
else
ad = "'" + ACTIVATION_DATE + "'";
if (DEACTIVATION_DATE == null)
dd = "null";
else
dd = "'" +DEACTIVATION_DATE +"'";
string sSQL = "INSERT INTO LINE_INFO (ACTIVATION_DATE,DEACTIVATION_DATE,STATUS,PO,NOTES) VALUES (" + ad + "," + dd + "," + _STATUS.ToString() + "," + _PO.ToString() + ",'" + _NOTES.ToString() + "');SELECT ##IDENTITY AS LASTID";
}
Variables;
DateTime? ACTIVATION_DATE;
DateTime? DEACTIVATION_DATE;
What is the smart way to handle Null DateTime values?
When I find the solution I will write an article about this topic.
Why are you using new DateTime(1970, 12, 30) when you're already using a nullable DateTime? The whole point of nullable value types is that you don't need magic values like that.
I would possibly use:
_ACTIVATION_DATE = dt.Rows[0]["ACTIVATION_DATE"] as DateTime?;
That will automatically use the null value for any non-DateTime value. Of course, that means you'll get a null value instead of an exception if you accidentally have an integer or something like that. Alternatively:
object tmp = dt.Rows[0]["ACTIVATION_DATE"];
_ACTIVATION_DATE = tmp is DbNull ? null : (DateTime?) tmp;
Then for the insert statement, do not include values directly in your SQL. Use a parameterized insert statement, and then you can just use a null DateTime? value to insert a null value. No need to mess around with string formats.
DateTime? implies you're using a Nullable<DateTime> to store the value - so why not just use .HasValue and .Value?
You shouldn't insert values directly because you create possibility to SQL injections. Instead you should use parameterized queries:
using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "INSERT INTO table1 (column1, column2) VALUES (#param1, #param2)";
command.Parameters.Add("#param1", SqlDbType.DateTime).Value =
DateTime.TryParse(txtDate.Text, out d) ?
(object)d :
DBNull.Value // inserting NULL
...
connection.Open();
command.ExecuteNonQuery();
}
When binding:
object date = reader["date"]; // NULL or '2010-08-26'
txtDate.Text = Convert.IsDBNull(date) ? (DateTime)date : String.Empty;
// or
txtDate.Text = (reader["date"] as DateTime? ?? String.Empty).ToString();
The null handling i most cases depend on the business needs, in your case seams that You need to store some value, but the information that date is null sometimes is useful. Because something has not happened yet. So its hard to determine some good approach to null date handling.
In Your case what it could be done i to replace that new DateTime(1970, 12, 30) with a static const field called default date.
public const DateTime DEFAULT_DATE = new DateTime(1970,12,30);
public void Insert()
{
string activationDate = "null";
string deactivationDate= "null";
if (ACTIVATION_DATE != null) {
ad = string.format("'{0}'",ACTIVATION_DATE); //Hire should be some date format used
}
if (DEACTIVATION_DATE != null) {
ad = string.format("'{0}'",DEACTIVATION_DATE); //Hire should be some date format used
}
string sSQL = string.format("INSERT INTO LINE_INFO (ACTIVATION_DATE,DEACTIVATION_DATE,STATUS,PO,NOTES) VALUES ({0},{1},{2},{3},'{4}');SELECT ##IDENTITY AS LASTID",activationDate ,deactivationDate ,_STATUS,_PO,_NOTES);
Ps. You should not use this type of statement creation instead of this you should use SqlCommand and paramteres
I am using the following SQL query and the ExecuteScalar() method to fetch data from an Oracle database:
sql = "select username from usermst where userid=2"
string getusername = command.ExecuteScalar();
It is showing me this error message:
System.NullReferenceException: Object reference not set to an instance of an object
This error occurs when there is no row in the database table for userid=2.
How should I handle this situation?
According to MSDN documentation for DbCommand.ExecuteScalar:
If the first column of the first row in the result set is not found, a
null reference (Nothing in Visual Basic) is returned. If the value in
the database is null, the query returns DBNull.Value.
Consider the following snippet:
using (var conn = new OracleConnection(...)) {
conn.Open();
var command = conn.CreateCommand();
command.CommandText = "select username from usermst where userid=2";
string getusername = (string)command.ExecuteScalar();
}
At run-time (tested under ODP.NET but should be the same under any ADO.NET provider), it behaves like this:
If the row does not exist, the result of command.ExecuteScalar() is null, which is then casted to a null string and assigned to getusername.
If the row exists, but has NULL in username (is this even possible in your DB?), the result of command.ExecuteScalar() is DBNull.Value, resulting in an InvalidCastException.
In any case, the NullReferenceException should not be possible, so your problem probably lies elsewhere.
First you should ensure that your command object is not null. Then you should set the CommandText property of the command to your sql query. Finally you should store the return value in an object variable and check if it is null before using it:
command = new OracleCommand(connection)
command.CommandText = sql
object userNameObj = command.ExecuteScalar()
if (userNameObj != null)
string getUserName = userNameObj.ToString()
...
I'm not sure about the VB syntax but you get the idea.
I just used this:
int? ReadTerminalID()
{
int? terminalID = null;
using (FbConnection conn = connManager.CreateFbConnection())
{
conn.Open();
FbCommand fbCommand = conn.CreateCommand();
fbCommand.CommandText = "SPSYNCGETIDTERMINAL";
fbCommand.CommandType = CommandType.StoredProcedure;
object result = fbCommand.ExecuteScalar(); // ExecuteScalar fails on null
if (result.GetType() != typeof(DBNull))
{
terminalID = (int?)result;
}
}
return terminalID;
}
The following line:
string getusername = command.ExecuteScalar();
... will try to implicitly convert the result to string, like below:
string getusername = (string)command.ExecuteScalar();
The regular casting operator will fail if the object is null.
Try using the as-operator, like this:
string getusername = command.ExecuteScalar() as string;
sql = "select username from usermst where userid=2"
var _getusername = command.ExecuteScalar();
if(_getusername != DBNull.Value)
{
getusername = _getusername.ToString();
}
Check out the example below:
using System;
using System.Data;
using System.Data.SqlClient;
class ExecuteScalar
{
public static void Main()
{
SqlConnection mySqlConnection =new SqlConnection("server=(local)\\SQLEXPRESS;database=MyDatabase;Integrated Security=SSPI;");
SqlCommand mySqlCommand = mySqlConnection.CreateCommand();
mySqlCommand.CommandText ="SELECT COUNT(*) FROM Employee";
mySqlConnection.Open();
int returnValue = (int) mySqlCommand.ExecuteScalar();
Console.WriteLine("mySqlCommand.ExecuteScalar() = " + returnValue);
mySqlConnection.Close();
}
}
from this here
SQL NULL value
equivalent in C# is DBNull.Value
if a NULLABLE column has no value, this is what is returned
comparison in SQL: IF ( value IS NULL )
comparison in C#: if (obj == DBNull.Value)
visually represented in C# Quick-Watch as {}
Best practice when reading from a data reader:
var reader = cmd.ExecuteReader();
...
var result = (reader[i] == DBNull.Value ? "" : reader[i].ToString());
In my experience, there are some cases the returned value can be missing and thus execution fails by returning null. An example would be
select MAX(ID) from <table name> where <impossible condition>
The above script cannot find anything to find a MAX in. So it fails. In these such cases we must compare the old fashion way (compare with C# null)
var obj = cmd.ExecuteScalar();
var result = (obj == null ? -1 : Convert.ToInt32(obj));
If you either want the string or an empty string in case something is null, without anything can break:
using (var cmd = new OdbcCommand(cmdText, connection))
{
var result = string.Empty;
var scalar = cmd.ExecuteScalar();
if (scalar != DBNull.Value) // Case where the DB value is null
{
result = Convert.ToString(scalar); // Case where the query doesn't return any rows.
// Note: Convert.ToString() returns an empty string if the object is null.
// It doesn't break, like scalar.ToString() would have.
}
return result;
}
Always have a check before reading row.
if (SqlCommand.ExecuteScalar() == null)
{
}
This is the easiest way to do this...
sql = "select username from usermst where userid=2"
object getusername = command.ExecuteScalar();
if (getusername!=null)
{
//do whatever with the value here
//use getusername.toString() to get the value from the query
}
In your case either the record doesn't exist with the userid=2 or it may contain a null value in first column, because if no value is found for the query result used in SQL command, ExecuteScalar() returns null.
Alternatively, you can use DataTable to check if there's any row:
SqlCommand cmd = new SqlCommand("select username from usermst where userid=2", conn);
SqlDataAdapter adp = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
adp.Fill(dt);
string getusername = "";
// assuming userid is unique
if (dt.Rows.Count > 0)
getusername = dt.Rows[0]["username"].ToString();
private static string GetUserNameById(string sId, string connStr)
{
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(connStr);
System.Data.SqlClient.SqlCommand command;
try
{
// To be Assigned with Return value from DB
object getusername;
command = new System.Data.SqlClient.SqlCommand();
command.CommandText = "Select userName from [User] where userid = #userid";
command.Parameters.AddWithValue("#userid", sId);
command.CommandType = CommandType.Text;
conn.Open();
command.Connection = conn;
//Execute
getusername = command.ExecuteScalar();
//check for null due to non existent value in db and return default empty string
string UserName = getusername == null ? string.Empty : getusername.ToString();
return UserName;
}
catch (Exception ex)
{
throw new Exception("Could not get username", ex);
}
finally
{
conn.Close();
}
}
Slight conjecture: if you check the stack for the exception, it is being thrown then the ADO.NET provider for Oracle is reading the underlying rowset to get the first value.
If there is no row, then there is no value to find.
To handle this case execute for a reader and handle Next() returning false for the case of no match.
I Use it Like This with Microsoft Application Block DLL (Its a help library for DAL operations)
public string getCopay(string PatientID)
{
string sqlStr = "select ISNULL(Copay,'') Copay from Test where patient_id=" + PatientID ;
string strCopay = (string)SqlHelper.ExecuteScalar(CommonCS.ConnectionString, CommandType.Text, sqlStr);
if (String.IsNullOrEmpty(strCopay))
return "";
else
return strCopay ;
}
I have seen in VS2010
string getusername = command.ExecuteScalar();
gives compilation error,
Cannot implicitly convert type object to string.
So you need to write
string getusername = command.ExecuteScalar().ToString();
when there is no record found in database it gives error
Object reference not set to an instance of an object
and when I comment '.ToString()', it is not give any error. So I can say ExecuteScalar not throw an exception. I think anserwer given by #Rune Grimstad is right.
I had this issue when the user connecting to the database had CONNECT permissions, but no permissions to read from the database. In my case, I could not even do something like this:
object userNameObj = command.ExecuteScalar()
Putting this in a try/catch (which you should probably be doing anyway) was the only way I could see to handle the insufficient permission issue.
object objUserName;
objUserName = command.ExecuteScalar();
if (objUserName == null) //if record not found ExecuteScalar returns null
{
return "";
}
else
{
if (objUserName == DBNull.Value) //if record found but value in record field is null
{
return "";
}
else
{
string getusername = objUserName.ToString();
return getusername;
}
}
/* Select some int which does not exist */
int x = ((int)(SQL_Cmd.ExecuteScalar() ?? 0));
I used this in my vb code for the return value of a function:
If obj <> Nothing Then
Return obj.ToString()
Else
Return ""
End If
Try this code, it appears to solve your problem.
Dim MaxID As Integer = Convert.ToInt32(IIf(IsDBNull(cmd.ExecuteScalar()), 1, cmd.ExecuteScalar()))
I'm using Oracle.
If your sql returns numeric value, which is int, you need to use Convert.ToInt32(object). Here is the example below:
public int GetUsersCount(int userId)
{
using (var conn = new OracleConnection(...)){
conn.Open();
using(var command = conn.CreateCommand()){
command.CommandText = "select count(*) from users where userid = :userId";
command.AddParameter(":userId", userId);
var rowCount = command.ExecuteScalar();
return rowCount == null ? 0 : Convert.ToInt32(rowCount);
}
}
}
Try this
sql = "select username from usermst where userid=2"
string getusername = Convert.ToString(command.ExecuteScalar());