1

I have to compare a table field that is a date stored as varchar in the format 'dd/MM/yyyy' with a date value, but the comparison fails. I have exception

Conversion failed when converting date and/or time from character string. I tried converting the date to compare i nstring, like this

string dateFormat = date.ToString("dd/MM/yyyy");

and then write the query like this:

string sql = "select * from TB_RICHIESTE where CONVERT(DATE, Date) <= CONVERT(DATE, '" + dateFormat + "')";

But I have this excpetion. Someone can help me? Thanks

Alfredo Torre
  • 678
  • 1
  • 9
  • 25
  • 6
    *Don't*. Use the proper type for the field *and* the parameter. And don't construct SQL statements by concatenating strings. Use parameterized queries – Panagiotis Kanavos Oct 26 '17 at 09:03
  • If the *table* has a date in the form `dd/MM/yyyy` there's a very serious bug. The field's type should be corrected to `date`. You can't sort by such a field or search for date ranges, eg dates after a specific date – Panagiotis Kanavos Oct 26 '17 at 09:06

2 Answers2

5

First, you should not store dates as strings.
As Panagiotis Kanavos wrote in his comment - this is a serious bug. You can't sort by such a column, you can't search for date ranges, and most important - you can't control if someone enters an invalid value - nothing is stopping someone from entering "Alfredo" to that column.
For more information, read Aaron Bertrand's Bad habits to kick : choosing the wrong data type.

Second, you should not pass dates from .Net to Sql server as strings. you should pass instances of DateTime as parameters. The .Net DateTime maps directly to SQL Server's Date.

If you can't change the data type of the column, you can at least convert it to date using the proper convert style (103 in your case).

Here is a better way to do it:

var sql = "select * from TB_RICHIESTE where CONVERT(DATE, [Date], 103) <= @Date";

Then you add the @Date parameter to the SqlCommand:

com.Parameters.Add("@Date", SqlDbType.Date).Value = date.Date;
Community
  • 1
  • 1
Zohar Peled
  • 79,642
  • 10
  • 69
  • 121
  • Slightly better: `... .Value = date.Date;`. Then it works even if the type in the database is(or will be) `DateTime`. – Tim Schmelter Oct 26 '17 at 09:16
  • @TimSchmelter I'm already converting the data type of the column to `Date`, and the data type of the parameter is also `Date`. I don't see how sending `date.Date` instead of simply `date` would change anything. – Zohar Peled Oct 26 '17 at 09:17
  • Perfect solution. Thanks – Alfredo Torre Oct 26 '17 at 09:19
  • Glad to help :-) – Zohar Peled Oct 26 '17 at 09:20
  • @ZoharPeled: it wouldn't change and it wouldn't hurt. Your code would hurt if OP changes to `DateTime` and then changes `SqlDbType.Date` to `SqlDbType.DateTime`. With my little change that won't cause any harm. You are relying on the database, i'm relying on database and C# – Tim Schmelter Oct 26 '17 at 09:31
  • @TimSchmelter: Well, I can't be held responsible for changes the OP *might* make. I gave the best answer I could, and that particular change in the code, if that's the *only* change, will not make it better. – Zohar Peled Oct 26 '17 at 09:34
  • @ZoharPeled: why you feel attacked, i have upvoted your good answer. Call me paranoid but i like to pass the correct value and not the value that will hopefully reach the database. It's important to store the correct type in the databse and it's important to pass the correct type and value. I find it inaccurate to filter by a value `10/26/2017 11:38:42` when i want to filter by `10/26/2017 00:00:00`. Even if it works because of the target type it's not the best approach. What's your problem with using `date.Date`? – Tim Schmelter Oct 26 '17 at 09:40
  • @TimSchmelter I don't feed attacked, sorry if my previous comment seems too defensive. I understand your point about passing the correct value in the first place. I still think it's redundant in this particular case but if it will make you feed better I've edited my answer to reflect your comment. – Zohar Peled Oct 26 '17 at 09:43
0

Use Parameter to pass date values refer @Zohar Peled post. This is the proper method handling date values. OR You can pass the date value in ISO format, refer the below code.

string dateFormat = date.ToString("yyyy/MM/dd");


string sql = "select * from TB_RICHIESTE where CONVERT(DATE, Date) <= CONVERT(DATE, '" + dateFormat + "')";
Sandeep
  • 413
  • 4
  • 13
  • First, this is not ISO format. If you have to pass string literals for dates, use `yyyy-mm-dd` or better yet `yyyymmdd`. Second, concatenating strings into SQL statements is risky, since it's an open door for SQL Injection attacks. Might not be the case here but it's always better to use parameters instead of concatenating strings. – Zohar Peled Oct 26 '17 at 09:29
  • If the real ISO or the unseparated format are used there's no reason to convert the *parameter*. Converting the *field* is a bad idea that prevents the database from using indexes and results in a full table scan – Panagiotis Kanavos Oct 26 '17 at 09:43