views:

69

answers:

3

I have a search page, which has Date text field. The user may or may not populate this field. But the field is a parameter of a SQL stored proc that gets called to execute the search query.

When I walk through the code (and the Date field is blank), I get an error that the value could not be converted to DateTime

How can I convert a null value to DateTime, since the parameter is expected by the query?

cmdSearch.Parameters.Add(new SqlParameter("@StartDate", SqlDbType.DateTime));
cmdSearch.Parameters["@StartDate"].Value = Convert.ToDateTime(txtStartDate.Text.Trim());
+2  A: 
cmdSearch.Parameters["@StartDate"].Value = 
    String.IsNullOrEmpty(txtStartDate.Text) ? SqlDateTime.MinValue : 
        Convert.ToDateTime(txtStartDate.Text.Trim()); 

That will check to see if the Text is null or an empty string before trying to parse the value.

Be sure to use the SqlDateTime structure instead of DateTime since the two have vastly different MinValues.

Keep in mind that this will not fix cases where the TextBox has text that is not in proper date format. You will keep getting Exceptions in those cases!

Justin Niessner
Depending on how the sproc is implemented, you may want to use DateTime.MinValue (or MaxValue) instead of DBNull.Value. It all depends on how the sproc handles it. If it supplies a default value if one isn't supplied, then leaving it out is an option as well.
tvanfosson
I understand the date format issue. I will create validation for that.However, I get an error when I try out your code:Type of conditional expression cannot be determined because there is no implicit conversion between 'System.DBNull' and 'System.DateTime'
user279521
@user279521 - Updated my answer to pass MinValue instead of null.
Justin Niessner
+4  A: 

Wrap an if statement around the whole thing and test to see if String.IsNullOrEmpty(txtStartDate.Text)

EDIT

This is what I meant by, "whole thing" - apologies for not being clearer

if (!String.IsNullOrEmpty(txtStartDate.Text))
    cmdSearch.Parameters["@StartDate"].Value = Convert.ToDateTime(txtStartDate.Text.Trim());
else
    cmdSearch.Parameters["@StartDate"].Value = DateTime.MinValue;
Ardman
+1, assuming by whole thing you mean the part that adds the startdate parameter. If it is null you have a choice. Either don't pass the parameter at all, or pass it in with a null or some other default value. If you elect to not pass it, make sure the s'proc has a default value assigned in the parameters section. Something like "@StartDate datetime = null"
Chris Lively
Wrapping the whole thing in an if statement will result in the parameter missing from the query. You still need to add the parameter, but set the value to null if the text is empty.
Justin Niessner
Correct Justin. I thought of the if statement, but then the parameter would get left out;
user279521
@Ardman - Your code could be much more compact using the conditional operator to set the Value. This seems very verbose. Also, you should pass SqlDateTime.MinValue instead of simply DateTime.MinValue.
Justin Niessner
@Justin Niessner: Thanks for the comment, and I do compact my code. But, I'm trying to give a simplistic view of what I was trying to achieve.
Ardman
@Justin, @user279521: it's OK to leave parameters out of the call to a s'proc.. As long as the s'proc has a default value specified in its definition.
Chris Lively
@Chris Lively - That's true, but nowhere in the post does in say the parameter is optional at the Stored Procedure. It's just optional at the UI.
Justin Niessner
My bad Justin. The proc does have a default value of null.
user279521
+1  A: 

If you set the parameter in the SQL proc as an optional parameter, by supplying a default value

CREATE PROCEDURE MyProc
...
@StartDate datetime = null,
....

them you can just omit sending that parameter from the c# code

DateTime result;
if (DateTime.TryParse(txtStartDate.Text, out result))
{
   cmdSearch.Parameters.Add(new SqlParameter("@StartDate", SqlDbType.DateTime));
   cmdSearch.Parameters["@StartDate"].Value = result;
}

If the parsing of the text field is unsuccessful, the parameter is not added in the parameter list, and the database uses the default value.

Also, using DateTime.TryParse(..) prevents dealing with exceptions.

SWeko
I think you nailed it dude !! So far your comment "If the parsing of the text field is unsuccessful, the parameter is not added in the parameter list, and the database uses the default value." I thought a parameter had to be passed in all circumstances. Learned something today!
user279521
Thx. One caveat that I would like to point out, that from a design perspective this couples the database procedure and the data layer code, so it might be a bit less maintainable. On the other hand, changing the default passed value requires just a proc update, and not a code recompile.
SWeko