This happened today and it's the weirdest thing.
I'm using Entity Framework + LINQ to insert DB Values. There is a datetime column and it was working until 2016/04/01.
Today, when i insert some rows and tried to select them with:
Where BulletingDate = Convert(DateTime, '2016-03-01 00:00:00')
This works, but somehow now when i tried to insert values with this:
a.BulletingDate = DateTime.Parse(txtBulletinDate.Text);
entities.Auctions.Add(a);
entities.SaveChanges();
It adds datetime like: 2016-01-04 00:00:00.000
But Bulletin Date Text is: 2016-04-01 00:00:00
I can't seem to figure out.
Please Help.
Date formats are notoriously fragile; it's very easy for queries that you think are running YYYY-MM-DD to suddenly start doing YYYY-DD-MM or similar over something as minor as a different user logging in to the terminal.
Don't rely on dates passed into databases as strings being parsed exactly as you expect. Pass them in as date objects and you'll get much better results.
The datetime type in SQL Server uses fractional seconds. That's the .000 on the end.
If you can, I suggest switching to datetime2 in SQL Server 2008 and up, which has optional fractional seconds. If you don't need to track fractions of a second, then you can use datetime2(0). It plays nicely with C# DateTime.
Bouild your datetime object like this
DateTime x = new DateTime(2016,01,04);//year month day
so you dont have problems when passing it to entity framework
also if your string is in this format "20140104 00:00:00" you should be safe too (at least MSSQL have no problem with that format, not sure if C# is cool too)
Related
I have a program that is moving data between two tables in a database. For this, I am using a SQL query and the System.Data.SqlClient package.
All of a sudden, this query throws an error when executing.
SQLCommand.ExecuteNonQuery is throwing:
Conversion failed when converting date and/or time from character string.
I have isolated the line with the conversion to:
AND DATEDIFF(dd,GETDATE(),SUBSTRING(a.date, 1, 10))<14
where a.date is the datetime as varchar. The query is a INSERT-SELECT query, and if I run only the SELECT part, it works. Even more strange is that this query works perfectly fine to run in SSMS both with and without data found.
Have anyone else seen this case lately?
where a.date is the datetime as varchar.
well there's your main problem. If you are storing a date/time: use the appropriate storage type in the database. You have a wide range to choose from, for example date, smalldatetime, datetime and datetime2 - and: SQL Server will know how to correctly understand and work with that data.
Ultimately the problem here is that SUBSTRING(a.date, 1, 10) isn't giving a result that SQL Server understands as a date through implicit string conversion operations. This approach is a: inefficient, and b: brittle (especially between cultures), hence why you simply shouldn't do that. If you store the data appropriately: all the problems will go away.
However! You could also use CONVERT to tell SQL Server to interpret the string as a date/time, explicitly telling it the format you expect (as a number code), so that it stands a chance.
If your a.date (and substring) isn't in one of the supported formats: abandon all hope.
BTW; DATEDIFF(dd,GETDATE(),SUBSTRING(a.date, 1, 10))<14 is probably more efficiently done by way of calculating the start-date/end-date of your range once and just comparing with a comparison operator. GETDATE() won't change per row, so "14 days from now" won't change per row. This would make your query a lot more efficient, especially when combined with the correct date/time format - it becomes:
a.date <= #end -- or < #end, or > #end, or >= #end
which can use an index.
Interesting! "No changes has been made to the code, and no new data has entered the queried table since then."
So the question why it doesn't work as the same way really have a many choice for you
Your code just don't run into the problem date data before.
Application server have something changed like date region/culture so it affect the application way of seeing date when communicate with DB server
the 2. but from DB server e.g. Infra team upgrade/patch the DB server, the configuration is affect so this has problem with date format , update/patching Db cause the build-in functions too have upgraded behavior too!)
The statement in double-quote is false.
System.Data.SqlClient 's feature when process the query ?
and so on...
I think finding the causes just from this little information is the very difficult task.
From my little search ,you really should go diving into the query and data as the others tried to suggest.
Conversion failed when converting date and/or time from character string while inserting datetime
This question already has answers here:
Insert, select and update DateTime
(2 answers)
Closed 8 years ago.
I have a table with a Date type. And I want to insert the date in this format: dd-mm-yyyy (ex: 27/10/2014). I already tried with String but the problem is when i want do a search with 2 Dates the SQL just compare the days. I just realy need the day, month and year. And in C# i use DateTime.Now.ToShortDateString(); to retrieve the date and insert in the database.
I used that query to search the dates:
Query:
SELECT *
FROM [TABLE]
WHERE ([COLUMN] >= '25/10/2014' AND [COLUMN] <= '26/10/2014');
Its any way to save the data like the format i want? Then will be more easy to select the data I want.
Sorry for my english, please help thanks.
SQL Server doesn't store a DateTime in any string format - it's stored as an 8 byte numerical value.
The various settings (language, date format) only influence how the DateTime is shown to you in SQL Server Management Studio - or how it is parsed when you attempt to convert a string to a DateTime.
There are many formats supported by SQL Server - see the MSDN Books Online on CAST and CONVERT. Most of those formats are dependent on what settings you have - therefore, these settings might work some times - and sometimes not.
The way to solve this is to use the (slightly adapted) ISO-8601 date format that is supported by SQL Server - this format works always - regardless of your SQL Server language and dateformat settings.
The ISO-8601 format is supported by SQL Server comes in two flavors:
YYYYMMDD for just dates (no time portion); note here: no dashes!, that's very important! YYYY-MM-DD is NOT independent of the dateformat settings in your SQL Server and will NOT work in all situations!
or:
YYYY-MM-DDTHH:MM:SS for dates and times - note here: this format has dashes (but they can be omitted), and a fixed T as delimiter between the date and time portion of your DATETIME.
This is valid for SQL Server 2000 and newer.
If you use SQL Server 2008 or newer and the DATE datatype (only DATE - not DATETIME!), then you can indeed also use the YYYY-MM-DD format and that will work, too, with any settings in your SQL Server.
Don't ask me why this whole topic is so tricky and somewhat confusing - that's just the way it is. But with the YYYYMMDD format, you should be fine for any version of SQL Server and for any language and dateformat setting in your SQL Server.
The recommendation for SQL Server 2008 and newer is to use DATE if you only need the date portion, and DATETIME2(n) when you need both date and time. You should try to start phasing out the DATETIME datatype if ever possible
So in your concrete case, I would rewrite that query as:
SELECT *
FROM [TABLE]
WHERE ([COLUMN] >= '20141025' AND [COLUMN] <= '20141026');
to be independent of any language, regional or dateformat settings in SQL Server ....
Never ever save your date and datetime values as strings. And always parameterize your SQL. If you want to make it easy for yourself, use a micro-ORM like Dapper to simplify such operations:
var result = connection.Query(
"SELECT * FROM EXAMPLE where data between #lower and #upper",
new { lower = DateTime.Parse("10/25/14"), upper = DateTime.Parse("10/26/14") });
I also recommend you use concrete data types o return information from the database, so you will not be forced to use dynamic properties.
Yes, for example in MS SQL, you can save the data in datetime2 (or equivalent) and format it on the way out. This approach will allow you to compare the dates.
Steps you can take:
change the Data type for the column at hand from string to datatime
You can apply formatting on the date upon retrieving. For example, users from Europe will have different date structure from users in north America.
so i have a string "09/15/2014" and in c# it converts it to date:
DateTime from = Convert.ToDateTime(fromdate);
this outputs "9/15/2014" and when I send it over to sql I get this:
select convert(varchar, '9/1/2014 12:00:00 AM', 101)
which doesn't work for me because I need to keep any leading zero's.
help?
If you're worried about the string formats for dates with Sql Server, you're doing it wrong. As a comment to another answer indicates, SQL Server internally stores all dates in a machine-optimized numeric format that is not easily human-readable. It only converts them to a human-understandable format for output in your developer tools.
When sending dates to Sql Server, always use query parameters. In fact, when sending any data, of any type, to Sql Server in an SQL statement, always use query parameters. Anything else will not only result in formatting issues like your problem here, but will also leave you crazy-vulnerable to sql injection attacks. If you find yourself using string manipulation to include data of any type into an SQL string from client code, step away from the keyboard and go ask a real programmer how to do it right. If that sounds insulting, it's because it's so hard to understate the importance of this issue and the need to take it seriously.
When retrieving dates from Sql Server, most of the time you should just select the datetime field. Let client code worry about how to format it. Do you want leading zeros? Great! The Sql Datetime column will at some point be available in C# as a .Net DateTime value, and you can use the DateTime's .ToString() method or other formatting option to convert the value to whatever you want, at the client.
SQL queries use a date and time format which goes like this:
2014-09-15
That's year-month-day. As per the comments below, this may be different depending on the collation you have on your database (see Scott's comment for a more accurate way to describe this and get dates into this format).
DateTime's ToString method has an overload which takes a formatting string. So you can pass the format you want the string to be output to. Try it like this:
string queryDate = from.ToString("yyyy-MM-dd");
And see what you get. Use that on your query.
But if you really want this done right, use parameters. Like:
SqlCommand command = new Command(connection, "SELECT * FROM foo WHERE someDate = #date");
command.Parameters.AddWithValue("#date", from);
// where "from" is your DateTime variable from the code you've shown.
This will save you the trouble of DateTime to String conversions.
I am debugging a query that is getting built in C# maybe with EntityFrameWork - not sure - but it doesn't return any records although it should.
The query has some DateTime fields and they are like this:
personStartDate {4/3/2013 12:00:00 AM}
The value for Date is getting from user interface date picker but I guess it also defaults the time part to 12:00:00 AM somehow.
Then I go to SQL Server and view the table rows and values on their datatime field data looks like this example: '2013-04-23 09:20:38.897'
Do you see any obvious problem right there?
Also I am trying to take the generated SQL from my breakpoint in C# and post it to SQL Server to see what does it return so for a value like {4/3/2013 12:00:00 AM} I am replacing it with 2013-04-03 12:00:00.000 Is that even correct?
Formatting is irrelevant. Internally it won't be in a text format at all, and I'd hope that the query doesn't end up sending the query value to the database as text either.
If you're only interested in the date part, you need to say that in the query:
where foo.Start.Date == personStartDate
(for example - we don't know what your query looks like).
If your field in the database is logically just a Date but is currently a DateTime, you should consider changing your schema to match your logical data model. It'll make things simpler.
If you create a DateTime using DateTime.Today then the time part will default to midnight. That is what the date picker is doing.
Your database contains a time portion too. If that is incorrect you can convert it in sql: Best approach to remove time part of datetime in SQL Server
2013-04-03 12:00:00.000 is noon is 12:00:00 PM. You want 12:00:00 AM which is midnight. You should use 2013-04-03 00:00 in your test or 2013-04-03 or '3 April 2013'. Again, the time portion will default to 00:00.
To get the query to work in c# with the "bad" data in the database, make the query less precise by doing "less than tomorrow more than or equal to today" rather than "equals". Or make the database more precise by dropping the time part - then you can use "equals". If you are using Entity Framework and Linq-to-Entities you may need to use EF's DbFunctions
Ideally you should track down the inserts and updates that are setting the time in the database and stop that happening, then fix the existing data. Then you could change the data type in the database from DateTime to Date.
A Sql Server DateTime value is a pair of 32-bit integers. The first is the count of days from the SQL Server calendar's epoch (1 Jan 1900 00:00:00.000); the second is the count of milliseconds since start of day.
The string representation of that is dependent on (A) the default language setting for your SQL Server instance, (B) the current language setting for the session, (C) the current set dateformat setting, and probably a few other options I've forgotten.
If you care about the string representation, explicitly convert it to a string using convert(varchar(X),your-datetime-value-here,style) using the style of your choice.
Note that SQL Server Date and DateTime values are converted to/from System.DateTime values by the runtime.
I've found this from this link:
http://www.sqlite.org/datatype3.html
1.2 Date and Time Datatype
SQLite does not have a storage class
set aside for storing dates and/or
times. Instead, the built-in Date And
Time Functions of SQLite are capable
of storing dates and times as TEXT,
REAL, or INTEGER values:
TEXT as ISO8601 strings ("YYYY-MM-DD
HH:MM:SS.SSS").
REAL as Julian day
numbers, the number of days since noon
in Greenwich on November 24, 4714 B.C.
according to the proleptic Gregorian
calendar.
INTEGER as Unix Time, the
number of seconds since 1970-01-01
00:00:00 UTC. Applications can chose
to store dates and times in any of
these formats and freely convert
between formats using the built-in
date and time functions.date and time functions.
I'm a bit confused as to which I should use. I'm creating a Windows Forms C# application and will be using the built DateTime control.
Which option would best suit me? I think TEXT would, but maybe I'm mistaken. I'm new to SQLite.
Thank you.
I assume you are using System.Data.SQLite? Even if SQLite itself doesn't recognize datetime data type, this data provider recognizes it.
For example, if you use SQLiteDataAdapter to populate a datatable with a select statement, if the data type of a column is datetime, the returned datacolumn will be datetime.
There is limitation to the provider: it can't guess data type when your select contains more than one table. In this case, you can declare the returning data type yourself by prepending your query like this:
types [integer], [text], [boolean], [datetime];
select A.id, A.subject, B.isactive, B.due_date from ...
The provider stores the data as text like 2009-04-01 17:42:38.828125. SQLite is fine with this format, for example you can calculate the next day with:
select datetime('2009-04-01 17:42:38.828125', '+1 days');
EDIT: you specify data type as datetime like this:
create table C ( d datetime );
I have been using Text and haven't had any problem with it.