繁体   English   中英

在商店生产中使用 SQL 服务器中的日期名称

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM