【问题标题】:Passing DATEDIFF interval as user defined function argument?将 DATEDIFF 间隔作为用户定义的函数参数传递?
【发布时间】:2019-05-21 08:23:55
【问题描述】:

我想编写一个函数来返回 datediff 忽略 SQL Server 上的周末。 是否允许将间隔作为参数传递给我的用户定义函数,如下所示? SQL Server 说“为 datediff 指定的参数 1 无效。”

CREATE FUNCTION [dbo].[DATEDIFFWD](@interval varchar(2), @ini datetime, @end datetime)
RETURNS int
AS
BEGIN
    DECLARE @output int
    SET @output = DATEDIFF(@interval, @ini, @end)
    IF (@interval = 'hh') SET @output = @output - (DATEDIFF(WK, @ini, @end) * 48)
    IF (@interval = 'dd') SET @output = @output - (DATEDIFF(WK, @ini, @end) * 2)
    RETURN @output
END

【问题讨论】:

  • 你不能。但是由于您使用的是if @interval = 'hh'...,您不妨添加if @interval = 'hh' @output = datediff(hour, ); @output = @output - ...
  • 旁白:DateDiff 返回以指定单位跨越的 边界 的数量,例如2018-01-01T00:30:002018-01-01T23:30:00 之间的天数是 02018-01-01T23:30:002018-01-02T00:30:00 之间的天数是 1。始终使用跨越的week 边界的数量并乘以一个因子以得到更小的单位,例如hour,不寻常。走另一条路,例如以分钟为单位除以1200 得到天数的差异消除了DateDiff 对于day 的边界交叉方面。

标签: sql-server tsql user-defined-functions


【解决方案1】:

你可以改写成:

CREATE FUNCTION [dbo].[DATEDIFFWD](@interval varchar(2),
                                   @ini datetime, @end datetime)
RETURNS int
AS
BEGIN
    RETURN (SELECT CASE @interval 
      WHEN 'hh' THEN DATEDIFF(hh, @ini, @end) - ((DATEDIFF(WK, @ini, @end) * 48))
      WHEN 'dd' THEN DATEDIFF(dd, @ini, @end) - ((DATEDIFF(WK, @ini, @end) * 2))
    END
    );
END

请注意scalar function could be inlined starting from SQL Server 2019

db<>fiddle demo

为了获得更好的性能,我会改用表函数:

CREATE FUNCTION [dbo].[DATEDIFFWD](@interval varchar(2),
                                   @ini datetime, @end datetime)
RETURNS TABLE
AS
RETURN (
    SELECT CASE @interval 
     WHEN 'hh' THEN DATEDIFF(hh, @ini, @end) - ((DATEDIFF(WK, @ini, @end) * 48))
     WHEN 'dd' THEN DATEDIFF(dd, @ini, @end) - ((DATEDIFF(WK, @ini, @end) * 2))
    END AS r
);

【讨论】:

    【解决方案2】:

    DATEDIFF will not accept user-defined DATEPART 的变量等效项。您必须在动态 SQL 中将其连接起来,或者使用其他一些逻辑将该变量分隔到 DATEDIFF 之外。另外,我不会在@interval 上使用varchar(2),主要是因为it's a bad habit one should kick.

    【讨论】:

    • 我会接受它,因为它不经常发生@SeanLange哈哈
    • 你不能在函数内部使用动态SQL
    • @LukaszSzozda 但您可以使用动态 sql 构建字符串并将结果执行到输出参数。
    • 哪个函数有什么意义? UDF 还是 datediff?我不明白你的评论。我一开始不会亲自写这个 UDF。
    • 现在我明白你在做什么,这是一个公平的观点,如果你排除解决方法。
    猜你喜欢
    • 1970-01-01
    • 2019-04-25
    • 1970-01-01
    • 1970-01-01
    • 2014-08-18
    • 2021-04-13
    • 2023-04-02
    相关资源
    最近更新 更多