I'm having a problem "Invalid time format" when I try to use bcp functions(bcp_sendrow/bind etc.) to insert into a table having a datetime column.
so as per googled examples, I populated a DBDATETIME structure, for example: if I wanted to populate 3rd august 2009, exactly 8am localtime, I'd populate the structure members like so:
dtdays=40026(num days since 19000101) and
dttime = 28800000 (num millisecs since midnight)
(Also having bound the var. as a SQLDATETIME)
if dttime is 7 digits wide(or less), then bcp suceeds(but obviously with a wrong time value (date part is ok) )
how can I sort this out? I've tried datetime2 /time etc. but nothing helped.
please help , all advice/ideas most appreciated.
(I'm using Sql server 2008, and (ODBC) sql native client 10.0)
thanks!
never mind.. got it finally (sort of)
-DBDATETIME::dttime (num of millisecs since start of day) needs to be DIVIDED by 3.333333..
that way you get to the closest value to represent your time. (the field width is only 7 digits wide)..this probably has something to do with datetime type being able to represent only 1/3rd of a sec. accurately....
anyways, I tried using datetime2 with ODBC bcp api , but couldn't make the time part work
please let me know if anyone finds a better way
thanks!
Related
I have a report to do, so I need to return a date from a datetime column, but it need to come only with the date from the column.
I am using the Microsoft SQL Server 2014. I've already tried to use CONVERT(name_of_the_column, GETDATE()) but I realised the it only works to return the current datetime from the server.
How can I do that?
Use CONVERT(DATE, <expression>).
create table t (dt datetime);
insert into t (dt) values ('2022-10-20 12:34:56');
select *, CONVERT(DATE, dt) from t;
Result:
dt (No column name)
----------------------- ----------
2022-10-20 12:34:56.000 2022-10-20
See example at db<>fiddle.
I prefer to use CAST instead.
CAST(name_of_the_field AS DATE)
I need to return a date from a datetime column
There are several things to cover in order to fully answer this.
First, if that really is a datetime column, something to understand here is datetime values will ALWAYS have a time component. It's even right there in the name. There is no way to return a datetime value that does not have a time portion. The closest you can get is casting to a string or date, but that's not really the same thing. Typically what happens instead is the time portion is truncated back to midnight (all 0s)... but that time portion is still there. That's where you see answers like this:
dateadd(dd, datediff(dd,0, name_of_the_column), 0)
or this:
CONVERT(varchar(10), name_of_the_column,101)
The next to thing to understand is the one thing you should not do is convert the date value to a string, as in the second example.
Because of cultural/internationalization issues, converting datetime or numeric values to and from strings is much slower and more error-prone than you'd like to believe. It's something to avoid, and probably best left to your client code or reporting tool.
A final consideration is datetime values NEVER have any time zone awareness (that would involve datetime2). So if there's anything on the client to show this in a local time it may be picking the wrong offset. Do that with a value where the time portion was already truncated, and you can end up with unexpected results.
Put all this together, and what you should do is CAST() to a DATE:
CAST(name_of_the_column AS DATE)
Now I have seen this comment on another answer with this recommendation:
keeps turning back time
This could be the time zone mismatch I've already mentioned, or it could also be that name_of_the_column is not really a datetime column in the first place, but rather a string/varchar column pretending to be a datetime column. In that case, the CAST() may be parsing the values with different cultural rules than you expect. It goes back to that whole "slower and more error-prone/something to avoid" thing again. Also in this is the case the schema is considered broken, and you really should fix it to use actual datetime or datetime2 values.
Speaking of "fix it", I also noticed the SQL Server 2014 tag. SQL Server 2014 has been fully end of life since 2019. That means it has not received any updates — not even critical security patches! — for several years now. It's dangerous and irresponsible to still be using it. Updating to a supported version is job #1 here.
I don't know why, but the only way that have returned the result I want to reach was using
CONVERT(VARCHAR, TB.COLUM, 103) AS 'NAME'.
But as mentioned before, this is not a good practice, and than I resolved to made do the convertion in the report tool of the system that am I working
I want to start by saying my SQL knowledge is limited (the sololearn SQL basics course is it), and I have fallen into a position where I am regularly asked to pull data from the SQL database for our ERP software. I have been pretty successful so far, but my current problem is stumping me.
I need to filter my results by having the date match from 2 separate tables.
My issue is that one of the tables outputs DATETIME with full time data. e.g. "2022-08-18 11:13:09.000"
While the other table zeros the time data. e.g. "2022-08-18 00:00:00.000"
Is there a way I can on the fly convert these to just a DATE e.g. "2022-08-18" so I can set them equal and get the results I need?
A simple CAST statement should work if I understand correctly.
CAST( dateToConvert AS DATE)
I was wondering if there was a way to store a date (example: 01/01/2013) as datetime without SQL Server CE adding the time (example: 12:00:00 AM).
I could always store it as the string "01/01/2013" but I really want to be able to compare the dates on querying the database.
I realize that as long as I only stored the date part, all of the times in the datetime field would have equal values (i.e. 12:00:00 AM), so comparing them wouldn't be a problem and I could just always ignore the time part, however, it seems ridiculous to have this unnecessary data appended to every entry in the table.
Is there a way to store only the date part of the datetime as datetime so that the dates can still be compared in the SQL query or do I just need to live with this overhead and move on?
Side Note:
I just spent the last 30 minutes searching Google and SO for an answer I was sure was already out there, but to my surprise, I couldn't find anything on this issue.
Update:
The conclusion I have come to is that I will just accept the time in the datetime format and let it always default to 12:00:00 AM by only adding the date part during the INSERT statement (e.g. 01/01/2013). As long as the time part always remains the same throughout, the dates will still be easily comparable and I can just trim it up when I convert it to string for screen display. I believe this will be the easiest way to handle this scenario. After all, I decided to use SQL for the power of its queries, otherwise, I might have just used XML instead of a database, in the first place.
No you really can't get rid of the time component. It is part of the data type defined by sql server. I was very annoyed by it until I found that I could still display the dates without the time using JQuery to reformat them with the date formatter plugi:
https://github.com/phstc/jquery-dateFormat
Good Luck!
select CONVERT(date, GETDATE())
How would you store a time or time range in SQL?
It won't be a datetime because it will just be let's say 4:30PM (not, January 3rd, 4:30pm).
Those would be weekly, or daily meetings.
The type of queries that I need are of course be for display, but also later will include complex queries such as avoiding conflicts in schedule.
I'd rather pick the best datatype for that now.
I'm using MS SQL Server Express 2005.
Thanks!
Nathan
Personally I would find this a reason to upgrade to 2008 which has a separate time datatype.
I would recommend still using a DateTime data type and ignoring the date values--ideally using the static MinDate for SQL (Google it). This will give you the benefits of working with a strongly typed field and the only cost will be a few extra bytes.
As for ranges, store them in two separate columns. Then you can subtract one from the other to determine the difference.
Edit: did some Googling.
SQL Server 2008 adds a Time data type, so you might want to consider that.
You can use SQL 2005's DateTime type and combine it with the CONVERT function to extract just the HH:MM:SS.MMM
SELECT CONVERT(VARCHAR(12), GETDATE(), 114) AS [HH:MI:SS(24H)] (Found on this handy-dandy page)
Different SQL versions support different minimum dates. You could use a static date that will be supported by all such as 1/1/2000, or you could use SQL 2005's minimum value of 1/1/1753 and append the time values to that startic day
So if you stick with 2005, pick your static date, like 1/1/2000, and store your times on it. So 1m:30s would be 2000-1-1 00:01:30.000, and 1h:15m would be 2000-1-1 01:15:00.000
You can then do Date2 - Date1 and get your result of (1h:15:m - 1m:30s) 2000-01-01 01:13:45.000. CONVERT it and you'll have 1:13:45.
You could store it as an int as 24 hour time and format as needed.
Or store it as a datetime with some fixed date and remove it as needed for display:
Jan 1 2000 4:30PM
I would go with datetime field as it gives you the power of all the datetime related functionality.
You might want to consider storing it as an int column representing the number of minutes since midnight. In your entity you could expose this as a TimeSpan (or int) representing the same thing. You'd only need to convert between your display values (time format) and the database value (minutes) in order to perform your queries and this could easily be done in your entity (TimeSpan.TotalMinutes, for example).
to me it sounds like you're developing a type of meeting scheduler or something to display the meetings.
i think that i would set it p with 2 columns MeetingStart and MeetingEnd, both as datetime fields. This way, you can determine the length of the meeting, and since you already have the date you can easily use it to display it on a calendar or something.
I have a database with DateTime fields that are currently stored in local time. An upcoming project will require all these dates to be converted to universal time. Rather than writing a c# app to convert these times to universal time, I'd rather use available sqlserver/sql features to accurately convert these dates to universal time so I only need an update script. To be accurate, the conversion would need to account for Daylight savings time fluctuations, etc.
A User Defined Function would allow you to write an SQL query that looks like this:
SELECT toUTC([MyDateColumn], [MyTimeZoneColumn]) FROM [MyTable]
Then you get universal times back from the server without a lot of ugly syntax in the query itself. Now you could build the UDF for this with regular SQL similar to what Chris posted, but SQL Server 2005 and later will let you build the UDF using CLR (.Net: C# optional) instead. It has much better support for dates and can do a better job taking timezones and daylight savings time into account.
check out the convert function and the getutcdate function?
http://msdn.microsoft.com/en-us/library/ms187928.aspx
Check out this link from CodeProject.com - it does exactly what you want: take a date and a time zone, pass them to a UDF, and get the date in UTC or any other time zone.
IMPORTANT: Check the comments of that article - the author wasn't allowed to revise the article after a certain point, and there is an updated version of the code used for the UDFs in the comments that addresses some issues not found in the original article code.
ALSO IMPORTANT: Don't use this for querying large data sets. It's perfectly fine for a one-time load into a database, or for returning a UTC date for a single row (like a user login table or what have you.)
If you want performance, the only really acceptable method for time zone conversion is to have a lookup table that handles every possible time zone conversion for every single hour in a year, with a case statement to handle rollovers between years (ie December 31 - January 1 or vice versa.) Yes, the table is huge, but the query performance is nil.
SQL Doesn't have anything built in for this.
Two ways would be the C# application (you mentioned you don't want) or writing a really complicated update statement with something like:
UtcDate = DATEADD(hour, CASE WHEN OriginalDate BETWEEN x AND y THEN 4
WHEN OriginalDate BETWEEN x2 AND y2 THEN 5 ... END, OriginalDate)
Note - I'd recommend the C# app plus something like TZ4Net to handle the conversion.