[英]USE DATENAME IN SQL SERVER IN STORE PRODECURE
我有这个带有 3 个参数的存储过程 -1:开始日期 -2:结束日期 -3:天数 这个存储过程的 function 是在不计算特定日期的情况下获取两个日期之间的差异
CREATE PROCEDURE TEST (@start_date DATE,@end_date DATE,@name_days VARCHAR(MAX))
AS
BEGIN
DECLARE @NUMBER_DAYS INT;
;with AllDates AS
(
SELECT @start_date AS DateOf
UNION ALL
SELECT DateAdd(day,1,DateOf)
FROM AllDates
WHERE DateOf<@end_date
)
select SUM(CASE WHEN DATENAME(weekday,dateof) in (@name_days) THEN 0 ELSE 1 END) as SumOfDays
FROM AllDates;
END
我的问题是我需要知道我是否可以像示例一样在执行过程中添加两个天的名称(但这对我不起作用有人有任何建议!以及如何做)
EXEC TEST '2020-07-01','2020-07-13','Monday Tuesday'
一种方法是使用表类型参数。 我还从使用 rCTE 的迭代(和缓慢)方法切换到更快的 Tally Table。
但是,理想情况下,如果您想更定期地执行此操作,最好使用日历表(使用您最喜欢的搜索引擎,您会找到 1000 个有关如何构建这些的示例)而不是内联相符。
无论如何,使用表类型参数,您可以执行以下操作:
USE Sandbox;
GO
CREATE TYPE dbo.DayNames AS table(DayName varchar(15));
GO
CREATE PROC dbo.TEST @StartDate date, @EndDate Date, @DayNames dbo.DayNames READONLY AS
BEGIN
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
SELECT TOP (SELECT DATEDIFF(DAY, @StartDate, @EndDate) +1)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
FROM N N1, N N2, N N3, N N4), --10,000 days
Dates AS(
SELECT DATEADD(DAY, T.I, @StartDate) AS Date,
DATENAME(WEEKDAY, DATEADD(DAY, T.I, @StartDate)) AS DayName
FROM Tally T)
SELECT COUNT(*) AS NumOfDays
FROM Dates D
JOIN @DayNames DN ON D.DayName = DN.DayName;
END;
GO
DECLARE @DayNames dbo.DayNames;
INSERT INTO @DayNames
VALUES ('Monday'),('Tuesday');
EXEC dbo.TEST '20000101', '20200817', @DayNames;
GO
--Cleanup
DROP PROC dbo.TEST;
DROP TYPE dbo.DayNames;
如果不想使用表类型参数,可以传入分隔列表,然后使用字符串拆分器,例如STRING_SPLIT
(在 SQL Server 2016+ 中)或用户构建的DelimitedSplit8K_LEAD
(如 Google LEADK_ADK_ADLIT8) )。
我建议使用日历表,但如果您使用的是 SQL 2016+,您可以使用 STRING_SPLIT function 完成此操作:
CREATE PROCEDURE TEST (@start_date DATE,@end_date DATE,@name_days VARCHAR(MAX))
AS
BEGIN
DECLARE @NUMBER_DAYS INT;
;with AllDates AS
(
SELECT @start_date AS DateOf
UNION ALL
SELECT DateAdd(day,1,DateOf)
FROM AllDates
WHERE DateOf<@end_date
)
select COUNT(*) SumOfDays
FROM AllDates
WHERE NOT EXISTS(SELECT 1
FROM STRING_SPLIT(@name_days,' ')
WHERE DATENAME(weekday,dateof) = value)
END
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.