【问题标题】:Substring function not comparing the output子字符串函数不比较输出
【发布时间】:2019-01-24 11:58:21
【问题描述】:
ALTER FUNCTION WEEKDAYS(@DAY VARCHAR)
RETURNS INT
AS BEGIN
    IF(@DAY IS NULL)
    RETURN 0

        DECLARE @OUTPUT INT

        SELECT @OUTPUT=
            CASE WHEN SUBSTRING(@DAY,1,1) = 'M' THEN 1
                 WHEN SUBSTRING(@DAY,1,2) = 'TU' THEN 2
                 WHEN SUBSTRING(@DAY,1,1) = 'W' THEN 3
                 WHEN SUBSTRING(@DAY,1,2) = 'TH' THEN 4
                 WHEN SUBSTRING(@DAY,1,1) = 'F' THEN 5
                 WHEN SUBSTRING(@DAY,1,2) = 'SA' THEN 6
                 WHEN SUBSTRING(@DAY,1,2) = 'SU' THEN 7
            ELSE
                99 END
        RETURN @OUTPUT
    END

我有这个功能。在星期一、星期三和星期五的情况下,该功能正在打印的输出是正确的。但在其他情况下,它会打印 else 条件的输出。

【问题讨论】:

  • 您的 DAY 参数被声明为 varchar - 这意味着 varchar(1)。您的代码假定为 varchar(2)。这里有一个重要的教训。我会更进一步——“工作日”并不总是“工作日”。小心你的假设。
  • 为什么需要在参数上使用子字符串?传递无效值的人应该收到无效的返回值或错误。不要试图隐藏源代码错误。并且不要通过适应他们的懒惰来鼓励懒惰的开发人员。

标签: sql-server


【解决方案1】:

总是声明长度、比例和精度...不声明长度导致意外行为;就像你在这里一样。

ALTER FUNCTION WEEKDAYS(@DAY VARCHAR)

等同于:

ALTER FUNCTION WEEKDAYS(@DAY VARCHAR(1))

@DAY 的长度为 1,它永远不会有值 'TU',因为那是 2 个字符;最大长度的两倍@DAY。为您的 varchar 参数定义适当的长度,问题就会消失。

不过,在完全不同的情况下,您为什么要使用 UDF 来获取工作日编号,为什么不使用 DATEPART(WEEKDAY, {Date})

【讨论】:

    【解决方案2】:

    您也可以使用DATEPART() 函数在不使用函数的情况下获取此信息。但要更正您的功能,您可以尝试以下操作。

    ALTER FUNCTION WEEKDAYS(@DAY VARCHAR(10))
    RETURNS INT
    AS BEGIN
        IF(@DAY IS NULL)
        RETURN 0
    
            DECLARE @OUTPUT INT
    
            SELECT @OUTPUT=
                CASE WHEN SUBSTRING(@DAY,1,1) = 'M' THEN 1
                     WHEN SUBSTRING(@DAY,1,2) = 'TU' THEN 2
                     WHEN SUBSTRING(@DAY,1,1) = 'W' THEN 3
                     WHEN SUBSTRING(@DAY,1,2) = 'TH' THEN 4
                     WHEN SUBSTRING(@DAY,1,1) = 'F' THEN 5
                     WHEN SUBSTRING(@DAY,1,2) = 'SA' THEN 6
                     WHEN SUBSTRING(@DAY,1,2) = 'SU' THEN 7
                ELSE
                    99 END
            RETURN @OUTPUT
        END
    
    SELECT dbo.WEEKDAYS('SUNDAY') as SUNDAY
    SELECT dbo.WEEKDAYS('MONDAY') as MONDAY
    SELECT dbo.WEEKDAYS('TUESDAY') as TUESDAY
    SELECT dbo.WEEKDAYS('WEDNESDAY') as WEDNESDAY
    SELECT dbo.WEEKDAYS('THURSDAY') as THURSDAY
    SELECT dbo.WEEKDAYS('FRIDAY') as FRIDAY
    SELECT dbo.WEEKDAYS('SATURDAY') as SATURDAY
    

    输出如下图

    【讨论】:

    • 星期四天。 ;)
    • @Larnu 根据条件给出 4。
    • 星期四ur一天,而不是“星期四”。
    • @Larnu 纠正了错字。但这不是技术问题,因为这里只有两个字符在检查和比较。
    猜你喜欢
    • 1970-01-01
    • 2017-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    相关资源
    最近更新 更多