SQL convert DATETIME TO VARCHAR? - sql

I am working on a query something require DATE!!
DECLARE #YesterDay DATETIME, #Today DATETIME
SET #YesterDay = DateAdd(DD, DateDiff(DD, 0, GETDATE())-1, 0)
SET #Today = DateAdd(DD, DateDiff(DD, 0, GETDATE()), 0)
select #YesterDay = convert(varchar, getdate()-1 , 110)
select #Today = convert(varchar, getdate() , 110)
EXEC #return_value = [dbo].[post_sec_admin_list_user_log]
#pDateFr = #YesterDay ,
#pDateTo = #Today,
#pName = '',
#pSec = NULL
#DateFr is varchar(50)
#DateT0 is varchar(50)
the #dateFr and #dateTo are both varchar..
And I try to execute it, it print the time format as this 2011-06-09 16:15:38.927
error statement
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
Additionally, the varchar format I need is MM-DD-YYYY
Anyone know where is my error at?
thanks

Your code is confusing:
DECLARE #YesterDay DATETIME, #Today DATETIME
SET #YesterDay = DateAdd(DD, DateDiff(DD, 0, GETDATE())-1, 0)
SET #Today = DateAdd(DD, DateDiff(DD, 0, GETDATE()), 0)
select #YesterDay = convert(varchar, getdate()-1 , 110)
select #Today = convert(varchar, getdate() , 110)
So you declare it as DATETIME, set value with DateDiff then overwrite that value with an varchar representation of a date that is recalculated using different method.
At line 4 and 5 #Yesterday and #Today variables are still DATETIME, because it's declared that way.
EDIT: As mentioned in the comment to my answer you need a variable to pass to the procedure.
So the correct fix would be to declare the variables as VARCHAR(50) at the beginning and do the conversion directly.
DECLARE #YesterDay VARCHAR(50), #Today VARCHAR(50)
SELECT #YesterDay = convert(varchar(50), dateadd(dd, -1, getdate()) , 110)
SELECT #Today = convert(varchar(50), getdate() , 110)
And then call the procedure the way you did originally.

My guess is that getdate()-1 part is wrong.
Also, you were making dateadd and datediff why? Try it like this:
SET #YesterDay = dateadd(dd, -1, GETDATE())
SET #Today = GETDATE()
select #YesterDay = convert(varchar(50), dateadd(dd, -1, getdate()) , 110)
select #Today = convert(varchar(50), getdate() , 110)
EXEC #return_value = [dbo].[post_sec_admin_list_user_log]
#pDateFr = #YesterDay ,
#pDateTo = #Today,
#pName = '',
#pSec = NULL

Related

DateDiff In months between two different types date formats

I have two date formats, EndDate in YYYYMMDD format and another Monthfirstdate in YYYY-MM-DD FORMAT. I need to get the difference between these two dates.
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE #Date DATE = dbo.value('DATE')
SELECT
E.EmployeeID
,E.StartDateKey
,E.EndDateKey
,E.FromDateKey
,E.ToDateKey
INTO #Employee
FROM
dbo.Employee E
---clean--
DECLARE #StartDate DATE = (SELECT DATEADD(YY, DATEDIFF(YY, 0, #Date) - 1, 0))
DECLARE #EndDate DATE = DATEADD(S, -1, DATEADD(MM, DATEDIFF(MM, 0, #Date) + 3, 0))
SELECT
E.EmployeeID
,CAST(CONVERT(VARCHAR(10), E.StartDateKey, 112) AS INT) AS _EmployeeStartDateKey
,CAST(CONVERT(VARCHAR(10), E.EndDateKey, 112) AS INT) AS _EmployeeFinishDateKey
,CAST(CONVERT(VARCHAR, D.MonthFirstDay, 112) AS INT) AS _DateKey
,???? AS [Tenure]
FROM #Employee AS E
INNER JOIN dbo.Date D ON
D.DateKey BETWEEN E.FromDateKey AND E.ToDateKey
WHERE
D.DateKey BETWEEN #tartDate AND #EndDate
AND D.DayOfMonth = 1
You can try below query in SQL Server:
DECLARE
#firstDate DATETIME = '2022-12-01',
#dateinStringFormat VARCHAR(20)= '20121201',
#endDate DATETIME;
--Converting date string to Datetime format(YYYY-MM-DD)
SELECT #endDate = CONVERT(CHAR(10), CONVERT(datetime, #dateinStringFormat), 120);
--Now, Calculating the date difference in Month
SELECT DATEDIFF(MONTH, #endDate, #firstDate) AS DateDiff;

How to declare a paramater with default value (previous date) in a Stored Procedure?

I want to set default params in a stored procedure as follows:
ALTER PROCEDURE [rpt].[STAT05] --#StartDate = '2017-08-15', #EndDate = '2017-08-16'
#StartDate DATETIME2 = DATEADD(DAY, -2, GETDATE())
,#EndDate DATETIME2 = DATEADD(DAY, -1, GETDATE())
AS
BEGIN
,which however returns:
Must declare the scalar variable "#StartDate".
What's wrong with that statement?
Default value for parameters in sp have to be constants.
ALTER PROCEDURE [rpt].[STAT05]
#StartDate DATETIME2 = null
,#EndDate DATETIME2 =null
AS
BEGIN
IF #StartDate is null
SET #StartDate = DATEADD(DAY, -2, GETDATE())
IF #EndDate is null
SET #EndDate = DATEADD(DAY, -1, GETDATE())

Conditionally setting a variable in SQL

I'm trying to do this:
If the Day parameter is the current day, then set #EndDate to be yesterday instead
If the Day parameter is in the future, set #EndDate to yesterday.
I've tried a few different approaches including two down below. I'm fairly new to programming so odds are I'm missing something fairly simple. Basically, I am trying to set #EndDate conditionally, depending on what #Day is set to be.
DECLARE #Day DATETIME
SET #Day = '09/2/17 12:50'
SET #Day = DATEADD(dd, DATEDIFF(dd, 0, #Day), 0)
DECLARE #Enddate DATETIME
SET #Enddate = CASE #Day
WHEN #Day < GETDATE() THEN GETDATE() - 1
END
--SET #Enddate = #Day
-- WHERE #Day < GETDATE()
--SET #Enddate = GETDATE()-1
-- WHERE#Day >= GETDATE()
Thanks
You are mixing the two possible ways to write a case expression...
You can either use
CASE #day
WHEN GETDATE() THEN 'x'
WHEN DATEADD(DAY, 1, GETDATE() THEN 'y'
END
or then you can use:
CASE
WHEN #day = GETDATE() THEN 'x'
WHEN #day > GETDATE() THEN 'y'
END
This is the correct way:
SET #Enddate = CASE
WHEN #Day < GETDATE()
THEN DATEADD(DAY, -1, GETDATE())
ELSE GETDATE()
END
For clarification, variable #yesterday added as DATE without time
Declare #Day datetime
Set #Day = '09/02/17 12:50'
SET #Day = DATEADD(dd, DATEDIFF(dd, 0, #Day), 0)
Declare #Enddate Datetime
Declare #yesterday as date
SET #yesterday=dateadd(day,-1,getdate())
Set #Enddate = Case
When #day< #yesterday Then #day else #yesterday End
Any values older than yesterday remains as is, other case sets yesterday

How to create a complete datetime from a month and year passed as parameters

I want to let a user select a month and a year in a report from textbox and use these parameters to create first day in the month and the last one for my server parameters 'DateFrom' and 'DateTo', so I can use these as filters.
I've tried:
#DateFrom DATETIME,
#DateTo DATETIME,
#Month NVARCHAR(MAX) = NULL,
#Year NVARCHAR(MAX) = NULL
AS
BEGIN
SET NOCOUNT ON;
SET #DateFrom = '1.' & #Month & #Year
SET #DateTo = DATEADD(m, 1, DATEADD(s, -1, #DateFrom))
Any help would be aprreciated.
Try This
SET #DateFrom = SELECT CAST(#Year + '-' + #Month + '-' + '01' AS DATE)
SET #DateTo = DATEADD(m, 1, DATEADD(s, -1, #DateFrom))

Date Range Based on Today

I am trying to write a stored procedure that will be called by an automated report on the 1st, 8th, 15th, and 22nd of each month.
Below I have the code I am currently trying to use however I keep getting the error Explicit conversion from data type int to date is not allowed. on the line for #StartDate if ran on the 1st. However I have tried commenting out that section and I just get the same error but then for the next #StartDate.
I need #StartDate and #EndDate to be able to change based on which day of the month the report is currently being ran.
On the 1st it would need to be ran from the 21st of the
previous month to the end of the previous month.
On the 8th it would need to be 1st of the current month to the 7th.
On the 15th it would need to be 8th of the current month to the 14th.
On the 22nd it would need to be 15th of the current month to the 21st.
Declare #RunDate date
Declare #StartDate Date
Declare #EndDate Date
Set #RunDate = '3/1/2017'
If (Day(#RunDate) = 1)
Begin
Set #StartDate = Convert(Date,(Month(DATEADD(d,-1,#Rundate)) + '/21/' + Case When Month(#Rundate) = '1' Then Year(#RunDate) Else Year(DATEADD(yy,-1,#Rundate)) End),101)
Set #EndDate = Convert(date,DATEADD(ms,-3,DATEADD(mm,0,DATEADD(mm,DATEDIFF(mm,0,#Rundate),0))),101)
End
Else
IF (Day(#RunDate) = 8)
Begin
Set #StartDate = Convert(Date,(Month(#Rundate) + '/1/' + Year(#RunDate)),101)
Set #EndDate = Convert(Date,(Month(#Rundate) + '/7/' + Year(#RunDate)),101)
End
Else
If (Day(#Rundate) = 15)
Begin
Set #StartDate = Convert(Date,(Month(#Rundate) + '/8/' + Year(#RunDate)),101)
Set #EndDate = Convert(Date,(Month(#Rundate) + '/14/' + Year(#RunDate)),101)
End
Else
If (Day(#Rundate) = 22)
Begin
Set #StartDate = Convert(Date,(Month(#Rundate) + '/15/' + Year(#RunDate)),101)
Set #EndDate = Convert(Date,(Month(#Rundate) + '/21/' + Year(#RunDate)),101)
End
I am using SQL Server 2012 back end with SSMS 2016 front end. If that helps.
You can simplify all of that down to:
Declare #RunDate date, #StartDate date, #EndDate date;
Set #RunDate = '20170301';
If (Day(#RunDate) = 1)
Begin;
Set #StartDate = dateadd(day,20,dateadd(month, datediff(month, 0, #RunDate)-1, 0))
Set #EndDate = dateadd(day,-1,dateadd(month, datediff(month, 0, #RunDate), 0))
End;
Else
If (Day(#RunDate) in (8,15,22))
Begin;
Set #StartDate = dateadd(day,Day(#RunDate)-8,dateadd(month, datediff(month, 0, #RunDate), 0))
Set #EndDate = dateadd(day,Day(#RunDate)-2,dateadd(month, datediff(month, 0, #RunDate), 0))
End;
Alternative using case, but doesn't verify for the day() in 8,15,22:
Declare #RunDate date, #StartDate date, #EndDate date;
Set #RunDate = '20170328';
set #StartDate = case day(#RunDate)
when 1 then dateadd(day,20,dateadd(month, datediff(month, 0, #RunDate)-1, 0))
else dateadd(day,Day(#RunDate)-8,dateadd(month, datediff(month, 0, #RunDate), 0))
end;
set #EndDate = case day(#RunDate)
when 1 then dateadd(day,-1,dateadd(month, datediff(month, 0, #RunDate), 0))
else dateadd(day,Day(#RunDate)-2,dateadd(month, datediff(month, 0, #RunDate), 0))
end;
rextester demo of both: http://rextester.com/CCUFI85069
Try changing the code to set the dates like this...
SET #StartDate = CONVERT(DATE,
CONCAT(MONTH(DATEADD(d, -1, #Rundate)),
'/21/',
IIF(MONTH(#Rundate) = '1', YEAR(#RunDate), YEAR(DATEADD(yy, -1, #Rundate)))) , 101)
The full code will look like this...
Declare #RunDate date
Declare #StartDate Date
Declare #EndDate Date
Set #RunDate = '3/1/2017'
If (Day(#RunDate) = 1)
Begin
Set #StartDate = CONVERT(DATE, CONCAT(MONTH(DATEADD(d, -1, #Rundate)), '/21/',IIF(MONTH(#Rundate) = '1', YEAR(#RunDate), YEAR(DATEADD(yy, -1, #Rundate)))) , 101)
Set #EndDate = Convert(date,DATEADD(ms,-3,DATEADD(mm,0,DATEADD(mm,DATEDIFF(mm,0,#Rundate),0))),101)
End
Else
IF (Day(#RunDate) = 8)
Begin
Set #StartDate = Convert(Date, CONCAT(Month(#Rundate) , '/1/' , Year(#RunDate)) ,101)
Set #EndDate = Convert(Date, CONCAT(Month(#Rundate) , '/7/' , Year(#RunDate)) ,101)
End
Else
If (Day(#Rundate) = 15)
Begin
Set #StartDate = Convert(Date, CONCAT(Month(#Rundate) , '/8/' , Year(#RunDate)) ,101)
Set #EndDate = Convert(Date, CONCAT(Month(#Rundate) , '/14/' , Year(#RunDate)) ,101)
End
Else
If (Day(#Rundate) = 22)
Begin
Set #StartDate = Convert(Date, CONCAT(Month(#Rundate) , '/15/' , Year(#RunDate)) ,101)
Set #EndDate = Convert(Date, CONCAT(Month(#Rundate) , '/21/' , Year(#RunDate)) ,101)
END
SELECT #StartDate, #EndDate
You could even hide the repetitive code and create a simple function...
CREATE FUNCTION [dbo].[GetDateBasedOnStringNumber] (#num NVARCHAR(20), #RunDate DATE)
RETURNS DATE
WITH SCHEMABINDING AS
BEGIN
DECLARE #retDate DATE
SELECT #retDate = Convert(Date, CONCAT(Month(#RunDate) , #num , Year(#RunDate)) ,101)
RETURN #retDate ;
END;
and then use this pattern instead...
SELECT #StartDate = dbo.GetDateBasedOnStringNumber('/1/', #RunDate)
SELECT #EndDate = dbo.GetDateBasedOnStringNumber('/7/', #RunDate)
The error is because you are trying to add integer and varchar values together. Using this line as an example:
Set #StartDate = Convert(Date,(Month(DATEADD(d,-1,#Rundate)) + '/21/' + Case When Month(#Rundate) = '1' Then Year(#RunDate) Else Year(DATEADD(yy,-1,#Rundate)) End),101)
If you break down the parts of your calculation you have the month integer value, a day varchar value and a year integer value. If you try to concatenate these you get the error message:
Msg 245, Level 16, State 1, Line 9 Conversion failed when converting
the varchar value '/21/' to data type int.
You could cast the integer values to varchar and it would work.
It is recommended to use the built-in date functions than using concatenation so you could achieve the same result like so:
DECLARE
#RunDate DATE = '20170101'
, #StartDate DATE
, #EndDate DATE
IF DATEPART(DAY, #RunDate) = 1
SELECT
#StartDate = DATEADD(DAY, -(DATEPART(DAY, DATEADD(DAY, -1, #RunDate)) - 20), #RunDate)
, #EndDate = DATEADD(DAY, -1, #RunDate)
SELECT
#StartDate
, #EndDate