I want to get the first business day of a given month. I generate a holiday table and use it in combination with regular weekday check, to find the first business day of a month.
It seems to work. However, when I use the first month as input e.g.(2020, 1) the function times out. This is for every year like this, every other month works.
CREATE FUNCTION FirstBusinessDay(@year INT, @month INT) RETURNS DATETIME
AS BEGIN
DECLARE @calendar TABLE (Name varchar(80), Date DATETIME)
INSERT INTO @calendar SELECT * FROM dbo.HolidayTable(@year)
DECLARE @d DATETIME = DATEFROMPARTS(@year, @month, 1)
DECLARE @isHoliday bit
SELECT @isHoliday = CASE WHEN Name IS NULL THEN 0 ELSE 1 END
FROM @calendar WHERE Date = @d
WHILE DATEPART(DW, @d+@@DATEFIRST-1) > 5 or @isHoliday = 'true'
BEGIN
SET @d = DATEADD(DAY, 1, @d)
SELECT @isHoliday = CASE WHEN Name IS NULL THEN 0 ELSE 1 END
FROM @calendar WHERE Date = @d
END
RETURN @d
END;
GO
Example usage
select dbo.FirstBusinessDay(2020, 1) as 'First Workday'; -- timeout
select dbo.FirstBusinessDay(2020, 2) as 'First Workday'; -- works
select dbo.FirstBusinessDay(2020, 3) as 'First Workday'; -- works
select dbo.FirstBusinessDay(2021, 7) as 'First Workday'; -- works
select dbo.FirstBusinessDay(2020, 12) as 'First Workday'; -- works
select dbo.FirstBusinessDay(2021, 1) as 'First Workday'; -- timeout
select dbo.FirstBusinessDay(2022, 1) as 'First Workday'; -- timeout
As you can see, there is a pattern, every time the first month is used, it times out. Can anyone spot the issue?
WHILEloop is a really bad idea in the first place, as is a multi-line scalar value function. You should really be using an inline table-value function with a set based solution here. Posting the DDL of your calendar table, which according to your above function is above TVF (I hope it isn't multi-line TVF...) so that we can show you a far better approach.sp_send_dbmail). What you have here is a performance nightmare (sorry, that's probably the lightest way I can put it), with Whiles, and both multi-line table-value and scalar-value functions. Honestly, everything above needs changing. You're thinking like you're writing a Programming language; you're not. SQL is exactly what is says it is, a Structured Query Language. Don't treat it like a PL.