Вы должны создать table type variable
первый:
CREATE TYPE BusinessDateTableType AS TABLE
(
[WeekDay] VARCHAR(50),
IsBusinessDate BIT
);
Затем создайте функцию, которая принимает табличное значение параметра указанного выше типа:
CREATE FUNCTION UDF_GetNextBusinessDay
(
@businessDates BusinessDateTableType READONLY,
@type VARCHAR(10),
@day DATE
)
RETURNS DATE
AS
BEGIN
-- Declare the return variable here
DECLARE @nextBusinessDate DATE
;WITH cte AS (
SELECT CASE
WHEN @type = 'Next' THEN 1
WHEN @type = 'Previous' THEN -1
END AS i
UNION ALL
SELECT CASE
WHEN @type = 'Next' THEN i + 1
WHEN @type = 'Previous' THEN i -1
END AS i
FROM cte
WHERE ABS(i) < 7
)
SELECT TOP 1 @nextBusinessDate = DATEADD(day, i, @day)
FROM cte AS d1
INNER JOIN @businessDates AS d2 ON DATENAME(DW, DATEADD(day, i, @day)) = d2.WeekDay
WHERE d2.IsBusinessDate = 1
ORDER BY ABS(i)
-- Return the result of the function
RETURN @nextBusinessDate
END
EDIT:
Мы можем легко подставить переменную table-type в UDF с помощью семи переменных типа BIT
, а затем использовать table variable
внутри UDF и заполнить его значениями этих переменных:
CREATE FUNCTION UDF_GetNextBusinessDay2
(
@IsMonWorkingDay BIT,
@IsTueWorkingDay BIT,
@IsWedWorkingDay BIT,
@IsThuWorkingDay BIT,
@IsFriWorkingDay BIT,
@IsSatWorkingDay BIT,
@IsSunWorkingDay BIT,
@type VARCHAR(10),
@day DATE
)
RETURNS DATE
AS
BEGIN
-- Declare the return variable here
DECLARE @nextBusinessDate DATE
DECLARE @businessDates TABLE ([WeekDay] VARCHAR(50), IsBusinessDate BIT)
INSERT INTO @businessDates VALUES
('Monday', @IsMonWorkingDay),
('Tuesday', @IsTueWorkingDay),
('Wednesday', @IsWedWorkingDay),
('Thursday', @IsThuWorkingDay),
('Friday', @IsFriWorkingDay),
('Saturday', @IsSatWorkingDay),
('Sunday', @IsSunWorkingDay)
;WITH cte AS (
SELECT CASE
WHEN @type = 'Next' THEN 1
WHEN @type = 'Previous' THEN -1
END AS i
UNION ALL
SELECT CASE
WHEN @type = 'Next' THEN i + 1
WHEN @type = 'Previous' THEN i -1
END AS i
FROM cte
WHERE ABS(i) < 7
)
SELECT TOP 1 @nextBusinessDate = DATEADD(day, i, @day)
FROM cte AS d1
INNER JOIN @businessDates AS d2 ON DATENAME(DW, DATEADD(day, i, @day)) = d2.WeekDay
WHERE d2.IsBusinessDate = 1
ORDER BY ABS(i)
-- Return the result of the function
RETURN @nextBusinessDate
END
Используя вторую версию UDF с этим данные испытаний:
DECLARE @type VARCHAR(10) = 'Next'
DECLARE @day DATE = '2014-12-22'
DECLARE @nextBusinessDate DATE
SET @nextBusinessDate = dbo.UDF_GetNextBusinessDay2(1,0,0,0,0,0,1, @type, @day)
SELECT @nextBusinessDate
производит следующий результат:
2014-12-28
Не могли бы вы уточнить, чего вы хотите достичь? –
найти следующий или предыдущий бизнес (рабочий день) с учетом базового списка рабочих дней/дней и определенной даты (обычно сегодня) – Bill