SQL Server date Format user dependent? - sql-server

I have a query with hard coded dates, in this format
startdate >= '2012-11-03' AND enddate <= '2012-11-30 23:59'
My database date format is 'mdy', however I'm sure it will accept yyyy-mm-dd as its the universal date structure.
When I try run this query in SSMS on my target DB connected with a specific database user (userX) I get an error about the date formats
Msg 242, Level 16, State 3, Line 1
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
However, when I run the exact query connected as the SA user, the query executes..
Why is this? I have given userX full dbo permissions (sysadmin etc) and still get the error?

If you need to specify datetimes using strings, you should use a safe, language-independent format.
In SQL Server, that's the ISO-8601 format (slightly adapted), and it supports basically two safe formats for DATETIME that always work - regardless of your language, regional and dateformat settings:
YYYYMMDD (e.g. 20121231 for 31st of December 2012) if you need date only
YYYY-MM-DDTHH:mm:ss (e.g. 2012-12-31T21:05:00 for 31st of December 2012, 9:05pm)
Note:
the first date-only format has no dashes or delimiters!
the second format has dashes for the date (can be omitted, too), and there's a fixed T as delimiter between the date and the time portion of the string
Update: as per your last comment (on the different default languages for the two users) - try this:
-- this is how your `SA` interprets the string as datetime....
SET LANGUAGE english
SELECT CAST('2012-11-30 23:59' AS DATETIME)
Works just fine...
-- this is how your British user interprets teh string as datetime
SET LANGUAGE british
SELECT CAST('2012-11-30 23:59' AS DATETIME)
Msg 242, Level 16, State 3, Line 7
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
This tries to interpret the string as 11th of the 30th month of 2012 and obviously, that fails....

consider using
startdate >= '2012-11-03' AND enddate < '2012-12-01'
instead

Related

How to insert Date values in Table in Microsoft SQL Server

I have created this table:
CREATE TABLE HUL
(
Company_name varchar(50),
Purchase_date date,
Quantity int,
Price float,
Age int,
profit_and_loss float
)
While I am trying to insert date values am getting an error. Am providing the insert query I have tried and the error as well
INSERT INTO HUL (Company_name, Purchase_date, Quantity, Price, Age, profit_and_loss)
VALUES ('Hindusthan_Unilever', '25-03-2022', 1, 1950.40, 125, 669.45);
Conversion failed when converting date and/or time from character string
INSERT INTO HUL (Company_name, Purchase_date, Quantity, Price, Age, profit_and_loss)
VALUES ('Hindusthan_Unilever', (CAST('25032022', AS DATE)), 1, 1950.40, 125, 669.45);
Incorrect syntax near the keyword 'AS'.
INSERT INTO HUL (Purchase_date)
VALUES ('25-03-2022');
Conversion failed when converting date and/or time from character string.
Can any one please me get the right query to fix this in Microsoft SQL Server.
SQL Server will happily parse strings into dates if they meet a certain set of formats.
Some of those formats depend upon your regional settings. For example, people in some parts of the world (mostly the USA) seem to like dates in month-day-year format, aka MM-dd-yyyy.
In other, slightly more sensible parts of the world people are used to day-month-year format, aka dd-MM-yyyy. This is what you are currently using.
But which of those SQL will accept depends on the regional settings of the system. It can't just accept both, because what would '01-02-2022' mean? Is it the first of Febrary, or the second of January? How can SQL Server know what you meant?
Then there are formats which are unambiguous. They only get interpreted one way no matter what your regional settings are. The simplest example is yearMonthDay, ie, yyyyMMdd. If you provide this format then the interpretation doesn't depend upon your regional settings. The value '20220201' is always interpreted as "the first of February".
So that explains the problem with your first query and your third query. In your second query you have an unnecessary comma. To fix the syntax error...
cast('25032022', AS DATE) -- no good, syntax error
cast('25032022' AS DATE) -- comma removed
But this would be interpreted as the value "22nd day of the 20th month (??) in the year 2503", because you have the numbers the wrong way around.
If necessary * you can force SQL to interpret text the way you want using set dateformat. Example:
set dateformat mdy; -- tell sql to read the text as month then day then year
select cast('01-02-2022' as date); -- SQL will now read this as January 2 2022
set dateformat dmy; -- now tell it to read it as day then month then year
select cast('01-02-2022' as date); -- now it's February 1, 2022
You can also "force" a particular interpretation using convert with a style argument, or try_parse with a culture.
* "Necssary" here meaning "you might not have the option of changing the incoming format, because developers aren't normally the ones adding data, users are, and you could be receiving the data in a csv, or by some other mechanism over which you have no control, but from which you still need to ingest"
One thing to understand here is different cultures and languages have different expectations around how dates are formatted.
SQL is no different. It is its own language, and just like any other language it has its own native date format for string literals. When writing SQL, it’s wrong to put your own cultural expectations into this very different language.
So for dates in SQL Server, the correct format is yyyMMdd (no separators). For dates with a time component, there are two accepted formats: yyyyMMdd HH:mm:ss[.fff] and yyyy-MM-ddTHH:mm:ss[.fff]. Anything else is not correct and there are times of the year when the value will be interpreted incorrectly.
Of course, this assumes you're including the the value as a literal in the string. If you're building this string in client code, it is never okay to use string concatenation to include these values in the SQL in the first place. Instead, you must always use parameterized queries/prepared statements.
Done properly, this means a strongly-typed datetime object in whatever client platform you prefer, assigned to a strong-typed DateTime parameter value sent directly to the server, such that the datetime value is never at any point even converted to a string.
https://blogs.msmvps.com/jcoehoorn/blog/2022/07/13/sql-and-dates/
In SQL Server insert into keyword is used to add up some values in a table.
INSERT INTO HUL
(
Company_name,
Purchase_date,
Quantity,
Price,
Age,
profit_and_loss
)
VALUES
(
'A Worldwide Company',
'28-07-2022',
1000,
175.20,
35,
70.50
)

T SQL Conversion failed when converting date and/or time from character string from VARCHAR(MAX)

I'm using SQL Server 2014. I have a date stored as varchar(MAX) in the format of:
2019-02-18
However, I want it in the British format dd/mm/yyyy (103).
This is my SQL:
SELECT CONVERT(DATE, DateField, 103) AS "JobStartDate"
FROM tblTest
However, I keep getting this error:
Conversion failed when converting date and/or time from character string.
What am I missing?
Update: The date is initially stored as varchar max as it is coming from a 3rd party system. I have no control over this and I completly understand this is the wrong format, but this is what I have been given.
I have a date stored as varchar(MAX)
There's your problem right there.
Not only you are using the wrong data type to store dates, you are also using max which is a known performance killer.
The solution to the problem is to alter the table and store dates in a Date data type - but first, you must look up all the objects that depends on that column and make sure they will not break or change them as well.
Assuming this can't be done, or as a temporary workaround, you must first convert the data you have to Date, and then convert it back to a string representation of that date using the 103 style to get dd/mm/yyyy.
Since yyyy-mm-dd string format is not culture dependent with the date data type, you can simply do this:
SELECT CONVERT(char(10), TRY_CAST(DateField As Date), 103) As [JobStartDate]
FROM tblTest
Note I've used try_cast and not cast since the database can't stop you from storing values that can't be converted to dates in that column.
You want to format the DateField column and not convert it to date.
So first convert it to DATE and then apply the format:
SELECT FORMAT(CONVERT(DATE, DateField, 21), 'dd/MM/yyyy') AS JobStartDate
See the demo.

Load the date separated by '/' with the Datetime datatype in sql server

INSERT INTO PUZ_DATE_FORMAT
SELECT FORMAT(GETDATE(),'d', 'it-IT') AS ItalianDate
I get this error:
Msg 242, Level 16, State 3, Line 1
The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value.
My table contains only a single column of datetime datatype, and the format statement which I've written will give the output like 15/12/2017.
But when I try to insert a row into the table, it won't allow me to do so. It allows only dd-mm-yyyy format - not dd/mm/yyyy. Why?
Basically what you are trying to do is insert a string value to a Datetime field. In doing so, SQL Server try to cast the string to a datetime during the insert. If your string is in the Universal format (yyyy-MM-dd) it can successfully parse it without any issue. Else the string has to be in the datetime format as Server's culture.
I guess your Server's culture is en-US which has the date time format as "MM/dd/yyyy". With regarding to your date (15/12/2017) server thinks 15 is the month, 12 is the day and so on. Which is obviously falling.
If you tried this before 12th of the month, It can successfully cast, But to an incorrect value.
Further, you are not doing the right thing by, casting a Datetime to a string and then try to insert in to Datetime field. Try to store the raw Datetime in database and format accordingly when displaying in UIs.
Cheers,

Won't insert into DATETIME field due to out of range value - has worked on 100's of other records

A query I have pasted below fails with this:
Msg 242, Level 16, State 3, Line 1
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
It has inserted successfully for 100's of other records why is it erroring out with this particular one?
INSERT INTO [My].dbo.Table ([branch], [policyref], [receipt_email_received])
VALUES ('02', 'SCJY05PC01', '13/10/2015 13:46:00')
Cheers
The error is due to using a date format not supported by the current language, assuming that the 13 represents the day and not the month. The current date format is clearly mm/dd/yyyy but you are entering in a date in the format of dd/mm/yyyy.
SET LANGUAGE English;
SELECT CONVERT(DATETIME, '13/10/2015 13:46:00');
GO
-- The conversion of a varchar data type to a datetime data type resulted
-- in an out-of-range value.
SET LANGUAGE Spanish;
SELECT CONVERT(DATETIME, '13/10/2015 13:46:00');
GO
-- 2015-10-13 13:46:00.000
SET LANGUAGE English;
It should also be mentioned that it is possible that the current language (and hence date format) is correct, but that in this one case, the "month" and "day" numbers got switched. It could be either by accident or if the data is coming from various sources and this source was one that uses the dd/mm/yyyy format.
Another option is to tell SQL Server what the format of the date-string is when you convert, regardless of current language (i.e. culture) setting:
SET LANGUAGE English;
SELECT CONVERT(DATETIME, '13/10/2015 13:46:00', 103);
-- 2015-10-13 13:46:00.000
But again, if the other dates you have entered so far come back correctly when you select them from the table, then it is probably just this one particular value that is off.
More info about style numbers (i.e. the 103) here: CAST and CONVERT

Correct way of specifying a given date in T-SQL

I am writing some T-SQL which needs to enforce a minimum date value onto some null fields:
DECLARE #epoch DATETIME;
set #epoch='1900-01-01';
select min = ISNULL(ValidFromDate,#epoch)
Is the string '1900-01-01' always going to return a datetime of Jan 1 1900 in any environment or will SQL server try to parse the string according to local culture rules?
If that's not good enough, what is the recommended way of specifying a particular date/time in T-SQL?
The best format for string-based dates is the ISO-8601 standard format.
For DATETIME variables and columns, this is either YYYYMMDD (for dates without time; without any dashes!) or YYYY-MM-DDTHH:MM:SS (date + time).
Contrary to popular belief, YYYY-MM-DD for DATETIME variables is NOT language-/dateformat-independent! If you try this, the second CAST will result in an error:
SET LANGUAGE us_english
SELECT CAST('2011-07-20' AS DATETIME)
SET LANGUAGE british
SELECT CAST('2011-07-20' AS DATETIME)
but this will work:
SET LANGUAGE british
SELECT CAST('20110720' AS DATETIME)
This is the best format since it's indepdendent of your language and dateformat settings in SQL Server.
For SQL Server 2008 and columns of type DATE (just date - no time), the format can also be YYYY-MM-DD (with the dashes) and that works for all settings, too.
Why there is such a difference between DATE and DATETIME is beyond me - that's just the way it is for now!
See Tibor Karaszi's excellent The Ultimate Guide to the DateTime data types for even more details and examples.

Resources