C# SQL Server compare date with string - c#

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

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;

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 + "')";

Related

Can't Select date range when months go from 'single' digit to 'double digit when querying SQLite Database

I am working on a new WPF project where a user can fill out fields to submit to an SQLite database in C#. Submission and retrieval of information from the database works fine until the user selects a date range that crosses from September to October and from December to January. Then no records are returned even if there are records in that date range. You can have a date range from January to September and October to December, but if you cross from single digit months to double digit months then nothing is returned.
I know SQLite apparently doesn't have "date" as a datatype but when I created my database it made it with "DATE" and didn't get any problems. I have also made it with "TEXT" but both have the same date range problem. I am using "System.Data.SQLite" to create and query the database.
my command string for querying consists of:
string cmdString = "SELECT * FROM " + table + " WHERE DATE >= '" + dateFrom + "' AND DATE <= '" + dateTo + "'";
dateFrom and dateTo strings formatted as "9/30/2019" and "10/31/2019"
I have tried formatting both dates as "MM/DD/YYYY" but that doesn't help.
I have tried using "BETWEEN" and it doesn't help.
I have tried using the "date" function in SQLite and it doesn't work in C# I guess.
My connection string is:
"data source=" + database + ";datetimeformat=CurrentCulture"
I cannot paste the whole code because it is related to my job.
UPDATE:
Thank you for the responses and answers. I got everything to work after changing my date format to fit SQLite. Another thing I missed was when getting the date text from my date picker widget in WPF it was obviously giving me single digits for dates like "9/1/2019" which caused and after I added in logic to add 0's to my SQLite converter function the date ranges can successfully be found.
I know SQLite apparently doesn't have "date" as a datatype but when I created my database it made it with "DATE" and didn't get any problems.
Unlike other databases the column type in SQLite is very flexible and has little bearing on the how the underlying data is stored. In short you can use virtually any type or even no type at all.
The column type ends of with a derived column type (type affinity) based upon a set of rules DATE, MY_DATE, A_DATE even RUMPLESTILTSKIN all end up with the catch-all NUMERIC type affinity.
However, type affinity doesn't play that much of a role. In fact in SQLite you can store any type of data in any column (bar 1 exception, that being the rowid or an alias of the rowid column).
See Datatypes In SQLite Version 3
However, SQLite does have very powerful date and time functions.
I have tried using the "date" function in SQLite and it doesn't work in C# I guess.
They are part of SQLite, they work with SQLite irrespective of the language used to invoke SQLite commands.
They don't work because of the format. Consider this snippet :-
CREATE TABLE IF NOT EXISTS anothertable (DATE);
INSERT INTO anothertable VALUES ('09/30/2019'),('2019-09-30'),('31/10/2019'),('2019-10-31');
SELECT *, date(DATE), datetime(DATE) FROM anothertable;
The result being :-
The Date and Time functions being useful if the date/time is stored in a recognised format as per :-
Time Strings
A time string can be in any of the following formats:
YYYY-MM-DD
YYYY-MM-DD HH:MM
YYYY-MM-DD HH:MM:SS
YYYY-MM-DD HH:MM:SS.SSS
YYYY-MM-DDTHH:MM
YYYY-MM-DDTHH:MM:SS
YYYY-MM-DDTHH:MM:SS.SSS
HH:MM
HH:MM:SS
HH:MM:SS.SSS
now
DDDDDDDDDD
As such it is likely best to utilise such formats.
Assuming you use 2019-09-30 (instead of 9/30/2019) then such dates are directly comparable that is WHERE DATE BEWTEEN 2019-09-30 AND 2019-10-31 would work as would
string cmdString = "SELECT * FROM " + table + " WHERE DATE >= '" + dateFrom + "' AND DATE <= '" + dateTo + "'"; (assuming that dateFrom and dateTo were so formatted).
The Reason why 9/30/2019 is greater than 10/31/2019 is that the comparison is textual so the character 9 is greater than the character 1 (comparison is over). Likewise 2/1/1700 is greater then 11/12/2099.
The alternative is to include some relatively complex manipulation e.g. :-
-- An example that would handle dd/mm/yyyy where dd and mm could be either 1 or 2 characters
WITH
-- First CTE gets the day and the rest of the date
ctedaypart AS (
SELECT
rowid AS daypartid,
substr(DATE,1,instr(DATE,'/')-1) AS day_part,
substr(DATE,instr(DATE,'/')+1) AS rest_after_day
FROM mytable
),
-- Second CTE gets the month and the rest of the date
ctemonthpart AS (
SELECT
daypartid AS monthpartid,
substr(rest_after_day,1,instr(rest_after_day,'/')-1) AS month_part,
substr(rest_after_day,instr(rest_after_day,'/')+1) AS year
FROM ctedaypart
),
-- Third CTE expands the day and month the have a leading 0 id less than 10 and joins the parts to form YYYY-MM-DD
expandedparts AS (
SELECT
*,
mytable.rowid AS expandedpartsid,
year||'-'||
CASE WHEN length(month_part) = 1 THEN '0'||month_part ELSE month_part END ||'-'||
CASE WHEN length(day_part) = 1 THEN '0'||day_part ELSE day_part END AS date_in_sqlite_format
FROM mytable JOIN ctedaypart ON mytable.rowid = daypartid JOIN ctemonthpart ON daypartid = monthpartid)
SELECT mytable.* FROM mytable JOIN expandedparts ON mytable.rowid = expandedpartsid WHERE (date_in_sqlite_format) BETWEEN ('2019-01-01') AND ('2019-03-31');

fetch date from datetime column in sql

I have a Product table.I want fetch date from datetime column.
I wrote this query.
Query code is here
SELECT Date = CONVERT(DATE, Date) FROM Product
Query is running sql server management studio and returning the correct date but when called from C# the query runs and returns a result but it returns datetime rather than just the date.
So for example if the query:
SELECT Date = CONVERT(DATE, Date) FROM Product
returns 09-02-16 in management studio
the C# code
SqlDataAdapter adr;
adr = new SqlDataAdapter("SELECT Date = CONVERT(DATE, Date) FROM Product", conn);
returns 09.02.2016 00:00:00
What I would like the C# code to return is: 09-02-16
Please help.
based on you comment you may want to try:
SqlDataAdapter adr;
adr = new SqlDataAdapter("SELECT [Date] = convert(VARCHAR,[Date], 5) FROM Product", conn);
The convert(datetime,[date], 5) will ensure you are returning the result as DD-MM-YY
Try with this SELECT CONVERT(date,[Date]) as date FROM Product
Date is a keyword in SQL, so I would avoid using it:
var adr = new SqlDataAdapter("SELECT CAST([Date] AS DATE) AS OnlyDate FROM Product", conn);
Your query is certainly wrong. either you want to do
SELECT CONVERT([DATE], 102) FROM Product
(OR) declare a variable and store the data there like
DECLARE #Date DATETIME;
SELECT #Date = TOP 1 CONVERT([DATE], 102) FROM Product
Assuming you have a column named DATE and you will have to use a proper format string unless you are passing format string as parameter. Though your query is bit unclear.
c# code is running result : 23.11.2015 00:00:00
How are you seeing this and where? In the debugger in VS? On the screen?
It is probably just formatting based on your culture (the one set on your PC). You are probably not understanding the difference between viewing the string representation in C# of a DateTime object, which can be formatted based on your locale, and the default ISO formatting in Sql Server.
Also there is no such thing in c# as just a date object, its always a date with time (DateTime) although the time component will then have 0 values for the time aspects of the object.
In short it is probably working the way it should.
Based on your comment:
I don't have an error. Query code running result: 2015-11-23. But c#
code is running result : 23.11.2015 00:00:00
I assume that your query is already working properly.
However, the format of the date is different!
So all you need to do is to convert the DateTime in your wished format.
Note: Per default the culture of your thread is based on the settings of your computer (In your case, it's dd.MM.yyyy). The result of the query on SQL Management Studio is depending on the column you are selecting (In your case: yyyy-MM-dd).
True code is here :
SqlDataAdapter adr;
adr = new SqlDataAdapter("SELECT LEFT(CONVERT(VARCHAR, Date, 120), 10) from Product", conn);

datetime query in SQL

I have to write a query to get rows where date is like current date.
I don't want to compare the the time part but only date part.
Like today's date is 2014-05-03
but in table its in datetime as 2014-05-03 10:08:22
i tried [http://www.w3schools.com/sql/func_convert.asp]
but could not do anything..
my query is like
select *from dbo.param where cvdatetime like '2014-05-03%';
but its does not work although if i use
select *from dbo.param where cvdatetime like '%2014%';
it works so i don't get why "like" can't work in the previous case
i just want to compare the date part only not the time part..
like in c# i will take the current date as
string today_n = DateTime.Now.ToShortDateString();
which will give only today's date
the query will be like
string query="select *from dbo.param where cvdatetime like '" + today_n + "%'"
what is the correct way?
also i want that whatever be the system date format query should work like even if system date time format is dd-mm-yyyy hh:mm:ss tt the query should work how can i ensure this?
Adding new requirement what if I need to check date hh:mm: only not seconds
i.e, 2014-05-04 12:00: part only not seconds part
You cannot use like as such on datetime column.
Use the below:
select * from dbo.param where convert(varchar, cvdatetime, 120) like '%2014%';
As, far your second question is concerned, you'll have to use parameterized queries to avoid sql injection attacks.
Using SQL Server 2005 or later, just convert the datetime to date:
select *
from dbo.param
where cast(cvdatetime as date) = '2014-05-03';
Do not think about dates as strings. Think of them as dates, with the string format only used for output purposes. Or, if you have to make an analogy to another type, think numbers. As an example, go into Excel, put a date into a cell. Nicely format it. Then set another cell equal to the value of the first cell (=A1 for example). Format that as a number and you will see some strange number, probably in the range of about 40,000. Excel stores dates as number of days since 1970-01-01. SQL has a similar (but different) storage mechanism.
You can use the following for the current date:
SELECT *
FROM dbo.param
WHERE CONVERT(DATE, cvdatetime) = CONVERT(DATE, GETDATE())

How to use DateTime with SQL queries?

How should I be using c# datetime values in my C# queries?
Up until now I've been doing the following:
Datetime my_time = new DateTime(2012, 09, 05);
cmd.Parameters.AddWithValue("#date", my_time);
cmd.CommandText = "SELECT * FROM sales WHERE date = #date";
Which has been working fine until this morning when I've been getting null errors when retrieving values from the results set.
I changed my date parameter to grab the short date string from my datetime value like this:
cmd.Parameters.AddWithValue("#date", my_time.ToShortDateString());
And it appears to be working fine again.
What is the correct way of doing this? Obviously I'm converting my datetime value to a string, only (presumably) for the database to convert it back to a datetime before evaluating my equality where clause, which seems a little pointless.
Edit:
I'm using SQL Server Compact Edition and the date field in my example has a precision setting of 8 (date, excluding time right?). Does that mean I was passing the full date with 00:00:00.000 on the end before? How might I pass a datetime value to the database without including the time, without converting to a string first?
You can just try with my_time.Date
cmd.Parameters.AddWithValue("#date", my_time.Date);
Do not pass it as a string or will run in troubles with culture formatting.
Try using SqlDateTime instead.
You're not converting the date to a string - AddWithValue knows it is a date, but it is a datetime, so it has a time component. Do your sales have a time component to them?
SELECT * FROM sales WHERE DateDiff(d, #date, date) = 0

DATE datatype of SQL Server 2008 returing time!

I have a column of datatype DATE in SQL Server 2008, which stores only the date in format "yyyy-MM-dd" but when I select the date from database via C# and converting into string, it shows the time part also like.
"2012-04-21 12:00:00"
what is the problem I didn't store time in database here is my query!
string sql = #"select card_no, amount, csc,expdate " +
"from user_account_card " +
"where user_id = '" + loginsession.Auser + "';";
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader red = cmd.ExecuteReader();
while (red.Read())
{
loginsession.Cardno = Convert.ToString(red["card_no"]);
loginsession.Cardamount = Convert.ToString(red["amount"]);
loginsession.Csc=Convert.ToString(red["csc"]);
loginsession.Expdate = Convert.ToString(red["expdate"]);//date part
break;
}
MessageBox.Show("database value from database--" +loginsession.Expdate);
Please help me what to do
If the time is showing as midnight then for all intents and purposes it is storing it without time.
SQL has a date data type that does not include time, but you need to re-design the table. Not sure if you need/want to do that.
You could also try this:
((Date)red["expdate"]).ToString();
Since this will convert to a Date data type and not a DateTime data type you should just see the date part in the returned string.
Convert.ToString doesn't have a "date" overload, only "datetime"
SQL Server 2008 will store just date in a DATE column - you can easily verify that in SQL Server Management Studio. Also: a DATE column doesn't store a date in a particular string format - that's just how you see it. A date is a date is a date - it's stored as a date and doesn't have any "format" per se.
However, .NET doesn't have a "date-only" datatype, so reading a DATE column from SQL Server ends up in a DateTime variable in .NET which contains DATE and TIME.
So it's really not an issue of SQL Server here - but rather an issue in .NET

Categories