Executing Stored Procedure With Dynamic Date Parameter - Conversion Error - tsql

I'm trying to execute the following stored procedure with a dynamic date parameter so that it picks up 6 months ago to yesterday.
When I run on a server with US language settings it works however when I run on a server with UK language settings I get the error:
Conversion failed when converting date and/or time from character string
I have tried converting the date to YYYYMMDD as this works on all servers however I have been unable to - I have even tried to force into a VARCHAR but no luck :(
Is there a way to get the date as YYYYMMDD format? Hope you can help.
USE Reports
DECLARE #DteStart DATETIME2(3)
DECLARE #DteEnd DATETIME2(3)
SELECT #DteStart = DATEADD(MM, DATEDIFF(MM, 0, CONVERT(DATE,GETDATE(),103))-6,0)
SELECT #DteEnd = DATEADD(DD, DATEDIFF(DD, 0, CONVERT(DATE,GETDATE(),103))-1,0)
EXEC [dbo].[spReportsMyData] #DteStart, #DteEnd;

Try something like this:
Declare
#StartDate as Date
, #EndDate as Date
Set #EndDate = DateAdd(Day, -1, Getdate())
Set #StartDate = DateAdd(Month, -6, #EndDate)
Select
Convert(VARCHAR(10), #StartDate, 112) As StartDate
, CONVERT(VARCHAR(10), #EndDate, 112) As EndDate
Does your stored procedure seriously need the dates specifically in YYYYMMDD format, though?

Related

Convert Excel formula (using Date and subtraction) into T-SQL

I am trying to write this Excel formula into T-SQL (to write a function).
Expected output is 0.71944444, but currently my output (using T-SQL) is 24.0000.
I am not sure why we have to add a day to same date and subtract the same date.
Bottom is a screenshot from Excel:
This is what I have so far in T-SQL:
CREATE FUNCTION [dbo].[fn_0921] (
#Punch_Start nvarchar(max)
)
RETURNS decimal(36, 8) AS
BEGIN
DECLARE #return_value nvarchar(max);
SET #return_value =
DATEDIFF(
MINUTE, CAST(#Punch_Start AS datetime2),
(
dateadd(
day, 1, CAST(#Punch_Start AS datetime2)
)
)
)
/ (60.0)
RETURN #return_value
END;
Thanks for help.
The Excel formula is returning the difference between the datetime in cell K4 & the start of the next day (i.e. 7/26/2021 00:00) as a fraction of a whole day. The following is the equivalent in T-SQL:
DECLARE #Punch_Start datetime2 = '7/25/2021 06:44';
SELECT DATEDIFF(
MINUTE,
#Punch_Start,
CAST(
CAST(
DATEADD(DAY, 1, #Punch_Start)
AS date) -- Add 1 day to #Punch_Start & cast as date to remove the time component - this is the start of the next day
AS datetime2) -- Cast back to datetime2 to get the difference in minutes
) / 1440.; -- Divide the difference in minutes by the number of minutes in a day (60 minutes per hour, 24 hours per day) to get the difference as a fraction of a day
This can probably help you:
DECLARE #date DATETIME2 = '2021-07-25 06:44'
DECLARE #seconds INT = DATEDIFF(second, CAST(#date AS date), #date)
DECLARE #secondsFromEnd FLOAT = 86400 - #seconds
SELECT #secondsFromEnd / 86400

Get a list of mondays between date range

I need to show N records with each record being 1 weeks worth of summarized data. One of the inputs will be a date range.
Since each week should start with monday, I want to get a list of all the monday dates in the date range. Any suggestions to get that?
Note: This has to run on SQL 2005
declare #dt datetime
SET #dt = '2010-01-01'
declare #dtEnd datetime
SET #dtEnd = '2010-12-04'
DECLARE #day AS NVARCHAR(30)
WHILE (#dt < #dtEnd) BEGIN
-- insert into table(datefield)
-- values(#dt)
SET #day = UPPER(DATENAME(weekday,#dt))
IF #day = 'MONDAY'
--PRINT 'date is: ' + CAST(#dt AS VARCHAR(30))
BEGIN
PRINT 'date is: ' + CAST(#dt AS VARCHAR(30)) + ' ' + #day
END
SET #dt = DATEADD(day, 1, #dt)
END
The code you show seems to work, but it can be made more efficient. The code I show below will calculate the first Monday on or after the start date. Then it is used in the same loop but we simply add 7 days each time through the loop.
declare #dt datetime,
#dtEnd datetime
SET #dt = '2010-01-01'
SET #dtEnd = '2010-12-04'
Set #dt = DateAdd(Day, 7 - DateDiff(Day, 0, #dt) % 7, #dt)
WHILE (#dt < #dtEnd) BEGIN
PRINT 'date is: ' + CAST(#dt AS VARCHAR(30)) + ' ' + DateName(Weekday, #dt)
SET #dt = DATEADD(day, 7, #dt)
END
One thing I notice about your code is that you are using DateName, which works ok for displaying the weekday name, but not so good for making decisions (like you are doing). The problem with DateName is that it uses the language setting of the currently logged in user.
The following code shows this behavior.
set language 'spanish'
Select DateName(Weekday, GetDate())
set language 'us_english'
Select DateName(Weekday, GetDate())
Basically, if the language of a user was set to spanish, your code would fail but mine would not. Mine works because it uses the fact that January 1, 1900 was a Monday. It calculates the number of days and takes a mod of that and uses that mod to add the correct number of days. Since January 1, 1900 will always be a Monday, and we are not using the DateName function, this code will work without regard to the language setting.
SELECT * from table t
WHERE t.date between 'startDate' and 'endDate'
AND (SELECT DATEPART(dw,t.StudyDate))=2

Take the time from the datetime and convert it into seconds?

I am running SQL Server 2005. Technically I know how to take the time from a tsql datetime.
CONVERT(VARCHAR(8),GETDATE(),108) AS HourMinuteSecond
The problem is that I have a datetime field and I need to essentially grab the time portion convert that to an integer specifically seconds. Then I need to do a bunch of arithmetic on this integer that I won't discuss here. I have searched on stackoverflow and haven't found a question that is specific to this question. Any ideas? I am really looking for best practices here, I am worried about creating a udf for this specific purpose as it completely throws the query optimizer out the window.
I have seen this webpage so please don't paste this. :
http://forums.devx.com/showthread.php?171561-TSQL-Converting-HH-MM-SS-to-seconds
Use DATEPART:
(DATEPART(HOUR, GETDATE()) * 3600) +
(DATEPART(MINUTE, GETDATE()) * 60) +
(DATEPART(SECOND, GETDATE()))
Just my 2 cents ...another way of doing this
Edit: Added method for SQL Server 2005 (Thank you Michael)
for SQL Server 2008
SELECT DATEDIFF(SECOND, CONVERT(date, GETDATE()), GETDATE())
for sql server 2005+
SELECT DATEDIFF(SECOND, DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())), GETDATE())
The functions you want is DatePart
Declare #d DateTime
Select #d = GetDate()
Select (DatePart(HOUR, #d) * 3600) + (DatePart(MINUTE, #d) * 60) + DatePart(SECOND, #d)

T-SQL - receive date value and adjust day / month retaining year

I am trying to perform a little date manipulation on a value I will be passing in to a stored procedure.
Example Inputs;
31/12/2008
15/11/2007
21/05/2005
Expected Output;
31/12/2012
15/11/2012
21/05/2012
Formatted code from the answer provided;
DECLARE #date DATETIME = '31/12/2007'
DECLARE #year INT
SET #year = DATEPART(YEAR, GETDATE())
SELECT DATEADD(YEAR, #year - DATEPART(YEAR, #date), #date)
You are trying to convert the year component to 2012?
-- get the year part
DATEPART(YEAR, [Date])
-- get the number of years to add
2012 - DATEPART(YEAR, [Date])
-- add that many years to the date
DATEADD(YEAR, 2012 - DATEPART(YEAR, [Date]), [Date])

TSQL need to return last day of month only, how do I drop year, month & time?

I am writing a function in T-SQL returning the last day of the month regardless of the date input.
Here is my code:
Alter Function dbo.FN_Get_Last_Day_in_Month2
(#FN_InputDt Datetime)
Returns smalldatetime
as
Begin
Declare #Result smalldatetime
Set #Result =
case when #FN_InputDt <> 01-01-1900 then
DATEADD(m, DATEDIFF(M, 0,#FN_InputDt)+1, -1)
Else 0 End
Return #Result
End
The code is not working correctly, here is a test that shows the bad behavior:
SELECT dbo.fn_get_last_day_in_month (07-05-2010)
Here is the (incorrect) result:
2010-07-31 00:00:00
What is 07-05-2010...May 7th or July 5th? You need to use a safe date format, take a look at Setting a standard DateFormat for SQL Server
example from How to find the first and last days in years, months etc
DECLARE #d DATETIME
SET #d = '20100705' -- notice ISO format
SELECT
DATEADD(yy, DATEDIFF(yy, 0, #d), 0) AS FirstDayOfYear,
DATEADD(yy, DATEDIFF(yy, 0, #d)+1, -1) AS LastDayOfYear,
DATEADD(qq, DATEDIFF(qq, 0, #d), 0) AS FirstDayOfQuarter,
DATEADD(qq, DATEDIFF(qq, 0, #d)+1, -1) AS LastDayOfQuarter,
DATEADD(mm, DATEDIFF(mm, 0, #d), 0) AS FirstDayOfMonth,
DATEADD(mm, DATEDIFF(mm, 0, #d)+1, -1) AS LastDayOfMonth,
#d - DATEDIFF(dd, ##DATEFIRST - 1, #d) % 7 AS FirstDayOfWeek,
#d - DATEDIFF(dd, ##DATEFIRST - 1, #d) % 7 + 6 AS LastDayOfWeek
for just the day use day or datepart
select DAY(getdate()),
DATEPART(dd,GETDATE())
Cast the return value to a SQL datetime type, and then call the "DAY" function to get the day in as an integer. See the function reference here:
http://msdn.microsoft.com/en-us/library/ms176052.aspx
Not sure which database you're using, but this should be a standard function across all databases.
I'd return a DATETIME, I've had trouble with SMALLDATETIME in the past.
DECLARE #Result DATETIME
SET #Result = DATEADD(m , 1, #FN_Input);
RETURN CAST(FLOOR(CAST(DATEADD(d, DATEPART(d, #Result) * -1, #Result) AS FLOAT)) AS DATETIME)
Also, I think you may be a victim of SQL's complete disregard of date formatting. Always, always, always, when typing a string into test a SQL function use the following format;
'05 Jul 2010'
Your function probably works but it interpreted your date as 5th July - not 7th May.
DECLARE #date DATETIME = '20130624';
SELECT Day(EOMONTH ( #date )) AS LastDay;
GO