1

为什么 SQL Server 认为这个函数是不确定的?

CREATE FUNCTION [Util].[BuildStreetFullName]
(
    @StreetNumber VARCHAR(20),
    @StreetDir VARCHAR(2),
    @StreetName VARCHAR(50) ,
    @StreetType VARCHAR(4) ,
    @StreetPostDir VARCHAR(2) 
)
RETURNS VarChar(100)
AS
BEGIN
    SET @StreetNumber   = NULLIF( Util.Trim(@StreetNumber   ), '');
    SET @StreetDir      = NULLIF( Util.Trim(@StreetDir      ), '');
    SET @StreetName     = NULLIF( Util.Trim(@StreetName     ), '');
    SET @StreetType     = NULLIF( Util.Trim(@StreetType     ), '');
    SET @StreetPostDir  = NULLIF( Util.Trim(@StreetPostDir  ), '');

    DECLARE @Result VarChar(100) =  @StreetNumber;

    IF @StreetDir IS NOT NULL BEGIN
        IF @Result IS NOT NULL
            SET @Result = @Result + ' ' + @StreetDir;
        ELSE
            SET @Result = @StreetDir;
    END

    IF @StreetName IS NOT NULL BEGIN
        IF @Result IS NOT NULL
            SET @Result = @Result + ' ' + @StreetName;
        ELSE
            SET @Result = @StreetName;
    END


    IF @StreetType IS NOT NULL BEGIN
        IF @Result IS NOT NULL
            SET @Result = @Result + ' ' + @StreetType;
        ELSE
            SET @Result = @StreetType;
    END

    IF @StreetPostDir IS NOT NULL BEGIN
        IF @Result IS NOT NULL
            SET @Result = @Result + ' ' + @StreetPostDir;
        ELSE
            SET @Result = @StreetPostDir;
    END

    RETURN NULLIF(@Result, '');
END

CREATE FUNCTION [Util].[Trim]
(
    @value nVarChar(max)
)
RETURNS nVarChar(max)
AS
BEGIN
    RETURN LTrim(RTrim(@value))
END
4

1 回答 1

3

1)您可以创建两个功能WITH SCHEMABINDING

ALTER FUNCTION dbo.[Trim]
(
    @value nVarChar(max)
)
RETURNS nVarChar(max)
WITH SCHEMABINDING
AS
...

ALTER FUNCTION dbo.[BuildStreetFullName]
(
    @StreetNumber VARCHAR(20),
    @StreetDir VARCHAR(2),
    @StreetName VARCHAR(50) ,
    @StreetType VARCHAR(4) ,
    @StreetPostDir VARCHAR(2) 
)
RETURNS VarChar(100)
WITH SCHEMABINDING
AS
...

这将强制 SQL Server 检查这些函数是否是确定性的。

SELECT  OBJECTPROPERTY( OBJECT_ID(N'dbo.[BuildStreetFullName]') , 'IsDeterministic' ) AS IsDeterministic

输出:

IsDeterministic
---------------
1

2)请不要使用!= NULL 运算符来检查NOT NULL。使用IS NOT NULL. 目前ANSI_NULLS OFF已弃用,未来版本的 SQL Server 将仅允许ANSI_NULLS ON.

3) 从性能的角度来看,标量函数可能是一场噩梦。我会将这些函数重写为内联表值函数

于 2014-06-16T19:14:22.000 回答