Convert nvarchar(MAX) to datetime
I have a table with couple of fields nvarchar(MAX)
which occupies date in dd/mm/yyyy
format.
I run this query:
SELECT CONVERT(datetime,[Start Date],103)
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
And I get error:
The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value.
The weird thing is that when I run this query like:
SELECT TOP 40 CONVERT(datetime,[Start Date],103)
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
It works but I don't want the TOP X
.
My table contains only 36 records. so i don't think that there is bad data.
20/03/2013
20/03/2013
10/03/2013
10/03/2013
11/03/2013
06/03/2013
06/03/2013
21/03/2013
12/03/2013
03/03/2013
18/03/2013
04/03/2013
28/02/2013
28/02/2013
28/02/2013
28/02/2013
31/01/2013
15/01/2013
23/01/2013
23/01/2013
31/01/2013
23/01/2013
30/01/2013
31/01/2013
24/01/2013
24/01/2013
24/01/2013
24/01/2013
24/01/2013
30/01/2013
23/01/2013
22/01/2013
23/01/2013
23/01/2013
23/01/2013
23/01/2013
Can someone help me with that?
sql sql-server
|
show 10 more comments
I have a table with couple of fields nvarchar(MAX)
which occupies date in dd/mm/yyyy
format.
I run this query:
SELECT CONVERT(datetime,[Start Date],103)
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
And I get error:
The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value.
The weird thing is that when I run this query like:
SELECT TOP 40 CONVERT(datetime,[Start Date],103)
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
It works but I don't want the TOP X
.
My table contains only 36 records. so i don't think that there is bad data.
20/03/2013
20/03/2013
10/03/2013
10/03/2013
11/03/2013
06/03/2013
06/03/2013
21/03/2013
12/03/2013
03/03/2013
18/03/2013
04/03/2013
28/02/2013
28/02/2013
28/02/2013
28/02/2013
31/01/2013
15/01/2013
23/01/2013
23/01/2013
31/01/2013
23/01/2013
30/01/2013
31/01/2013
24/01/2013
24/01/2013
24/01/2013
24/01/2013
24/01/2013
30/01/2013
23/01/2013
22/01/2013
23/01/2013
23/01/2013
23/01/2013
23/01/2013
Can someone help me with that?
sql sql-server
3
You need to check your data. There is a row containing bad date. TOP 40 misses it by chance.
– Nikola Markovinović
Mar 12 '13 at 10:21
1
It means your top 40 records having valid value so it convents them. some of records may have invalid data in that column
– Sachin
Mar 12 '13 at 10:21
2
It is a view, right? And it operates on larger table? Please check Short circuit section of this document.
– Nikola Markovinović
Mar 12 '13 at 10:29
3
Sql Server Query optimizer is free to choose order of execution. Views are expanded into query you submitted, so your query works on all the rows before they are filtered (even by view). In this particular case sql server runs ahead converting values it should not convert because they will not be included in final result. To solve, change convert tocase when isdate([Start Date]) = 1 then convert (...) else null end
. But do read the article I had linked.
– Nikola Markovinović
Mar 12 '13 at 10:37
3
Why, oh why, oh why are you storing datetimes inNVARCHAR(MAX)
? Do you need Unicode support? Are you going to have dates with 1 billion characters? Do you care if people enterd/m/y
orm/d/y
or2013-02-32
oris this a date?
into that column? Because they can. Do it right. Use the right data type (in this case probablyDATE
).
– Aaron Bertrand
Mar 12 '13 at 13:03
|
show 10 more comments
I have a table with couple of fields nvarchar(MAX)
which occupies date in dd/mm/yyyy
format.
I run this query:
SELECT CONVERT(datetime,[Start Date],103)
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
And I get error:
The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value.
The weird thing is that when I run this query like:
SELECT TOP 40 CONVERT(datetime,[Start Date],103)
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
It works but I don't want the TOP X
.
My table contains only 36 records. so i don't think that there is bad data.
20/03/2013
20/03/2013
10/03/2013
10/03/2013
11/03/2013
06/03/2013
06/03/2013
21/03/2013
12/03/2013
03/03/2013
18/03/2013
04/03/2013
28/02/2013
28/02/2013
28/02/2013
28/02/2013
31/01/2013
15/01/2013
23/01/2013
23/01/2013
31/01/2013
23/01/2013
30/01/2013
31/01/2013
24/01/2013
24/01/2013
24/01/2013
24/01/2013
24/01/2013
30/01/2013
23/01/2013
22/01/2013
23/01/2013
23/01/2013
23/01/2013
23/01/2013
Can someone help me with that?
sql sql-server
I have a table with couple of fields nvarchar(MAX)
which occupies date in dd/mm/yyyy
format.
I run this query:
SELECT CONVERT(datetime,[Start Date],103)
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
And I get error:
The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value.
The weird thing is that when I run this query like:
SELECT TOP 40 CONVERT(datetime,[Start Date],103)
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
It works but I don't want the TOP X
.
My table contains only 36 records. so i don't think that there is bad data.
20/03/2013
20/03/2013
10/03/2013
10/03/2013
11/03/2013
06/03/2013
06/03/2013
21/03/2013
12/03/2013
03/03/2013
18/03/2013
04/03/2013
28/02/2013
28/02/2013
28/02/2013
28/02/2013
31/01/2013
15/01/2013
23/01/2013
23/01/2013
31/01/2013
23/01/2013
30/01/2013
31/01/2013
24/01/2013
24/01/2013
24/01/2013
24/01/2013
24/01/2013
30/01/2013
23/01/2013
22/01/2013
23/01/2013
23/01/2013
23/01/2013
23/01/2013
Can someone help me with that?
sql sql-server
sql sql-server
edited Mar 12 '13 at 10:23
Aviadjo
asked Mar 12 '13 at 10:18
AviadjoAviadjo
19531432
19531432
3
You need to check your data. There is a row containing bad date. TOP 40 misses it by chance.
– Nikola Markovinović
Mar 12 '13 at 10:21
1
It means your top 40 records having valid value so it convents them. some of records may have invalid data in that column
– Sachin
Mar 12 '13 at 10:21
2
It is a view, right? And it operates on larger table? Please check Short circuit section of this document.
– Nikola Markovinović
Mar 12 '13 at 10:29
3
Sql Server Query optimizer is free to choose order of execution. Views are expanded into query you submitted, so your query works on all the rows before they are filtered (even by view). In this particular case sql server runs ahead converting values it should not convert because they will not be included in final result. To solve, change convert tocase when isdate([Start Date]) = 1 then convert (...) else null end
. But do read the article I had linked.
– Nikola Markovinović
Mar 12 '13 at 10:37
3
Why, oh why, oh why are you storing datetimes inNVARCHAR(MAX)
? Do you need Unicode support? Are you going to have dates with 1 billion characters? Do you care if people enterd/m/y
orm/d/y
or2013-02-32
oris this a date?
into that column? Because they can. Do it right. Use the right data type (in this case probablyDATE
).
– Aaron Bertrand
Mar 12 '13 at 13:03
|
show 10 more comments
3
You need to check your data. There is a row containing bad date. TOP 40 misses it by chance.
– Nikola Markovinović
Mar 12 '13 at 10:21
1
It means your top 40 records having valid value so it convents them. some of records may have invalid data in that column
– Sachin
Mar 12 '13 at 10:21
2
It is a view, right? And it operates on larger table? Please check Short circuit section of this document.
– Nikola Markovinović
Mar 12 '13 at 10:29
3
Sql Server Query optimizer is free to choose order of execution. Views are expanded into query you submitted, so your query works on all the rows before they are filtered (even by view). In this particular case sql server runs ahead converting values it should not convert because they will not be included in final result. To solve, change convert tocase when isdate([Start Date]) = 1 then convert (...) else null end
. But do read the article I had linked.
– Nikola Markovinović
Mar 12 '13 at 10:37
3
Why, oh why, oh why are you storing datetimes inNVARCHAR(MAX)
? Do you need Unicode support? Are you going to have dates with 1 billion characters? Do you care if people enterd/m/y
orm/d/y
or2013-02-32
oris this a date?
into that column? Because they can. Do it right. Use the right data type (in this case probablyDATE
).
– Aaron Bertrand
Mar 12 '13 at 13:03
3
3
You need to check your data. There is a row containing bad date. TOP 40 misses it by chance.
– Nikola Markovinović
Mar 12 '13 at 10:21
You need to check your data. There is a row containing bad date. TOP 40 misses it by chance.
– Nikola Markovinović
Mar 12 '13 at 10:21
1
1
It means your top 40 records having valid value so it convents them. some of records may have invalid data in that column
– Sachin
Mar 12 '13 at 10:21
It means your top 40 records having valid value so it convents them. some of records may have invalid data in that column
– Sachin
Mar 12 '13 at 10:21
2
2
It is a view, right? And it operates on larger table? Please check Short circuit section of this document.
– Nikola Markovinović
Mar 12 '13 at 10:29
It is a view, right? And it operates on larger table? Please check Short circuit section of this document.
– Nikola Markovinović
Mar 12 '13 at 10:29
3
3
Sql Server Query optimizer is free to choose order of execution. Views are expanded into query you submitted, so your query works on all the rows before they are filtered (even by view). In this particular case sql server runs ahead converting values it should not convert because they will not be included in final result. To solve, change convert to
case when isdate([Start Date]) = 1 then convert (...) else null end
. But do read the article I had linked.– Nikola Markovinović
Mar 12 '13 at 10:37
Sql Server Query optimizer is free to choose order of execution. Views are expanded into query you submitted, so your query works on all the rows before they are filtered (even by view). In this particular case sql server runs ahead converting values it should not convert because they will not be included in final result. To solve, change convert to
case when isdate([Start Date]) = 1 then convert (...) else null end
. But do read the article I had linked.– Nikola Markovinović
Mar 12 '13 at 10:37
3
3
Why, oh why, oh why are you storing datetimes in
NVARCHAR(MAX)
? Do you need Unicode support? Are you going to have dates with 1 billion characters? Do you care if people enter d/m/y
or m/d/y
or 2013-02-32
or is this a date?
into that column? Because they can. Do it right. Use the right data type (in this case probably DATE
).– Aaron Bertrand
Mar 12 '13 at 13:03
Why, oh why, oh why are you storing datetimes in
NVARCHAR(MAX)
? Do you need Unicode support? Are you going to have dates with 1 billion characters? Do you care if people enter d/m/y
or m/d/y
or 2013-02-32
or is this a date?
into that column? Because they can. Do it right. Use the right data type (in this case probably DATE
).– Aaron Bertrand
Mar 12 '13 at 13:03
|
show 10 more comments
3 Answers
3
active
oldest
votes
The quick, easy, lazy way that will let you keep using a bad data type and allow all kinds of garbage into your table
SET DATEFORMAT DMY;
SELECT
-- other columns,
[Start Date] = CONVERT(DATETIME, CASE WHEN ISDATE([Start Date]) = 1
THEN [Start Date] END, 103)
FROM
dbo.vw_All_Requests;
Now, in this case it will return NULL
for any column value where it does not contain a valid date in d/m/y
format. If you want to exclude those rows instead of including them with NULL
values, you can add a WHERE
clause:
SET DATEFORMAT DMY;
SELECT
-- other columns,
[Start Date] = CONVERT(DATETIME, CASE WHEN ISDATE([Start Date]) = 1
THEN [Start Date] END, 103)
FROM
dbo.vw_All_Requests
WHERE ISDATE([Start Date]) = 1;
The reason you can't do this...
SELECT CONVERT(DATETIME, [Start Date], 103)
FROM ...
WHERE ISDATE([Start Date]) = 1;
...is because SQL Server might attempt the CONVERT
before the filter, resulting in the same error you're getting now. The CASE
expression (in most cases) allows you to control that evaluation order.
Now, of course, a date that is valid as d/m/y
format does not necessarily mean it was what the user intended. If you had an American enter 07/04/2013
for July 4th, you're going to incorrectly perceive that as April 7th. This is why regional formats like d/m/y
and m/d/y
are no good.
The quick, easy, lazy way that will let you keep using a bad data type but prevent more garbage from getting into your table with a little bit more work
You should still follow the advice above and fix or remove any data that doesn't conform, and at the very least add a check constraint so that no more junk gets into your table:
ALTER TABLE dbo.SourceTable
ADD CONSTRAINT CK_SillyMaxColumnIsValidDate
CHECK (CONVERT(DATE, [Start Date], 103) >= '0001-01-01');
So the following inserts will fail or succeed:
-- these succeed:
INSERT dbo.SourceTable([Start Date]) SELECT '01/01/2005';
INSERT dbo.SourceTable([Start Date]) SELECT '25/01/2005';
GO
-- fails:
INSERT dbo.SourceTable([Start Date]) SELECT '01/25/2005';
GO
-- fails:
INSERT dbo.SourceTable([Start Date]) SELECT 'garbage';
The failures prevent the bad inserts altogether, and only allow valid d/m/y
strings into the table. The error message is:
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
The right way
First, identify the bad data:
SELECT [Start Date]
FROM dbo.vw_All_Requests
WHERE ISDATE([Start Date]) = 0;
Now, fix that data, wherever it comes from, so that you can fix the data type. This might mean a combination of these types of statements:
-- correct the date for specific bad values
UPDATE dbo.SourceTable
SET [Start Date] = '03/12/2012'
WHERE [Start Date] = 'whatever';
-- remove the value altogether for specific bad values
UPDATE dbo.SourceTable
SET [Start Date] = NULL
WHERE [Start Date] = 'whatever';
-- remove the row altogether for specific bad values
DELETE dbo.SourceTable
WHERE [Start Date] = 'whatever';
-- remove all rows with bad values
SET DATEFORMAT DMY;
DELETE dbo.SourceTable
WHERE ISDATE([Start Date]) = 0;
Then add a DATE
column to the source table:
ALTER TABLE dbo.SourceTable
ADD StartDate -- no space!
DATE;
Then update the data in that column:
UPDATE dbo.SourceTable
SET StartDate = CONVERT(DATETIME, [Start Date], 103);
Now drop the original column (you may need to adjust indexes that include this column or constraints that reference it):
ALTER TABLE dbo.SourceTable
DROP COLUMN [Start Date];
Now you can either change the new column name:
EXEC sp_rename N'dbo.SourceTable.StartDate', 'Start Date', 'COLUMN';
Or change the view:
ALTER VIEW dbo.vw_All_Requests
AS
SELECT
...
[Start Date] = StartDate
Or change your application to use the new, better column name. Don't forget to change all of your data type parameters to use the proper data type too, and when passing in string literals, STOP using regional formats like d/m/y
. Like @Kaf, I prefer yyyymmdd
, which can never be misinterpreted, but yyyy-mm-dd
will always work for DATE
- just not DATETIME
, example:
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '2012-03-15');
Result:
Msg 242, Level 16, State 3, Line 2
La conversion d'un type de données varchar en type de données datetime a créé une valeur hors limites.
Some background
Please read this post:
- Bad habits to kick : mis-handling date / range queries
As a final note
Please stop creating column names or aliases with spaces in them. If you need visual separation, use an underscore. These are both much better choices for column names, don't change the meaning in any way, and don't require ugly square brackets around every single reference:
Start_Date
StartDate
add a comment |
Saving Date in string type fields is not a good idea. But if that something you have to deal with at the moment, you could run this query with isdate()
function to check any bad data and fix them:
SELECT [Start Date]
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
WHERE isdate([Start Date]) = 0
Also, it would be better if you get the date in none culture specific
ISO format
before converting into Date type. If they are all in dd/mm/yyyy
format, you could get them in ISO format
('yyyymmdd'
) as below.
SQL FIDDLE DEMO
declare @d varchar(max) = '20/03/2013'
select convert(datetime,right(@d,4) + substring(@d,4,2) + left(@d,2))
So your actual query will be like:
SELECT CONVERT(datetime,right([Start Date],4) +
substring([Start Date],4,2) +
left([Start Date],2))
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
The last query still makes assumptions about the actual data. If one of the values is32/02/2012
orxx/yy/zzzz
orwhat_the
it will fail.
– Aaron Bertrand
Mar 12 '13 at 13:12
@AaronBertrand: So what Date do you want me to replace32/02/2012
orxx/yy/zzzz
with?
– Kaf
Mar 12 '13 at 13:17
that's not your problem. The point is you will never be able to performCONVERT(DATETIME
until you clean up the data.
– Aaron Bertrand
Mar 12 '13 at 13:19
@AaronBertrand: That is why first query filtering bad data for user to see them and fix.
– Kaf
Mar 12 '13 at 14:01
But if the dates are all in d/m/y format already, what is the point of all the right/left/substring operations? If you've cleaned the data those don't seem necessary.
– Aaron Bertrand
Mar 12 '13 at 14:13
|
show 2 more comments
This has nothing to do with TOP 40. It means you dont have problematic data in top 40 rows.
If you have less data in your table, you can simply increase the limit to find out where the error is occuring
Ex:
SELECT TOP 100 CONVERT(datetime,[Start Date],103)
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
2
I agree with you, but this doesn't answer the question and fix the problem. This level of information was given already in the comments to the thread. +1 if you edit your post to include a solution (i.e. data checking and short circuiting).
– Eli Gassert
Mar 12 '13 at 10:32
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f15358518%2fconvert-nvarcharmax-to-datetime%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
The quick, easy, lazy way that will let you keep using a bad data type and allow all kinds of garbage into your table
SET DATEFORMAT DMY;
SELECT
-- other columns,
[Start Date] = CONVERT(DATETIME, CASE WHEN ISDATE([Start Date]) = 1
THEN [Start Date] END, 103)
FROM
dbo.vw_All_Requests;
Now, in this case it will return NULL
for any column value where it does not contain a valid date in d/m/y
format. If you want to exclude those rows instead of including them with NULL
values, you can add a WHERE
clause:
SET DATEFORMAT DMY;
SELECT
-- other columns,
[Start Date] = CONVERT(DATETIME, CASE WHEN ISDATE([Start Date]) = 1
THEN [Start Date] END, 103)
FROM
dbo.vw_All_Requests
WHERE ISDATE([Start Date]) = 1;
The reason you can't do this...
SELECT CONVERT(DATETIME, [Start Date], 103)
FROM ...
WHERE ISDATE([Start Date]) = 1;
...is because SQL Server might attempt the CONVERT
before the filter, resulting in the same error you're getting now. The CASE
expression (in most cases) allows you to control that evaluation order.
Now, of course, a date that is valid as d/m/y
format does not necessarily mean it was what the user intended. If you had an American enter 07/04/2013
for July 4th, you're going to incorrectly perceive that as April 7th. This is why regional formats like d/m/y
and m/d/y
are no good.
The quick, easy, lazy way that will let you keep using a bad data type but prevent more garbage from getting into your table with a little bit more work
You should still follow the advice above and fix or remove any data that doesn't conform, and at the very least add a check constraint so that no more junk gets into your table:
ALTER TABLE dbo.SourceTable
ADD CONSTRAINT CK_SillyMaxColumnIsValidDate
CHECK (CONVERT(DATE, [Start Date], 103) >= '0001-01-01');
So the following inserts will fail or succeed:
-- these succeed:
INSERT dbo.SourceTable([Start Date]) SELECT '01/01/2005';
INSERT dbo.SourceTable([Start Date]) SELECT '25/01/2005';
GO
-- fails:
INSERT dbo.SourceTable([Start Date]) SELECT '01/25/2005';
GO
-- fails:
INSERT dbo.SourceTable([Start Date]) SELECT 'garbage';
The failures prevent the bad inserts altogether, and only allow valid d/m/y
strings into the table. The error message is:
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
The right way
First, identify the bad data:
SELECT [Start Date]
FROM dbo.vw_All_Requests
WHERE ISDATE([Start Date]) = 0;
Now, fix that data, wherever it comes from, so that you can fix the data type. This might mean a combination of these types of statements:
-- correct the date for specific bad values
UPDATE dbo.SourceTable
SET [Start Date] = '03/12/2012'
WHERE [Start Date] = 'whatever';
-- remove the value altogether for specific bad values
UPDATE dbo.SourceTable
SET [Start Date] = NULL
WHERE [Start Date] = 'whatever';
-- remove the row altogether for specific bad values
DELETE dbo.SourceTable
WHERE [Start Date] = 'whatever';
-- remove all rows with bad values
SET DATEFORMAT DMY;
DELETE dbo.SourceTable
WHERE ISDATE([Start Date]) = 0;
Then add a DATE
column to the source table:
ALTER TABLE dbo.SourceTable
ADD StartDate -- no space!
DATE;
Then update the data in that column:
UPDATE dbo.SourceTable
SET StartDate = CONVERT(DATETIME, [Start Date], 103);
Now drop the original column (you may need to adjust indexes that include this column or constraints that reference it):
ALTER TABLE dbo.SourceTable
DROP COLUMN [Start Date];
Now you can either change the new column name:
EXEC sp_rename N'dbo.SourceTable.StartDate', 'Start Date', 'COLUMN';
Or change the view:
ALTER VIEW dbo.vw_All_Requests
AS
SELECT
...
[Start Date] = StartDate
Or change your application to use the new, better column name. Don't forget to change all of your data type parameters to use the proper data type too, and when passing in string literals, STOP using regional formats like d/m/y
. Like @Kaf, I prefer yyyymmdd
, which can never be misinterpreted, but yyyy-mm-dd
will always work for DATE
- just not DATETIME
, example:
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '2012-03-15');
Result:
Msg 242, Level 16, State 3, Line 2
La conversion d'un type de données varchar en type de données datetime a créé une valeur hors limites.
Some background
Please read this post:
- Bad habits to kick : mis-handling date / range queries
As a final note
Please stop creating column names or aliases with spaces in them. If you need visual separation, use an underscore. These are both much better choices for column names, don't change the meaning in any way, and don't require ugly square brackets around every single reference:
Start_Date
StartDate
add a comment |
The quick, easy, lazy way that will let you keep using a bad data type and allow all kinds of garbage into your table
SET DATEFORMAT DMY;
SELECT
-- other columns,
[Start Date] = CONVERT(DATETIME, CASE WHEN ISDATE([Start Date]) = 1
THEN [Start Date] END, 103)
FROM
dbo.vw_All_Requests;
Now, in this case it will return NULL
for any column value where it does not contain a valid date in d/m/y
format. If you want to exclude those rows instead of including them with NULL
values, you can add a WHERE
clause:
SET DATEFORMAT DMY;
SELECT
-- other columns,
[Start Date] = CONVERT(DATETIME, CASE WHEN ISDATE([Start Date]) = 1
THEN [Start Date] END, 103)
FROM
dbo.vw_All_Requests
WHERE ISDATE([Start Date]) = 1;
The reason you can't do this...
SELECT CONVERT(DATETIME, [Start Date], 103)
FROM ...
WHERE ISDATE([Start Date]) = 1;
...is because SQL Server might attempt the CONVERT
before the filter, resulting in the same error you're getting now. The CASE
expression (in most cases) allows you to control that evaluation order.
Now, of course, a date that is valid as d/m/y
format does not necessarily mean it was what the user intended. If you had an American enter 07/04/2013
for July 4th, you're going to incorrectly perceive that as April 7th. This is why regional formats like d/m/y
and m/d/y
are no good.
The quick, easy, lazy way that will let you keep using a bad data type but prevent more garbage from getting into your table with a little bit more work
You should still follow the advice above and fix or remove any data that doesn't conform, and at the very least add a check constraint so that no more junk gets into your table:
ALTER TABLE dbo.SourceTable
ADD CONSTRAINT CK_SillyMaxColumnIsValidDate
CHECK (CONVERT(DATE, [Start Date], 103) >= '0001-01-01');
So the following inserts will fail or succeed:
-- these succeed:
INSERT dbo.SourceTable([Start Date]) SELECT '01/01/2005';
INSERT dbo.SourceTable([Start Date]) SELECT '25/01/2005';
GO
-- fails:
INSERT dbo.SourceTable([Start Date]) SELECT '01/25/2005';
GO
-- fails:
INSERT dbo.SourceTable([Start Date]) SELECT 'garbage';
The failures prevent the bad inserts altogether, and only allow valid d/m/y
strings into the table. The error message is:
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
The right way
First, identify the bad data:
SELECT [Start Date]
FROM dbo.vw_All_Requests
WHERE ISDATE([Start Date]) = 0;
Now, fix that data, wherever it comes from, so that you can fix the data type. This might mean a combination of these types of statements:
-- correct the date for specific bad values
UPDATE dbo.SourceTable
SET [Start Date] = '03/12/2012'
WHERE [Start Date] = 'whatever';
-- remove the value altogether for specific bad values
UPDATE dbo.SourceTable
SET [Start Date] = NULL
WHERE [Start Date] = 'whatever';
-- remove the row altogether for specific bad values
DELETE dbo.SourceTable
WHERE [Start Date] = 'whatever';
-- remove all rows with bad values
SET DATEFORMAT DMY;
DELETE dbo.SourceTable
WHERE ISDATE([Start Date]) = 0;
Then add a DATE
column to the source table:
ALTER TABLE dbo.SourceTable
ADD StartDate -- no space!
DATE;
Then update the data in that column:
UPDATE dbo.SourceTable
SET StartDate = CONVERT(DATETIME, [Start Date], 103);
Now drop the original column (you may need to adjust indexes that include this column or constraints that reference it):
ALTER TABLE dbo.SourceTable
DROP COLUMN [Start Date];
Now you can either change the new column name:
EXEC sp_rename N'dbo.SourceTable.StartDate', 'Start Date', 'COLUMN';
Or change the view:
ALTER VIEW dbo.vw_All_Requests
AS
SELECT
...
[Start Date] = StartDate
Or change your application to use the new, better column name. Don't forget to change all of your data type parameters to use the proper data type too, and when passing in string literals, STOP using regional formats like d/m/y
. Like @Kaf, I prefer yyyymmdd
, which can never be misinterpreted, but yyyy-mm-dd
will always work for DATE
- just not DATETIME
, example:
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '2012-03-15');
Result:
Msg 242, Level 16, State 3, Line 2
La conversion d'un type de données varchar en type de données datetime a créé une valeur hors limites.
Some background
Please read this post:
- Bad habits to kick : mis-handling date / range queries
As a final note
Please stop creating column names or aliases with spaces in them. If you need visual separation, use an underscore. These are both much better choices for column names, don't change the meaning in any way, and don't require ugly square brackets around every single reference:
Start_Date
StartDate
add a comment |
The quick, easy, lazy way that will let you keep using a bad data type and allow all kinds of garbage into your table
SET DATEFORMAT DMY;
SELECT
-- other columns,
[Start Date] = CONVERT(DATETIME, CASE WHEN ISDATE([Start Date]) = 1
THEN [Start Date] END, 103)
FROM
dbo.vw_All_Requests;
Now, in this case it will return NULL
for any column value where it does not contain a valid date in d/m/y
format. If you want to exclude those rows instead of including them with NULL
values, you can add a WHERE
clause:
SET DATEFORMAT DMY;
SELECT
-- other columns,
[Start Date] = CONVERT(DATETIME, CASE WHEN ISDATE([Start Date]) = 1
THEN [Start Date] END, 103)
FROM
dbo.vw_All_Requests
WHERE ISDATE([Start Date]) = 1;
The reason you can't do this...
SELECT CONVERT(DATETIME, [Start Date], 103)
FROM ...
WHERE ISDATE([Start Date]) = 1;
...is because SQL Server might attempt the CONVERT
before the filter, resulting in the same error you're getting now. The CASE
expression (in most cases) allows you to control that evaluation order.
Now, of course, a date that is valid as d/m/y
format does not necessarily mean it was what the user intended. If you had an American enter 07/04/2013
for July 4th, you're going to incorrectly perceive that as April 7th. This is why regional formats like d/m/y
and m/d/y
are no good.
The quick, easy, lazy way that will let you keep using a bad data type but prevent more garbage from getting into your table with a little bit more work
You should still follow the advice above and fix or remove any data that doesn't conform, and at the very least add a check constraint so that no more junk gets into your table:
ALTER TABLE dbo.SourceTable
ADD CONSTRAINT CK_SillyMaxColumnIsValidDate
CHECK (CONVERT(DATE, [Start Date], 103) >= '0001-01-01');
So the following inserts will fail or succeed:
-- these succeed:
INSERT dbo.SourceTable([Start Date]) SELECT '01/01/2005';
INSERT dbo.SourceTable([Start Date]) SELECT '25/01/2005';
GO
-- fails:
INSERT dbo.SourceTable([Start Date]) SELECT '01/25/2005';
GO
-- fails:
INSERT dbo.SourceTable([Start Date]) SELECT 'garbage';
The failures prevent the bad inserts altogether, and only allow valid d/m/y
strings into the table. The error message is:
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
The right way
First, identify the bad data:
SELECT [Start Date]
FROM dbo.vw_All_Requests
WHERE ISDATE([Start Date]) = 0;
Now, fix that data, wherever it comes from, so that you can fix the data type. This might mean a combination of these types of statements:
-- correct the date for specific bad values
UPDATE dbo.SourceTable
SET [Start Date] = '03/12/2012'
WHERE [Start Date] = 'whatever';
-- remove the value altogether for specific bad values
UPDATE dbo.SourceTable
SET [Start Date] = NULL
WHERE [Start Date] = 'whatever';
-- remove the row altogether for specific bad values
DELETE dbo.SourceTable
WHERE [Start Date] = 'whatever';
-- remove all rows with bad values
SET DATEFORMAT DMY;
DELETE dbo.SourceTable
WHERE ISDATE([Start Date]) = 0;
Then add a DATE
column to the source table:
ALTER TABLE dbo.SourceTable
ADD StartDate -- no space!
DATE;
Then update the data in that column:
UPDATE dbo.SourceTable
SET StartDate = CONVERT(DATETIME, [Start Date], 103);
Now drop the original column (you may need to adjust indexes that include this column or constraints that reference it):
ALTER TABLE dbo.SourceTable
DROP COLUMN [Start Date];
Now you can either change the new column name:
EXEC sp_rename N'dbo.SourceTable.StartDate', 'Start Date', 'COLUMN';
Or change the view:
ALTER VIEW dbo.vw_All_Requests
AS
SELECT
...
[Start Date] = StartDate
Or change your application to use the new, better column name. Don't forget to change all of your data type parameters to use the proper data type too, and when passing in string literals, STOP using regional formats like d/m/y
. Like @Kaf, I prefer yyyymmdd
, which can never be misinterpreted, but yyyy-mm-dd
will always work for DATE
- just not DATETIME
, example:
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '2012-03-15');
Result:
Msg 242, Level 16, State 3, Line 2
La conversion d'un type de données varchar en type de données datetime a créé une valeur hors limites.
Some background
Please read this post:
- Bad habits to kick : mis-handling date / range queries
As a final note
Please stop creating column names or aliases with spaces in them. If you need visual separation, use an underscore. These are both much better choices for column names, don't change the meaning in any way, and don't require ugly square brackets around every single reference:
Start_Date
StartDate
The quick, easy, lazy way that will let you keep using a bad data type and allow all kinds of garbage into your table
SET DATEFORMAT DMY;
SELECT
-- other columns,
[Start Date] = CONVERT(DATETIME, CASE WHEN ISDATE([Start Date]) = 1
THEN [Start Date] END, 103)
FROM
dbo.vw_All_Requests;
Now, in this case it will return NULL
for any column value where it does not contain a valid date in d/m/y
format. If you want to exclude those rows instead of including them with NULL
values, you can add a WHERE
clause:
SET DATEFORMAT DMY;
SELECT
-- other columns,
[Start Date] = CONVERT(DATETIME, CASE WHEN ISDATE([Start Date]) = 1
THEN [Start Date] END, 103)
FROM
dbo.vw_All_Requests
WHERE ISDATE([Start Date]) = 1;
The reason you can't do this...
SELECT CONVERT(DATETIME, [Start Date], 103)
FROM ...
WHERE ISDATE([Start Date]) = 1;
...is because SQL Server might attempt the CONVERT
before the filter, resulting in the same error you're getting now. The CASE
expression (in most cases) allows you to control that evaluation order.
Now, of course, a date that is valid as d/m/y
format does not necessarily mean it was what the user intended. If you had an American enter 07/04/2013
for July 4th, you're going to incorrectly perceive that as April 7th. This is why regional formats like d/m/y
and m/d/y
are no good.
The quick, easy, lazy way that will let you keep using a bad data type but prevent more garbage from getting into your table with a little bit more work
You should still follow the advice above and fix or remove any data that doesn't conform, and at the very least add a check constraint so that no more junk gets into your table:
ALTER TABLE dbo.SourceTable
ADD CONSTRAINT CK_SillyMaxColumnIsValidDate
CHECK (CONVERT(DATE, [Start Date], 103) >= '0001-01-01');
So the following inserts will fail or succeed:
-- these succeed:
INSERT dbo.SourceTable([Start Date]) SELECT '01/01/2005';
INSERT dbo.SourceTable([Start Date]) SELECT '25/01/2005';
GO
-- fails:
INSERT dbo.SourceTable([Start Date]) SELECT '01/25/2005';
GO
-- fails:
INSERT dbo.SourceTable([Start Date]) SELECT 'garbage';
The failures prevent the bad inserts altogether, and only allow valid d/m/y
strings into the table. The error message is:
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
The right way
First, identify the bad data:
SELECT [Start Date]
FROM dbo.vw_All_Requests
WHERE ISDATE([Start Date]) = 0;
Now, fix that data, wherever it comes from, so that you can fix the data type. This might mean a combination of these types of statements:
-- correct the date for specific bad values
UPDATE dbo.SourceTable
SET [Start Date] = '03/12/2012'
WHERE [Start Date] = 'whatever';
-- remove the value altogether for specific bad values
UPDATE dbo.SourceTable
SET [Start Date] = NULL
WHERE [Start Date] = 'whatever';
-- remove the row altogether for specific bad values
DELETE dbo.SourceTable
WHERE [Start Date] = 'whatever';
-- remove all rows with bad values
SET DATEFORMAT DMY;
DELETE dbo.SourceTable
WHERE ISDATE([Start Date]) = 0;
Then add a DATE
column to the source table:
ALTER TABLE dbo.SourceTable
ADD StartDate -- no space!
DATE;
Then update the data in that column:
UPDATE dbo.SourceTable
SET StartDate = CONVERT(DATETIME, [Start Date], 103);
Now drop the original column (you may need to adjust indexes that include this column or constraints that reference it):
ALTER TABLE dbo.SourceTable
DROP COLUMN [Start Date];
Now you can either change the new column name:
EXEC sp_rename N'dbo.SourceTable.StartDate', 'Start Date', 'COLUMN';
Or change the view:
ALTER VIEW dbo.vw_All_Requests
AS
SELECT
...
[Start Date] = StartDate
Or change your application to use the new, better column name. Don't forget to change all of your data type parameters to use the proper data type too, and when passing in string literals, STOP using regional formats like d/m/y
. Like @Kaf, I prefer yyyymmdd
, which can never be misinterpreted, but yyyy-mm-dd
will always work for DATE
- just not DATETIME
, example:
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '2012-03-15');
Result:
Msg 242, Level 16, State 3, Line 2
La conversion d'un type de données varchar en type de données datetime a créé une valeur hors limites.
Some background
Please read this post:
- Bad habits to kick : mis-handling date / range queries
As a final note
Please stop creating column names or aliases with spaces in them. If you need visual separation, use an underscore. These are both much better choices for column names, don't change the meaning in any way, and don't require ugly square brackets around every single reference:
Start_Date
StartDate
edited Nov 11 '18 at 21:16
answered Mar 12 '13 at 13:33
Aaron BertrandAaron Bertrand
209k27366407
209k27366407
add a comment |
add a comment |
Saving Date in string type fields is not a good idea. But if that something you have to deal with at the moment, you could run this query with isdate()
function to check any bad data and fix them:
SELECT [Start Date]
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
WHERE isdate([Start Date]) = 0
Also, it would be better if you get the date in none culture specific
ISO format
before converting into Date type. If they are all in dd/mm/yyyy
format, you could get them in ISO format
('yyyymmdd'
) as below.
SQL FIDDLE DEMO
declare @d varchar(max) = '20/03/2013'
select convert(datetime,right(@d,4) + substring(@d,4,2) + left(@d,2))
So your actual query will be like:
SELECT CONVERT(datetime,right([Start Date],4) +
substring([Start Date],4,2) +
left([Start Date],2))
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
The last query still makes assumptions about the actual data. If one of the values is32/02/2012
orxx/yy/zzzz
orwhat_the
it will fail.
– Aaron Bertrand
Mar 12 '13 at 13:12
@AaronBertrand: So what Date do you want me to replace32/02/2012
orxx/yy/zzzz
with?
– Kaf
Mar 12 '13 at 13:17
that's not your problem. The point is you will never be able to performCONVERT(DATETIME
until you clean up the data.
– Aaron Bertrand
Mar 12 '13 at 13:19
@AaronBertrand: That is why first query filtering bad data for user to see them and fix.
– Kaf
Mar 12 '13 at 14:01
But if the dates are all in d/m/y format already, what is the point of all the right/left/substring operations? If you've cleaned the data those don't seem necessary.
– Aaron Bertrand
Mar 12 '13 at 14:13
|
show 2 more comments
Saving Date in string type fields is not a good idea. But if that something you have to deal with at the moment, you could run this query with isdate()
function to check any bad data and fix them:
SELECT [Start Date]
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
WHERE isdate([Start Date]) = 0
Also, it would be better if you get the date in none culture specific
ISO format
before converting into Date type. If they are all in dd/mm/yyyy
format, you could get them in ISO format
('yyyymmdd'
) as below.
SQL FIDDLE DEMO
declare @d varchar(max) = '20/03/2013'
select convert(datetime,right(@d,4) + substring(@d,4,2) + left(@d,2))
So your actual query will be like:
SELECT CONVERT(datetime,right([Start Date],4) +
substring([Start Date],4,2) +
left([Start Date],2))
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
The last query still makes assumptions about the actual data. If one of the values is32/02/2012
orxx/yy/zzzz
orwhat_the
it will fail.
– Aaron Bertrand
Mar 12 '13 at 13:12
@AaronBertrand: So what Date do you want me to replace32/02/2012
orxx/yy/zzzz
with?
– Kaf
Mar 12 '13 at 13:17
that's not your problem. The point is you will never be able to performCONVERT(DATETIME
until you clean up the data.
– Aaron Bertrand
Mar 12 '13 at 13:19
@AaronBertrand: That is why first query filtering bad data for user to see them and fix.
– Kaf
Mar 12 '13 at 14:01
But if the dates are all in d/m/y format already, what is the point of all the right/left/substring operations? If you've cleaned the data those don't seem necessary.
– Aaron Bertrand
Mar 12 '13 at 14:13
|
show 2 more comments
Saving Date in string type fields is not a good idea. But if that something you have to deal with at the moment, you could run this query with isdate()
function to check any bad data and fix them:
SELECT [Start Date]
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
WHERE isdate([Start Date]) = 0
Also, it would be better if you get the date in none culture specific
ISO format
before converting into Date type. If they are all in dd/mm/yyyy
format, you could get them in ISO format
('yyyymmdd'
) as below.
SQL FIDDLE DEMO
declare @d varchar(max) = '20/03/2013'
select convert(datetime,right(@d,4) + substring(@d,4,2) + left(@d,2))
So your actual query will be like:
SELECT CONVERT(datetime,right([Start Date],4) +
substring([Start Date],4,2) +
left([Start Date],2))
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
Saving Date in string type fields is not a good idea. But if that something you have to deal with at the moment, you could run this query with isdate()
function to check any bad data and fix them:
SELECT [Start Date]
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
WHERE isdate([Start Date]) = 0
Also, it would be better if you get the date in none culture specific
ISO format
before converting into Date type. If they are all in dd/mm/yyyy
format, you could get them in ISO format
('yyyymmdd'
) as below.
SQL FIDDLE DEMO
declare @d varchar(max) = '20/03/2013'
select convert(datetime,right(@d,4) + substring(@d,4,2) + left(@d,2))
So your actual query will be like:
SELECT CONVERT(datetime,right([Start Date],4) +
substring([Start Date],4,2) +
left([Start Date],2))
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
edited Mar 12 '13 at 15:36
answered Mar 12 '13 at 10:54
KafKaf
26.8k44059
26.8k44059
The last query still makes assumptions about the actual data. If one of the values is32/02/2012
orxx/yy/zzzz
orwhat_the
it will fail.
– Aaron Bertrand
Mar 12 '13 at 13:12
@AaronBertrand: So what Date do you want me to replace32/02/2012
orxx/yy/zzzz
with?
– Kaf
Mar 12 '13 at 13:17
that's not your problem. The point is you will never be able to performCONVERT(DATETIME
until you clean up the data.
– Aaron Bertrand
Mar 12 '13 at 13:19
@AaronBertrand: That is why first query filtering bad data for user to see them and fix.
– Kaf
Mar 12 '13 at 14:01
But if the dates are all in d/m/y format already, what is the point of all the right/left/substring operations? If you've cleaned the data those don't seem necessary.
– Aaron Bertrand
Mar 12 '13 at 14:13
|
show 2 more comments
The last query still makes assumptions about the actual data. If one of the values is32/02/2012
orxx/yy/zzzz
orwhat_the
it will fail.
– Aaron Bertrand
Mar 12 '13 at 13:12
@AaronBertrand: So what Date do you want me to replace32/02/2012
orxx/yy/zzzz
with?
– Kaf
Mar 12 '13 at 13:17
that's not your problem. The point is you will never be able to performCONVERT(DATETIME
until you clean up the data.
– Aaron Bertrand
Mar 12 '13 at 13:19
@AaronBertrand: That is why first query filtering bad data for user to see them and fix.
– Kaf
Mar 12 '13 at 14:01
But if the dates are all in d/m/y format already, what is the point of all the right/left/substring operations? If you've cleaned the data those don't seem necessary.
– Aaron Bertrand
Mar 12 '13 at 14:13
The last query still makes assumptions about the actual data. If one of the values is
32/02/2012
or xx/yy/zzzz
or what_the
it will fail.– Aaron Bertrand
Mar 12 '13 at 13:12
The last query still makes assumptions about the actual data. If one of the values is
32/02/2012
or xx/yy/zzzz
or what_the
it will fail.– Aaron Bertrand
Mar 12 '13 at 13:12
@AaronBertrand: So what Date do you want me to replace
32/02/2012
or xx/yy/zzzz
with?– Kaf
Mar 12 '13 at 13:17
@AaronBertrand: So what Date do you want me to replace
32/02/2012
or xx/yy/zzzz
with?– Kaf
Mar 12 '13 at 13:17
that's not your problem. The point is you will never be able to perform
CONVERT(DATETIME
until you clean up the data.– Aaron Bertrand
Mar 12 '13 at 13:19
that's not your problem. The point is you will never be able to perform
CONVERT(DATETIME
until you clean up the data.– Aaron Bertrand
Mar 12 '13 at 13:19
@AaronBertrand: That is why first query filtering bad data for user to see them and fix.
– Kaf
Mar 12 '13 at 14:01
@AaronBertrand: That is why first query filtering bad data for user to see them and fix.
– Kaf
Mar 12 '13 at 14:01
But if the dates are all in d/m/y format already, what is the point of all the right/left/substring operations? If you've cleaned the data those don't seem necessary.
– Aaron Bertrand
Mar 12 '13 at 14:13
But if the dates are all in d/m/y format already, what is the point of all the right/left/substring operations? If you've cleaned the data those don't seem necessary.
– Aaron Bertrand
Mar 12 '13 at 14:13
|
show 2 more comments
This has nothing to do with TOP 40. It means you dont have problematic data in top 40 rows.
If you have less data in your table, you can simply increase the limit to find out where the error is occuring
Ex:
SELECT TOP 100 CONVERT(datetime,[Start Date],103)
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
2
I agree with you, but this doesn't answer the question and fix the problem. This level of information was given already in the comments to the thread. +1 if you edit your post to include a solution (i.e. data checking and short circuiting).
– Eli Gassert
Mar 12 '13 at 10:32
add a comment |
This has nothing to do with TOP 40. It means you dont have problematic data in top 40 rows.
If you have less data in your table, you can simply increase the limit to find out where the error is occuring
Ex:
SELECT TOP 100 CONVERT(datetime,[Start Date],103)
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
2
I agree with you, but this doesn't answer the question and fix the problem. This level of information was given already in the comments to the thread. +1 if you edit your post to include a solution (i.e. data checking and short circuiting).
– Eli Gassert
Mar 12 '13 at 10:32
add a comment |
This has nothing to do with TOP 40. It means you dont have problematic data in top 40 rows.
If you have less data in your table, you can simply increase the limit to find out where the error is occuring
Ex:
SELECT TOP 100 CONVERT(datetime,[Start Date],103)
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
This has nothing to do with TOP 40. It means you dont have problematic data in top 40 rows.
If you have less data in your table, you can simply increase the limit to find out where the error is occuring
Ex:
SELECT TOP 100 CONVERT(datetime,[Start Date],103)
FROM [YellowCard_NewDesign].[dbo].[vw_All_Requests]
edited Mar 12 '13 at 10:28
answered Mar 12 '13 at 10:23
Mayukh RoyMayukh Roy
1,60421728
1,60421728
2
I agree with you, but this doesn't answer the question and fix the problem. This level of information was given already in the comments to the thread. +1 if you edit your post to include a solution (i.e. data checking and short circuiting).
– Eli Gassert
Mar 12 '13 at 10:32
add a comment |
2
I agree with you, but this doesn't answer the question and fix the problem. This level of information was given already in the comments to the thread. +1 if you edit your post to include a solution (i.e. data checking and short circuiting).
– Eli Gassert
Mar 12 '13 at 10:32
2
2
I agree with you, but this doesn't answer the question and fix the problem. This level of information was given already in the comments to the thread. +1 if you edit your post to include a solution (i.e. data checking and short circuiting).
– Eli Gassert
Mar 12 '13 at 10:32
I agree with you, but this doesn't answer the question and fix the problem. This level of information was given already in the comments to the thread. +1 if you edit your post to include a solution (i.e. data checking and short circuiting).
– Eli Gassert
Mar 12 '13 at 10:32
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f15358518%2fconvert-nvarcharmax-to-datetime%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
You need to check your data. There is a row containing bad date. TOP 40 misses it by chance.
– Nikola Markovinović
Mar 12 '13 at 10:21
1
It means your top 40 records having valid value so it convents them. some of records may have invalid data in that column
– Sachin
Mar 12 '13 at 10:21
2
It is a view, right? And it operates on larger table? Please check Short circuit section of this document.
– Nikola Markovinović
Mar 12 '13 at 10:29
3
Sql Server Query optimizer is free to choose order of execution. Views are expanded into query you submitted, so your query works on all the rows before they are filtered (even by view). In this particular case sql server runs ahead converting values it should not convert because they will not be included in final result. To solve, change convert to
case when isdate([Start Date]) = 1 then convert (...) else null end
. But do read the article I had linked.– Nikola Markovinović
Mar 12 '13 at 10:37
3
Why, oh why, oh why are you storing datetimes in
NVARCHAR(MAX)
? Do you need Unicode support? Are you going to have dates with 1 billion characters? Do you care if people enterd/m/y
orm/d/y
or2013-02-32
oris this a date?
into that column? Because they can. Do it right. Use the right data type (in this case probablyDATE
).– Aaron Bertrand
Mar 12 '13 at 13:03