Error in Updating a table using datetime as parameter in Stored procedure - sql

Here is my query:
UPDATE Mst_Attendance
SET FNLogged=#FNLogged,
ANLogged=#ANLogged,LogTime=#LogTime,LogOuttime=#LogOuttime
WHERE EmployeeId=#Employee_id AND Atdate = CONVERT(VARCHAR(10), #AtDate, 101) AS [MM/DD/YYYY]
-- Convert(Datetime,#AtDate)
SELECT * FROM Mst_Attendance where Atdate=#AtDate and EmployeeId=#Employee_id
Error occured near AS

Just remove the AS [MM/DD/YY] snippet. You don't need it, and it's not valid inside a WHERE clause.
And what in the world are you doing storing dates as strings in your database? That's just a bad idea. Are you trying to truncate the time portion?

AS in that context is used to give an alias to a column or table; there is no sense in an AS here, since that isn't a select.
You have already specified a format via CONVERT(VARCHAR(10), #AtDate, 101), but this also seems odd; dates are not strings. If you are matching on a datetime - keep everything as a datetime.
If you are actually trying to remove the time portion (leaving just a date), either a: don't send the time (cut it at the caller), or b: do something like:
set #date = cast(floor(cast(#date as float)) as datetime)

Related

Why isn't SQL Server letting me store '21/04/17' as a date?

I've got a table that currently has all columns stored as nvarchar(max), so I'm converting all the datatypes to be what they should be. I have a column of dates, however when I run this:
ALTER TABLE Leavers ALTER COLUMN [Actual_Termination_Date] date;
I get
"Conversion failed when converting date and/or time from character string".
This is relatively normal, so I did the following to investigate:
SELECT DISTINCT TOP 20 [Actual_Termination_Date]
FROM LEAVERS
WHERE ISDATE([Actual_Termination_Date]) = 0
which returned:
NULL
13/04/2017
14/04/2017
17/04/2017
19/04/2017
21/04/2017
23/04/2017
24/04/2017
26/04/2017
28/04/2017
29/03/2017
29/04/2017
30/04/2017
31/03/2017
42795
42797
42813
42817
42820
42825
The null and excel style date formats (e.g. 42795) are no problem, however it's the ones appearing as perfectly normal dates I'm having a problem with. I usually fix issues like this by using one of the following fixes:
SELECT cast([Actual_Termination_Date] - 2 as datetime)
FROM LEAVERS
WHERE ISDATE([Actual_Termination_Date]) = 0
or
SELECT cast(convert(nvarchar,[Actual_Termination_Date], 103) - 2 as datetime)
FROM LEAVERS
WHERE ISDATE([Actual_Termination_Date]) = 0
When these return back the dates as I would expext, I'd then do an UPDATE statement to change them in the table and then convert the column type. However I keep getting an error message telling me that various dates can't be converted such as:
Conversion failed when converting the nvarchar value '21/04/2017' to data type int.
Any thoughts? Thanks!
Probably because of your language setting. For '21/04/2017' to work, you'll need to be using the BRITISH language, or other language that uses dd/MM/yyyy. I suspect you are using ENGLISH which is actually American.
American's use MM/dd/yyyy meaning that '21/04/2017' would mean the 4th day of the 21st month in the year 2017; obviously that doesn't work.
The best method is to use an unambiguous format, regardless of language and data type. For SQL Server that's yyyyMMdd and yyyy-MM-ddThh:mm:ss.nnnnnnn (yyyy-MM-dd and yyyy-MM-dd hh:mm:ss.nnnnnnn are not unambiguous in SQL Server when using the older datetime and smalldatetime data types).
Otherwise you can use CONVERT with a style code:
SELECT CONVERT(date,'21/04/2017', 103)
The problem with your data, however, is that you have values that are in the format dd/MM/yyyy and integer values. The int (not varchar) value 42817 as a datetime in SQL Server is 2017-03-25. On the other hand, if this data came from Excel then the value is 2017-03-23. I am going to assume the data came from Excel, not SQL Server (because the ACE drivers have a habit of reading dates as numbers, because the thing they aren't is "ace").
You'll need to therefore convert the values to an unambiguous format first, so that'll be yyyyMMdd. As we have 2 different types of values, this is a little harder, but still possible:
UPDATE dbo.Leavers
SET Actual_Termination_Date = CONVERT(varchar(8), ISNULL(TRY_CONVERT(date, Actual_Termination_Date, 103), DATEADD(DAY, TRY_CONVERT(int, Actual_Termination_Date),'18991230')), 112);
Then you can alter your table:
ALTER TABLE dbo.Leavers ALTER COLUMN [Actual_Termination_Date] date;
DB<>Fiddle using MichaƂ Turczyn's DML statement.
Put the column into a canonical format first, then convert:
update leavers
set Actual_Termination_Date = try_convert(date, [Actual_Termination_Date], 103);
ALTER TABLE Leavers ALTER COLUMN [Actual_Termination_Date] date;
The update will do an implicit conversion from the date to a string. The alter should be able to "undo" that implicit conversion.
Back up the table before you do this! You are likely to discover that some dates are not valid -- that is pretty much the rule when you store dates as strings although in a small minority of cases, all date strings are actually consistently formatted.
The actual date does not matter. The error happens when you try to subtract 2 from a string:
[Actual_Termination_Date] - 2
The clue comes from the error message:
Conversion failed when converting the nvarchar value '21/04/2017' to data type int.
To fix the problem, use DATEADD after the conversion:
SELECT DATEADD(days, -2, convert(datetime, [Actual_Termination_Date], 103))
You just have inconsistent date format within your column, which is terrible.
Having wrong datatype lead to it, that's why it is so important to have proper data types on columns.
Let's investigate it a little:
-- some test data
declare #tbl table (dt varchar(20));
insert into #tbl values
(NULL),
('13/04/2017'),
('14/04/2017'),
('17/04/2017'),
('19/04/2017'),
('21/04/2017'),
('23/04/2017'),
('24/04/2017'),
('26/04/2017'),
('28/04/2017'),
('29/03/2017'),
('29/04/2017'),
('30/04/2017'),
('31/03/2017'),
('42795'),
('42797'),
('42813'),
('42817'),
('42820'),
('42825');
-- here we handle one format
select convert(date, dt, 103) from #tbl
where len(dt) > 5
or dt is null
-- here we handle excel like format
select dateadd(day, cast(dt as int), '1900-01-01') from #tbl
where len(dt) = 5
So, as you can see you have to apply to different approaches for this task. CASE WHEN statement should fit here nicely, see below SELECT:
select case when len(dt) = 5 then
dateadd(day, cast(dt as int), '1900-01-01')
else convert(date, dt, 103) end
from #tbl

Calculate Time Difference for Date/Time Variable

I have two variables 'triage_date_time' and 'checkin_date_time'. Both are formatted as, for example, 2018-12-31 14:13:00. Showing the year-month-day and hour-minute-second both within one cell.
I wanted to create a variable that calculates the time it takes from check-in to triage.
I attempted to use the following code:
SELECT DISTINCT datediff(minute, 'triage_date_time', 'checkin_date_time') as
checkin_to_triage
However, when running this code I get the following error... "Conversion failed when converting date and/or time from character string".
Any suggestions of how I can write a code that would calculate the minute difference of these two variables.
Thanks!
One problem is obviously the single quotes. Assuming that you are using SQL Server, variables start with #. So:
select datediff(minute, #triage_date_time, #checkin_date_time) as checkin_to_triage
If you are confused and really mean columns in a table, then:
select datediff(minute, triage_date_time, checkin_date_time) as checkin_to_triage
from t;
could it be that your field is a CHARACTER data type ?
cast your char to datetime
SELECT DISTINCT datediff(minute, CAST(triage_date_time AS datetime), CAST(checkin_date_time AS datetime)) as checkin_to_triage
Try with this query
DECLARE #triage_date_time DATETIME = '20181231 14:13:00'
DECLARE #checkin_date_time DATETIME = '20181231 16:13:00'
SELECT DATEDIFF (MINUTE, #triage_date_time, #checkin_date_time) AS 'checkin_to_triage'
Output :
checkin_to_triage
120

Convert from nvarchar to datetime from a large record table with potentially bad date strings

I have a main table called Cases that I am inserting data into. I have a alternative table where all of the raw data called rawTableData is stored and then sent to the main table.
I have a nvarchar column in my rawTableDatathat stores a datetime string in this format
2016-04-04-10.50.02.351232
I have a column in my Cases table that has a datatype of DATETIME.
I first tried to find the bad data in this method below
SELECT CONVERT(datetime, nvarcharDateColumn, 103)
FROM rawTableData
WHERE ISDATE(CONVERT(datetime, nvarcharDateColumn, 103)) != 1
And I get the error below
The conversion of nvarchar data type to a datetime data type resulted in an out-of-range value.
Then I tried a different approach hoping to find all of the out of range values
SELECT nvarcharDateColumn
FROM rawTableData
WHERE ISDATE(nvarcharDateColumn)
But that only returns all rows since its nvarchar.
Again, I kept going and tried a different approach
SELECT CONVERT(DATETIME, CASE WHEN ISDATE(nvarcharDateColumn) = 1 THEN nvarcharDateColumn END, 103)
FROM rawTableData
I am not sure what I am doing wrong here and any help would be appreciated.
I am using SQL Server 2012
You can use TRY_CONVERT:
SELECT nvarchardatecolumn, TRY_CONVERT(date, nvarchardatecolumn)
FROM rawTableData
And if you only want to return the invalid dates, use a derived table:
SELECT *
FROM (SELECT nvarchardatecolumn, TRY_CONVERT(date, nvarchardatecolumn) DateCheck
FROM rawTableData
) A
WHERE DateCheck IS NULL

Convert YYYYMMDD to DATE

I have a bunch of dates in varchar like this:
20080107
20090101
20100405
...
How do I convert them to a date format like this:
2008-01-07
2009-01-01
2010-04-05
I've tried using this:
SELECT [FIRST_NAME]
,[MIDDLE_NAME]
,[LAST_NAME]
,cast([GRADUATION_DATE] as date)
FROM mydb
But get this message:
Msg 241, Level 16, State 1, Line 2Conversion failed when converting date and/or time from character string.
The error is happening because you (or whoever designed this table) have a bunch of dates in VARCHAR. Why are you (or whoever designed this table) storing dates as strings? Do you (or whoever designed this table) also store salary and prices and distances as strings?
To find the values that are causing issues (so you (or whoever designed this table) can fix them):
SELECT GRADUATION_DATE FROM mydb
WHERE ISDATE(GRADUATION_DATE) = 0;
Bet you have at least one row. Fix those values, and then FIX THE TABLE. Or ask whoever designed the table to FIX THE TABLE. Really nicely.
ALTER TABLE mydb ALTER COLUMN GRADUATION_DATE DATE;
Now you don't have to worry about the formatting - you can always format as YYYYMMDD or YYYY-MM-DD on the client, or using CONVERT in SQL. When you have a valid date as a string literal, you can use:
SELECT CONVERT(CHAR(10), CONVERT(datetime, '20120101'), 120);
...but this is better done on the client (if at all).
There's a popular term - garbage in, garbage out. You're never going to be able to convert to a date (never mind convert to a string in a specific format) if your data type choice (or the data type choice of whoever designed the table) inherently allows garbage into your table. Please fix it. Or ask whoever designed the table (again, really nicely) to fix it.
Use SELECT CONVERT(date, '20140327')
In your case,
SELECT [FIRST_NAME],
[MIDDLE_NAME],
[LAST_NAME],
CONVERT(date, [GRADUATION_DATE])
FROM mydb
In your case it should be:
Select convert(datetime,convert(varchar(10),GRADUATION_DATE,120)) as
'GRADUATION_DATE' from mydb
I was also facing the same issue where I was receiving the Transaction_Date as YYYYMMDD in bigint format. So I converted it into Datetime format using below query and saved it in new column with datetime format. I hope this will help you as well.
SELECT
convert( Datetime, STUFF(STUFF(Transaction_Date, 5, 0, '-'), 8, 0, '-'), 120) As [Transaction_Date_New]
FROM mydb
Just to add more info about all solution above:
SELECT [FIRST_NAME],
[MIDDLE_NAME],
[LAST_NAME],
CONVERT(date, [GRADUATION_DATE])
FROM mydb
Assuming you don't have a WHERE clause, it is ok, the Convert will try to return all dates even if it is not a valid date like '00000000' (it was in my case).
But, if you need a WHERE clause, so you can see a message like this:
So I tested a mix of some approaches mentioned above like:
DECLARE #DateStart datetime = '2021-02-18'
DECLARE #DateEnd datetime = '2021-02-19'
SELECT [FIRST_NAME],
[MIDDLE_NAME],
[LAST_NAME],
CONVERT(date, [GRADUATION_DATE])
FROM mydb
WHERE
--THIS LINE SHOULD BE ENOUGTH TO AVOID WRONG DATES, BUT IT IS NOT
ISDATE([GRADUATION_DATE]) = 1 AND
CONVERT(char(10), [GRADUATION_DATE], 120) BETWEEN #DateStart and #DateEnd
And Finally I used this way with success:
DECLARE #DateStart datetime = '2021-02-18'
DECLARE #DateEnd datetime = '2021-02-19'
SELECT [FIRST_NAME],
[MIDDLE_NAME],
[LAST_NAME],
CONVERT(date, [GRADUATION_DATE])
FROM mydb
WHERE
CONVERT(char(10),
-- I ADDED THIS LINE TO IGNORE WRONG DATES
CASE WHEN ISDATE([GRADUATION_DATE]) = 1 THEN [GRADUATION_DATE] ELSE '1900-01-01' END, 120)
BETWEEN #DateStart and #DateEnd

how to remove time from datetime

The field DATE in the database has the following format:
2012-11-12 00:00:00
I would like to remove the time from the date and return the date like this:
11/12/2012
First thing's first, if your dates are in varchar format change that, store dates as dates it will save you a lot of headaches and it is something that is best done sooner rather than later. The problem will only get worse.
Secondly, once you have a date DO NOT convert the date to a varchar! Keep it in date format and use formatting on the application side to get the required date format.
There are various methods to do this depending on your DBMS:
SQL-Server 2008 and later:
SELECT CAST(CURRENT_TIMESTAMP AS DATE)
SQL-Server 2005 and Earlier
SELECT DATEADD(DAY, DATEDIFF(DAY, 0, CURRENT_TIMESTAMP), 0)
SQLite
SELECT DATE(NOW())
Oracle
SELECT TRUNC(CURRENT_TIMESTAMP)
Postgresql
SELECT CURRENT_TIMESTAMP::DATE
If you need to use culture specific formatting in your report you can either explicitly state the format of the receiving text box (e.g. dd/MM/yyyy), or you can set the language so that it shows the relevant date format for that language.
Either way this is much better handled outside of SQL as converting to varchar within SQL will impact any sorting you may do in your report.
If you cannot/will not change the datatype to DATETIME, then still convert it to a date within SQL (e.g. CONVERT(DATETIME, yourField)) before sending to report services and handle it as described above.
just use, (in TSQL)
SELECT convert(varchar, columnName, 101)
in MySQL
SELECT DATE_FORMAT(columnName, '%m/%d/%Y')
I found this method to be quite useful. However it will convert your date/time format to just date but never the less it does the job for what I need it for. (I just needed to display the date on a report, the time was irrelevant).
CAST(start_date AS DATE)
UPDATE
(Bear in mind I'm a trainee ;))
I figured an easier way to do this IF YOU'RE USING SSRS.
It's easier to actually change the textbox properties where the field is located in the report. Right click field>Number>Date and select the appropriate format!
SELECT DATE('2012-11-12 00:00:00');
returns
2012-11-12
Personally, I'd return the full, native datetime value and format this in the client code.
That way, you can use the user's locale setting to give the correct meaning to that user.
"11/12" is ambiguous. Is it:
12th November
11th December
For more info refer this: SQL Server Date Formats
[MM/DD/YYYY]
SELECT CONVERT(VARCHAR(10), cast(dt_col as date), 101) from tbl
[DD/MM/YYYY]
SELECT CONVERT(VARCHAR(10), cast(dt_col as date), 103) from tbl
Live Demo
TSQL
SELECT CONVERT(DATE, GETDATE()) // 2019-09-19
SELECT CAST(GETDATE() AS DATE) // 2019-09-19
SELECT CONVERT(VARCHAR, GETDATE(), 23) // 2019-09-19
In mysql at least, you can use DATE(theDate).
You may try the following:
SELECT CONVERT(VARCHAR(10),yourdate,101);
or this:
select cast(floor(cast(urdate as float)) as datetime);
Use this SQL:
SELECT DATE_FORMAT(date_column_here,'%d/%m/%Y') FROM table_name;