检查变量是否包含空值时,UDF显示奇怪的行为

时间:2018-05-01 12:13:53

标签: sql sql-server sql-server-2012

我正在尝试编写一个由检查约束使用的UDF,但似乎仍然遇到问题。

当拥有完整的空表时,以下结果为1

declare @a float = (SELECT max(amount) FROM Bid WHERE auctionId = 1)
if(@a is null) select 1
else select 0

但是当我尝试在UDF中实现类似的逻辑时,每次在空表上运行它时,它似乎返回0。

CREATE FUNCTION dbo.fn_ck_newBidIsHigher(@auction int, @bid numeric(8,2))
RETURNS bit
BEGIN
    DECLARE @currentHighestBid float = (SELECT max(amount) FROM Bid WHERE auctionId = @auction)

    IF((@bid > @currentHighestBid) OR (@currentHighestBid is null))
    BEGIN
        RETURN 1
    END

    RETURN 0
END
GO

现在已经看了一个多小时(也许这就是问题),但我无法弄清楚它出了什么问题。

我在check约束中调用函数,如下所示:

ALTER TABLE Bid ADD CONSTRAINT ck_New_Bid_Must_Be_Higher_Than_Previous_Bid CHECK(dbo.fn_ck_newBidIsHigher(auctionId, amount) = 1)

1 个答案:

答案 0 :(得分:0)

使用CASE而不是使用IF?使用CASE时,您可以获得2个以上的可能结果。 F.E. 1或0或NULL,而不是仅1或0。

此外,比较相同类型的值更安全 只是为了避免在比较之前来自隐式强制转换/转换的任何意外副作用。

CREATE FUNCTION dbo.fn_ck_newBidIsHigher(@auction int, @bid numeric(8,2))
RETURNS bit
BEGIN

    DECLARE @currentHighestBid numeric(8,2) = (SELECT max(amount) FROM Bid WHERE auctionId = @auction);

    DECLARE @result bit = (
      case 
      when @bid > @currentHighestBid then 1 
      when @bid <= @currentHighestBid then 0 
      end);

RETURN @result;
END