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:
YYYYMMDDfor just dates (no time portion); note here: no dashes!, that's very important!YYYY-MM-DDis NOT independent of the dateformat settings in your SQL Server and will NOT work in all situations!
or:
YYYY-MM-DDTHH:mm:ssfor dates and times - note here: this format has dashes (but they can be omitted), and a fixedTas delimiter between the date and time portion of yourDATETIME.
This is valid for SQL Server 2000 and newer.
So in your specific case - use these strings:
insert into table1 values('2012-02-21T18:10:00', '2012-01-01T00:00:00');
and you should be fine (note: you need to use the international 24-hour format rather than 12-hour AM/PM format for this).
Alternatively: if you're on SQL Server 2008 or newer, you could also use the DATETIME2 datatype (instead of plain DATETIME) and your current INSERT would just work without any problems! :-) DATETIME2 is a lot better and a lot less picky on conversions - and it's the recommend date/time data types for SQL Server 2008 or newer anyway.
SELECT
CAST('02-21-2012 6:10:00 PM' AS DATETIME2), -- works just fine
CAST('01-01-2012 12:00:00 AM' AS DATETIME2) -- works just fine
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.
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:
YYYYMMDDfor just dates (no time portion); note here: no dashes!, that's very important!YYYY-MM-DDis NOT independent of the dateformat settings in your SQL Server and will NOT work in all situations!
or:
YYYY-MM-DDTHH:mm:ssfor dates and times - note here: this format has dashes (but they can be omitted), and a fixedTas delimiter between the date and time portion of yourDATETIME.
This is valid for SQL Server 2000 and newer.
So in your specific case - use these strings:
insert into table1 values('2012-02-21T18:10:00', '2012-01-01T00:00:00');
and you should be fine (note: you need to use the international 24-hour format rather than 12-hour AM/PM format for this).
Alternatively: if you're on SQL Server 2008 or newer, you could also use the DATETIME2 datatype (instead of plain DATETIME) and your current INSERT would just work without any problems! :-) DATETIME2 is a lot better and a lot less picky on conversions - and it's the recommend date/time data types for SQL Server 2008 or newer anyway.
SELECT
CAST('02-21-2012 6:10:00 PM' AS DATETIME2), -- works just fine
CAST('01-01-2012 12:00:00 AM' AS DATETIME2) -- works just fine
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.
Sometimes, the conversion in SQL Server fails not because of the Date or Time formats used. It is merely because you are trying to store wrong data that is not acceptable to the system.
Example:
Create Table MyTable (MyDate);
Insert Into MyTable(MyDate) Values ('2015-02-29');
The SQL Server will throw the following error:
Conversion failed when converting date and/or time from character string.
The reason for this error is simply there is no such date (Feb-29) in Year (2015).
Videos
I'm a beginner in SQL in general.. I run this query in MSSQL Server
INSERT INTO STUDENT (STU_FNAME, STU_LNAME, STU_DOB, STU_STREET, STU_CITY,
STU_STATE) VALUES
('Matthew', 'Star', '19991111', '436 Garland Ave', 'Honolulu', 'Hawaii');But I get the error:
Conversion failed when converting date and/or time from character string.
I found a post on StackOverflow, but it looks like I'm using the date format correctly (YYYYMMDD). Can someone give me some insight? I'm using the "DATE" datatype. I've tried other formats (yyyy/mm/dd or yyyy-mm-dd) but no dice
You are storing dates as strings - why? Opening_Date and Date should be date or datetime, not varchar. But before you can fix that, you need to identify the rows that are causing the conversion problem:
SELECT cod_store, [Date]
FROM dbo.FactTransactions
WHERE ISDATE([Date]) = 0;
SELECT cod_storekey, Opening_Date
FROM dbo.DimStore
WHERE ISDATE(Opening_Date) = 0;
And now that you've fixed the question and I know you're using 2012 and not 2008 R2, it might be cleaner to use TRY_CONVERT(), especially since it will allow you to identify any rows where the month and day are transposed incorrectly. For example, assuming you expect dates to be stored as mm/dd/yyyy strings:
SELECT cod_store, [Date]
FROM dbo.FactTransactions
WHERE TRY_CONVERT(datetime, [Date], 101) = 0;
SELECT cod_storekey, Opening_Date
FROM dbo.DimStore
WHERE TRY_CONVERT(datetime, Opening_Date, 101) = 0;
In addition to identifying garbage rows where users have stored nonsense like floob and 9992-13-36 as "dates," this will also identify rows where users have stored 13/07/1999 instead of 07/13/1999 (but there is no way to know if 05/06/2000 is meant to be May 6 or June 5).
Now you need to fix those rows before you can correct the tables.
ALTER TABLE dbo.DimStore ALTER COLUMN Opening_Date date; -- or datetime;
ALTER TABLE dbo.FactTransactions ALTER COLUMN [Date] date; -- or datetime;
You might also consider renaming the Date column to be (a) less vague and (b) not a reserved word.
If you can't fix the tables, then you need to change your query:
UPDATE T1
SET ORDINAL = DATEDIFF(DAY,
CASE WHEN ISDATE(T2.Opening_Date) = 1 THEN T2.OpeningDate END,
CASE WHEN ISDATE(T1.[Date]) = 1 THEN T1.Date END)
FROM dbo.FactTransactions AS T1
INNER JOIN dbo.DimStore AS T2
ON T1.cod_store = T2.cod_storeKey
WHERE ISDATE(T2.Opening_Date) = 1
AND ISDATE(T1.[Date]) = 1;
And @RLF brought up a great point, too; if you can't fix the table, then the date columns could contain data that represent a specific date (say, September 7) but be entered in the wrong format (e.g. on a US English system, entered as a string in British format, 7/9/2015). So really, you need to fix the table and stop storing these things as strings.
Some other useful material:
- Bad habits to kick : mis-handling date / range queries
- Bad habits to kick : avoiding the schema prefix
You can use Convert with the correct style in order to convert varchar(x) in your local format to proper dates:
DATEDIFF(DAY, convert(date, T2.Opening_Date, 104), convert(date, T1.Date, 104))
In this sample, I supposed you are using the German style (dd.mm.yyyy). German style is 104:
Select convert(date, '01.02.2015', 104)
Ouput: 2015-02-01
You must adapt it to your settings and local format and replace 104 by whatever your are using. Main style are:
Style Standard Input/Ouput
1 U.S. 1 = mm/dd/yy
101 U.S. 101 = mm/dd/yyyy
2 ANSI 2 = yy.mm.dd
102 ANSI 102 = yyyy.mm.dd
3 British/French 3 = dd/mm/yy
103 British/French 103 = dd/mm/yyyy
4 German 4 = dd.mm.yy
104 German 104 = dd.mm.yyyy
5 Italian 5 = dd-mm-yy
105 Italian 105 = dd-mm-yyyy
Look at CAST and CONVERT (Transact-SQL)
If you have dates with bad formats or mixed formats, you can also look at TRY_CONVERT with a query such as:
Select ...
FROM FactTransactions T1
INNER JOIN DimStore T2 ON T1.cod_store = T2.cod_storeKey
Where try_convert(date, T2.Opening_Date, 104) is null
or try_convert(date, T1.Date, 104) is null
It will give you a list of dates with incorect format for style 104. Again, adapt it to your settings and replace 104. You can use it before fixing bad formats and dates.
But the main question and problem are: why are you using varchar(x). You should be using Date or Datetime 2 if you can update your table.
Try the following:
CREATE OR ALTER PROCEDURE [dbo].[urunGiris]
@TableName VARCHAR(100)
, @MalzemeStokNo VARCHAR(50)
, @MalzemeAd VARCHAR(100)
, @Irsaliye VARCHAR(100)
, @MalzemeAgirlik VARCHAR(50)
, @GirenMiktar INT
, @GirenTonaj FLOAT(53)
, @CikanMiktar INT
, @CikanTonaj FLOAT(53)
, @KalanMiktar INT
, @KalanTonaj FLOAT(53)
, @Tarih DATETIME
AS
BEGIN
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = N'insert into ' + @TableName
+ N'(MalzemeStokNo, MalzemeAd, Irsaliye, MalzemeAgirlik,GirenMiktar,GirenTonaj,CikanMiktar,
CikanTonaj,KalanMiktar,KalanTonaj,Tarih)
values (@MalzemeStokNo1,
@MalzemeAd1,
@Irsaliye1,
@MalzemeAgirlik1,
@GirenMiktar1,
@GirenTonaj1,
@CikanMiktar1,
@CikanTonaj1,
@KalanMiktar1,
@KalanTonaj1,
@Tarih1)';
EXECUTE sp_executesql
@SQL
, N'@MalzemeStokNo1 varchar(50),@MalzemeAd1 varchar(100),@Irsaliye1 varchar(100),@MalzemeAgirlik1 varchar(50),
@GirenMiktar1 int,@GirenTonaj1 FLOAT (53),@CikanMiktar1 int,@CikanTonaj1 FLOAT (53),@KalanMiktar1 int,@KalanTonaj1 FLOAT (53),@Tarih1 datetime'
, @MalzemeStokNo1 = @MalzemeStokNo
, @MalzemeAd1 = @MalzemeAd
, @Irsaliye1 = @Irsaliye
, @MalzemeAgirlik1 = @MalzemeAgirlik
, @GirenMiktar1 = @GirenMiktar
, @GirenTonaj1 = @GirenTonaj
, @CikanMiktar1 = @CikanMiktar
, @CikanTonaj1 = @CikanTonaj
, @KalanMiktar1 = @KalanMiktar
, @KalanTonaj1 = @KalanTonaj
, @Tarih1 = @Tarih;
END;
Hi @ÖMER NASUHİ KESKİN
Although you made improvements to your previous code, you still haven't noticed the problem.
declare @SQL nvarchar(max)
In your code, you set the @sql to nvarchar, so you need to make sure that the string to the right of '=' also needs to be nvarchar. Like Olaf mentioned datetime, and 'insert into' and the @Irsaliye you set to type varchar above, etc.
Dynamic SQL is a complex feature, and you need to use it for complex work, so you must be careful when writing code to avoid problems as much as possible. Otherwise, if you report an error at runtime, it will be difficult to find the problem in the whole string of code.
Best regards,
Percy Tang
If the answer is the right solution, please click "Accept Answer". If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our Documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
There is a table in the database where some dates have data type VARCHAR and some are DATE. When I am executing the query, the dates in the result appear in YYYY-MM-DD format. I am working on a stored procedure where I am using the fields which have the dates as VARCHAR.
The stored procedure is executing correctly but my rdl file is showing the error -
"An error occurred during local report processing. Conversion failed when converting date and/or time from character string"
I have tried changing the format of these fields in Report Builder to Number > Date and then run it but shows the same error.
Does anyone know a solution for this error?
Thanks!