Executing the stored procedure causes error - sql

I have a stored procedure in which I want to get the reportdate while executing.
I pass one parameter to the stored procedure for executing it,. I pass it like this
exec UserReportData '10-06-2016'
but I get an error:
The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.
This is my stored procedure:
ALTER PROCEDURE [dbo].[UserReportData]
#As_ONDATE Datetime
AS
BEGIN
DECLARE #REPORTDATE datetime
--DECLARE #OPENING INT
SELECT *
INTO #temptable
FROM
(SELECT
a.CUser_id, b.User_Id, a.U_datetime AS REPORTDATE
FROM
inward_doc_tracking_trl a, user_mst b
WHERE
a.CUser_id = b.mkey
AND CONVERT(varchar(50), a.U_datetime, 103) = #As_ONDATE) AS x
DECLARE Cur_1 CURSOR FOR
SELECT CUser_id, User_Id
FROM #temptable
OPEN Cur_1
DECLARE #CUser_id INT
DECLARE #User_Id INT
FETCH NEXT FROM Cur_1 INTO #CUser_id, #User_Id
WHILE (##FETCH_STATUS = 0)
BEGIN
SELECT CONVERT(varchar(50), U_datetime, 103)
FROM inward_doc_tracking_trl
WHERE CONVERT(varchar(50), U_datetime, 103) = #As_ONDATE
UPDATE #temptable
SET REPORTDATE = #REPORTDATE
WHERE CUser_id = #CUser_id
AND User_Id = #User_Id
FETCH NEXT FROM Cur_1 INTO #CUser_id, #User_Id
END
CLOSE Cur_1
DEALLOCATE Cur_1
SELECT * FROM #temptable
DROP TABLE #temptable
END
Kindly help me know what is the cause of the error.

The various settings (language, date format) only influence how the DateTime is shown to you in SQL Server Management Studio - or how it is parsed when you attempt to convert a string to a DateTime.
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:
YYYYMMDD for just dates (no time portion); note here: no dashes!, that's very important! YYYY-MM-DD is NOT independent of the dateformat settings in your SQL Server and will NOT work in all situations!
or:
YYYY-MM-DDTHH:MM:SS for dates and times - note here: this format has dashes (but they can be omitted), and a fixed T as delimiter between the date and time portion of your DATETIME.
This is valid for SQL Server 2000 and newer.
If you use SQL Server 2008 or newer and the DATE datatype (only DATE - not DATETIME!), then you can indeed also use the YYYY-MM-DD format and that will work, too, with any settings in your SQL Server.
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.
The recommendation for SQL Server 2008 and newer is to use DATE if you only need the date portion, and DATETIME2(n) when you need both date and time. You should try to start phasing out the DATETIME datatype if ever possible
So in your concrete case - just change how you call your stored procedure to:
exec UserReportData '20160610' -- 10th of June, 2016
or
exec UserReportData '20161006' -- 6th of October, 2016
depending on whether this was the 6th October or the 10th June of 2016 you're interested in ...

You are passing datetime, by default SQL Server uses MMDDYYYY or YYYYMMDD format.
You are using the DD-MM-YYYY format,
Either you write as
set dateformat dmy --set ddmmyyyy format
exec UserReportData '10-06-2016'
set dateformat mdy --set default again
or you passed the value which is in proper format. No other solution work.

Related

UPDATE SET FORMAT not working in SQL Server 2016?

FORMAT instruction works in a SELECT but has no effect in an UPDATE:
SELECT ##VERSION
DROP TABLE IF EXISTS #t;
CREATE TABLE #t(DateMin datetime);
INSERT INTO #t VALUES ('2019-13-01 00:00:00')
SELECT * FROM #t
UPDATE #t SET DateMin = FORMAT(DateMin, 'dd/MM/yyyy');
SELECT * FROM #t;
SELECT #DateMin AS a, FORMAT(#DateMin, 'dd/MM/yyyy') AS b
A type like DATETIME isn't stored with a format.
So if one updates a DATETIME with a string in a certain format, it doesn't matter for the stored value in the DATETIME field.
The formatted string is implicitly converted to a datetime. At least if it's in a format that's valid.
The function FORMAT, which returns a NVARCHAR is rather used for representation of the datetime field in a query.
Or if one wants to INSERT/UPDATE a string field with a datetime in a certain format. But that should be avoided, because it's much easier to work with a datetime than a string.
If you want to change that format for the user use this:
set dateformat dmy;
By running this statement:
DBCC USEROPTIONS;
you will see your dateformat is ydm so you can alway back it up to that if this is not what you wanted :)
You cannot set the output format of a datetime in the datetime itselfs.
If you need to output the datetime as formatted char/varchar, you need to use the convert-function when you select the data:
SELECT CONVERT(char(10), CURRENT_TIMESTAMP, 101) -- format: MM/dd/yyyy
SELECT CONVERT(char(10), CURRENT_TIMESTAMP, 103) -- format: dd/MM/yyyy
In your case:
SELECT #DateMin AS a, CONVERT(char(10), #DateMin, 103) AS b
That works as expected.
If you want to have a mutable data-type, you need to declare it as sql_variant:
DROP TABLE IF EXISTS #t;
CREATE TABLE #t(DateMin sql_variant);
INSERT INTO #t VALUES ('2019-01-13T00:00:00')
UPDATE #t SET DateMin = FORMAT(CAST(DateMin AS datetime), 'dd''/''MM''/''yyyy');
SELECT * FROM #t;
Also, your format-expression needs to explicitly put the / into quotation marks, aka 'dd''/''MM''/''yyyy', otherwise sql-server replaces it with the date-separator specific to the current culture, which would be . in my case.
Just use convert with option 103 instead, it works on all versions of sql-server and it's probably faster.
Also, your insert-statement fails on some versions of sql-server, because iso-date-format is 2019-01-13T00:00:00 and not 2019-13-01 00:00:00
Correct is:
INSERT INTO #t VALUES ('2019-01-13T00:00:00')
Also
DROP TABLE IF EXISTS #t;
is sql-server 2016+ only, otherwise you need
IF OBJECT_ID('tempdb..#t') IS NOT NULL DROP TABLE #t
And post sql-server 2005, you should use datetime2 instead of datetime.
You shouldn't use datetime anymore, because datetime uses float, and as such is imprecise - if you insert an iso datetime value, it can do funny things because of the float-point-machine-epsilon, e.g. set it to the next day if you have 23:59:59.999, just as a scary example.
I advise you to never use the sql_variant type. If you have a temp-table with defined columns, just create another column where you will write the char/varchar value to.

Convert date string to date sql server

I have a table tbl with column cln varchar(50).
Data is stored in format 'January-2008', February-2009, March-2010 etc(full month name)
I want to convert it to date (for comparison, sort etc).
please try below query
DECLARE #v varchar(20)
SET #v='January-2008'
SELECT CAST('01-'+#V as DATE)
Since you don't get the day data and only -, we'll add '01-' to complete the date day part.
sql fiddle link: http://sqlfiddle.com/#!6/6f326/7
Use Convert with Style to avoid errors in different date settings
DECLARE #v varchar(20)
SET #v='January-2008'
SELECT CONVERT(DATETIME,'01-'+#v,13)

SQL Formatting issue when converting varchar to date 103

I have a date field I pull in from excel as a varchar type and I currently convert it using this line:
convert(date,[Appt Date],103) as [Appt date]
this works but the result is a date in the following format:
YYYY/MM/DD
According to other sites the 103 format at the end of the line should convert this varchar to UK formatting ( DD/MM/YYYY ).
Can anyone advise why this is not happening?
By default, MSSQL server store dates in YYYY/MM/DD. You can only change the language on the whole server, not individual databases.
set language 'british english'
run this first before inserting.
or another alternative is to use SET DATEFORMAT (from MSDN)
declare #dates table (orig varchar(50) ,parsed datetime)
SET DATEFORMAT ydm;
insert into #dates
select '2008-09-01','2008-09-01'
SET DATEFORMAT ymd;
insert into #dates
select '2008-09-01','2008-09-01'
select * from #dates
It should be VARCHAR not DATE
SELECT convert(VARCHAR(20),[Appt Date],103) as [Appt date]

Store date without time in SQL database where datatype is datetime [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Storing the date Only in SQL Server 2005
I am using SQL Server 2005 database. When I store a date there is only datetime as datatype for dates, so whenever I remove time from date and store it in database it takes the default time but I want to get it store as only date and not time
Upgrade to SQL Server 2008 which has a date datatype. Otherwise just let it put in the time as midnight and ignore it when querying. The one thing you do NOT want to do is store it as a varchar or nvarchar.
You'll have to store the value as a datetime and just ignore the time part.
You could create a user-defined type as described in this blog post but it seems more trouble than it's worth.
Just use an int instead of a Datetime, Or, you could create your own datatype
CREATE TYPE [dbo].[MyDateType] FROM [int]
And just cast dates to/from this datatype
Declare #Dt Datetime Set #dt = '11 June 2011 08:00'
Declare #MyDt int
Set #MyDt = Cast(#dt as int)
Select Cast (#MyDt as DateTime)
or using the custom data type...
Declare #Dt Datetime Set #dt = '11 June 2011 08:00'
Declare #MyDt MyDateType
Set #MyDt = Cast(#dt as MyDateType)
Select Cast (#MyDt as DateTime)

How to enter a Date into a table in TSQL? (Error converting data type varchar to datetime)

I want to enter 30/10/1988 as the date to a DOB column in a table using a procedure
alter procedure addCustomer
#userName varchar(50),
#userNIC varchar(50),
#userPassword varchar(100),
#userDOB datetime,
#userTypeID int,
#userEmail varchar(50),
#userTelephone int,
#userAddress char(100),
#userCityID int,
#status int output
as
declare #userID int
declare #eid int
declare #tid int
declare #aid int
execute getLastRaw 'userID','tblUserParent', #userID output
insert into tblUserParent values (#userID, #userName, #userNIC, #userPassword, #userDOB, #userTypeID)
execute getLastRaw 'addressID','tblAddress', #aid output
insert into tblAddress values (#aid, #userAddress, #userID, #userCityID)
execute getLastRaw 'emailID','tblEmail', #eid output
insert into tblEmail values (#eid, #userEmail, #userID)
execute getLastRaw 'telephoneID','tblTelephoneNO', #tid output
insert into tblTelephoneNO values (#tid, #userTelephone , #userID)
insert into tblUserCustomer values (#userID, #eid , #tid, #aid)
...but it gives an error when i enter like this '30/10/1988'
Msg 8114, Level 16, State 5, Procedure addCustomer, Line 0 Error converting data type varchar to datetime.
...but when I enter like only the 30/10/1988
Incorrect syntax near '/'
How do I fix this?
If you would truly like to avoid the possibility of ambiguous dates based, then you should always enter it in one of the two unambiguous date formats Answer has already been selected and it's valid but I'm a believer in spreading the knowledge ;)
As noticed by #cloud and my post representing a younger, and less wise me with a link only answer, I'll pop the contents of the archive of Jamie Thompson's answer for unambiguous date formats in TSQL
tl;dr;
yyyy-MM-ddTHH24:mi:ss
yyyyMMdd HH24:mi:ss
One of the most commonly used data types in SQL Server is [datetime]
which unfortunately has some vagaries around how values get casted. A
typical method for defining a [datetime] literal is to write it as a
character string and then cast it appropriately. The cast syntax looks
something like this: DECLARE #dt NVARCHAR(19) = '2009-12-08 18:00:00';
SELECT CAST(#dt AS datetime);
Unfortunately in SQL Server 2005 the result of the cast operation may
be dependent on your current language setting. You can discover your
current language setting by executing: SELECT ##LANGUAGE To
demonstrate how your language setting can influence the results of a
cast take a look at the following code: ALTER DATABASE tempdb
SET COMPATIBILITY_LEVEL = 90 ; --Behave like SQL Server 2005
USE tempdb
GO
DECLARE #t TABLE (
dateString NVARCHAR(19)
);
INSERT #t (dateString)
VALUES ('2009-12-08 18:00:00') --'yyyy-MM-dd hh24:mi:ss'
, ('2009-12-08T18:00:00') --'yyyy-MM-ddThh24:mi:ss'
, ('20091208 18:00:00') --'yyyyMMdd hh24:mi:ss'
SET LANGUAGE french;
SELECT 'french' AS lang
, DATENAME(MONTH,q.[dt]) AS mnth
, q.[dt]
FROM (
SELECT CAST(dateString AS DATETIME) AS dt
FROM #t
)q;
SET LANGUAGE us_english;
SELECT 'us_english' AS lang
, DATENAME(MONTH,q.[dt]) AS mnth
, q.[dt]
FROM (
SELECT CAST(dateString AS DATETIME) AS dt
FROM #t
)q; We are taking the value which can be described in words as “6pm on 8th December 2009”, defining it in three different ways, then
seeing how the ##LANGUAGE setting can affect the results. Here are
those results: french language datetime Notice how the interpretation
of the month can change depending on ##LANGUAGE. If
##LANGUAGE=’french’ then the string '2009-12-08 18:00:00' is
interpreted as 12th August 2009 (‘août’ is French for August for those
that don’t know) whereas if ##LANGUAGE=’us_english’ it is interpreted
as 8th December 2009. Clearly this is a problem because the results of
our queries have a dependency on a server-level or connection-level
setting and that is NOT a good thing. Hence I recommend that you only
define [datetime] literals in one of the two unambiguous date formats:
yyyy-MM-ddTHH24:mi:ss yyyyMMdd HH24:mi:ss That was going to be the end
of this blog post but then I found out that this behaviour changed
slightly in SQL Server 2008. Take the following code (see if you can
figure out what the results will be before I tell you): ALTER
DATABASE tempdb
SET COMPATIBILITY_LEVEL = 100 ; --Behave like SQL Server 2008
GO
USE tempdb
GO
SET LANGUAGE french;
DECLARE #dt NCHAR(10) = '2009-12-08 18:00:00'; --Ambiguous date
format
SELECT CAST(#dt AS datetime) AS [ExplicitCast]
, DATENAME(MONTH,#dt) AS [MonthFromImplicitCast]
, DATENAME(MONTH,CAST(#dt AS datetime)) AS
[MonthFromExplicitCast]; Here we are doing three different things with
our nchar literal: explicitly cast it as a [datetime] extract the
month name from the char literal using the DATENAME function (which
results in an under-the-covers implicit cast) extract the month name
from the char literal using the DATENAME function after it has been
explicitly casted as a [datetime] Note that the compatibility level is
set to SQL Server 2008 and ##LANGUAGE=’french’. Here are the results:
image (Were you correct?) Let’s take a look at what is happening here.
The behaviour when we are explicitly casting as [datetime] hasn’t
changed, our nchar literal is still getting interpreted as 12th August
rather than 8th December when ##LANGUAGE=’french’. The
[MonthFromExplicitCast] field is interesting though, it seems as
though the implicit cast has resulted in the desired value of 8th
December. Why is that? To get the answer we can turn to BOL’s
description of the DATENAME function syntax: image The implicit cast
is not casting to [datetime] at all, it is actually casting to [date]
which is a new datatype in SQL Server 2008. The new date-related
datatypes in SQL Server 2008 (i.e. [date], [datetime2], [time],
[datetimeoffset]) disregard ##LANGUAGE and hence we get behaviour that
is more predictable and, frankly, better. These new behaviours for SQL
Server 2008 were unknown to me when I began this blog post so I have
learnt something in the course of authoring it, I hope it has helped
you too. No doubt someone somewhere is going to get nastily burnt by
this at some point, make sure that it isn’t you by always using
unambiguous date formats: yyyy-MM-ddTHH24:mi:ss yyyyMMdd HH24:mi:ss
regardless of which version you are on!
The following works in both SQL Server and MySql without ambiguity: yyyy-mm-dd, like so:
INSERT INTO TableName(DateColumn) VALUES ('1988-10-30');
...as an added benefit there's no question of whether it's a US or European style date on days like the fourth of March...
See if there is a culture setting that you can change to allow you to use dd/mm/yyyy. I believe it is expecting mm/dd/yyyy.
A potentially easy way around the problem is to use a date format with no ambiguity between mm/dd/yyyy and dd/mm/yyyy such as dd-mmm-yyyy, eg: 30-OCT-1988