0

我在下面的项目中遇到错误,我不明白为什么。任何人都可以为我解释一下吗?

CREATE FUNCTION dbo.fn_AcMonthOrder
(
    @Month varchar(100)
)
RETURNS INT 
AS
BEGIN 
    DECLARE @MonthOrder Int 
    SET @MonthOrder = 
        (CASE 
        WHEN @Month IN ('Aug','August',8) THEN 1 
        WHEN @Month IN ('Sep','September',9) THEN 2 
        WHEN@Month IN ('Oct','October',10) THEN 3 
        ...
        ELSE 0 END)
    RETURN @MonthOrder
END 

如果我尝试调用此函数,那么它对整数有效,但不适用于 varchars。即 PRINT @dbo.fn_AcMonthOrder(8) 将按预期返回 1,但 PRINT @dbo.fn_AcMonthOrder('Aug') 或 PRINT @dbo.fn_AcMonthOrder('August') 返回以下错误:

Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'Aug' to data type int.
4

4 回答 4

2

当您在表达式中使用不同的数据类型时,SQL Server 遵循数据类型优先级。在这种情况下:

8 IN ('Aug','August', 8) 

你正在intvarchar. 由于int具有更高的优先级,它将转换varcharint. 这种特殊情况没有引发错误的原因可能是优化。这确实会引发错误:

8 IN ('Aug','August',10) 

这不会引发错误:

'Aug' IN ('Aug','August',8) 

但这再次引发错误:

'Sept' IN ('Aug','August',8) 

这证实了优化器首先比较了不需要转换的元素。只有当它到达无法转换的元素时才会引发错误。

归根结底,最好的解决方案是确保所有数据类型都相同。在您的情况下,您可以将数字列为字符串:

WHEN @Month IN ('Aug','August','8') THEN 1 
                              ^^^^^
于 2013-05-01T07:46:09.963 回答
1
        WHEN @Month IN ('Aug','August','8') THEN 1 
        WHEN @Month IN ('Sep','September','9') THEN 2 
        WHEN@Month IN ('Oct','October','10') THEN 3 

将数字中的月份值括在单引号中,例如将 8 更改为 '8' 。这是因为 @Month 是 VARCHAR() 数据类型,而 IN() 子句要求其中的值必须在它们之间进行兼容的数据类型转换。

于 2013-05-01T07:39:57.597 回答
1

IN-list 中的所有元素都必须是可以进行隐式转换的类型。您不能将 varchar 值转换为整数,但反之亦然。所以试试这个说法。

CREATE FUNCTION dbo.fn_AcMonthOrder
(
  @Month varchar(100)
)
RETURNS INT AS
BEGIN
  DECLARE @MonthOrder Int
  SET @MonthOrder =
    (CASE
      WHEN @Month IN ('Aug','August','8') THEN 1
      WHEN @Month IN ('Sep','September','9') THEN 2
      WHEN@Month IN ('Oct','October','10') THEN 3
      ELSE 0
    END)
  RETURN @MonthOrder
END
于 2013-05-01T07:40:45.893 回答
1

当您使用 IN 子句时,您应该使用一个 DataType 现在您在 8 附近使用' Aug ',并且它假定它应该将 'aug',... 转换为 int 这是不正确的。你可以这样写(为你所有的情况做这件事)

WHEN @Month IN ('Aug','August','8') THEN 1 
.....
于 2013-05-01T07:41:40.727 回答