为什么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
答案 0 :(得分: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)从性能的角度来看,标量函数可能是一场噩梦。我会重写这些函数为inline table valued functions。