【问题标题】:SQL Scalar UDF to get number of days in YearSQL Scalar UDF 获取年份中的天数
【发布时间】:2026-01-26 12:30:01
【问题描述】:

我编写代码来确定一年中有多少天。我试图让它变得非常简单。 我发现我认为确定闰年的代码非常干净。我正在使用 DATEPART(Y,@Year) 将输入的日期传递给闰年程序,并且有些方法没有得到正确的结果,所以我必须在我的 SQL 代码中处理输入日期,因为返回了正确的位。

这是闰年的代码:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

ALTER FUNCTION [dbo].[FN_Is_Leap_Year]
(
 -- the parameters for the function here

        @year int
)

RETURNS BIT
AS
BEGIN
RETURN (select case datepart(mm, dateadd(dd, 1, cast((cast(@year as varchar(4)) + '0228') as datetime)))
WHEN 2 THEN 1
ELSE 0  END)

END

这是我为处理输入日期并获取一年中的 # 天而编写的代码:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

ALTER FUNCTION [dbo].[FN_Get_Days_In_Year]
(
    @InputDT    varchar(10)
)

RETURNS int
AS
BEGIN

DECLARE  @Result  int,
         @Year    int   


Set @Result = 
 CASE
    WHEN dbo.FN_Is_Leap_Year(Datepart(yyyy,@Year)) = 0 Then 365
    WHEN dbo.FN_Is_Leap_Year(Datepart(yyyy,@Year)) = 1 Then 366
 END


        RETURN @Result
    END

【问题讨论】:

  • 在最后一段代码中,为什么在CASE语句中调用函数(dbo.FN_Is_Leap_Year) 2次?你应该使用CASE dbo.FN_Is_Leap_Year(Datepart(yyyy,@Year)) WHEN 0 THEN 365 ELSE 366 END。哎呀,我会转储第一个函数并将其一行代码拉入CASE
  • SELECT 1 + DATEDIFF(day, CAST(@year AS VARCHAR(4)) + '-01-01', CAST(@year AS VARCHAR(4)) + '-12-31'); ?

标签: tsql variables user-defined-functions


【解决方案1】:

搞定了!!

GO
ALTER FUNCTION [dbo].[FN_Get_Days_In_Year]
(
    @InputDT     int
)

RETURNS varchar(3)
AS
BEGIN

Declare     @Year    int,   
            @RetVal  bit,
            @Result varchar(3)

    Set @Year   = datepart(yy, @InputDT)
    Set @RetVal = dbo.FN_Is_Leap_Year(Datepart(yy,'2012'))  
    Set @Result = CASE @RetVal
                      WHEN 1 THEN 366
                      ELSE 365 
                  End    
    Return @Result
END     

【讨论】:

  • 好。我不明白你的类型发生了什么。它应该返回一个 int 而不是 varchar(3) 并接受一个日期数据类型。另外,除非您在很多地方都使用它,否则我可能会为此放弃 UDF 并使用类似CASE WHEN Col1 % 4 > 0 THEN 365 WHEN Col1 % 400 = 0 THEN 366 WHEN Col1 % 100 = 0 THEN 365 ELSE 366 END
  • 不,我错了,我验证该位通过正常,但代码仍未正确返回,感谢任何帮助。 GO ALTER FUNCTION [dbo].[FN_Get_Days_In_Year] (@InputDT int) 返回 varchar(3) AS BEGIN 声明 @Year int, @RetVal bit, @Result varchar(3) Set @Year = datepart(yy, @InputDT) Set @ RetVal = dbo.FN_Is_Leap_Year(Datepart(yy,@Year)) 设置@Result = Case When @RetVal = 1 then 365 Else 366 end Return @Result END
  • Martin,很抱歉我没有完全按照您的案例陈述,您能详细说明一下吗?
  • 马丁,我已经通过你的代码:CASE WHEN Col1 % 4 > 0 THEN 365 WHEN Col1 % 400 = 0 THEN 366 WHEN Col1 % 100 = 0 THEN 365 ELSE 366 END 让它工作!
【解决方案2】:

上述答案的修改版:

DECLARE @year INT,
        @DaysInYear INT
SET @year = 2011

SELECT @DaysInYear = CASE DATEPART(mm, DATEADD(dd, 1, CAST((CAST(@year AS VARCHAR(4)) + '0228') AS DATETIME))) 
            WHEN 2 THEN 366 ELSE 365  END 

SELECT @DaysInYear 'DaysInYear'

【讨论】: