为什么SQL2005说这个UDF是不确定的?

为什么SQL2005说这个UDF是不确定的?,sql,user-defined-functions,deterministic,non-deterministic,Sql,User Defined Functions,Deterministic,Non Deterministic,我有以下功能: SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER FUNCTION [dbo].[IP4toBIGINT]( @ip4 varchar(15) ) RETURNS bigint WITH SCHEMABINDING AS BEGIN -- oc3 oc2 oc1 oc0 -- 255.255.255.255 -- Declared as BIGINTs to avoid over

我有以下功能:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO    
ALTER FUNCTION [dbo].[IP4toBIGINT](
    @ip4 varchar(15)
) 
RETURNS bigint
WITH SCHEMABINDING
AS
BEGIN
    -- oc3 oc2 oc1 oc0
    -- 255.255.255.255
    -- Declared as BIGINTs to avoid overflows when multiplying later on     DECLARE @oct0 bigint, @oct1 bigint, @oct2 bigint, @oct3 bigint;
    DECLARE @Result bigint;

    SET @oct3 = CAST(PARSENAME(@ip4, 4) as tinyint);
    SET @oct2 = CAST(PARSENAME(@ip4, 3) as tinyint);
    SET @oct1 = CAST(PARSENAME(@ip4, 2) as tinyint);
    SET @oct0 = CAST(PARSENAME(@ip4, 1) as tinyint);

    -- Combine all values, multiply by 2^8, 2^16, 2^24 to bitshift.
    SET @Result = @oct3 * 16777216 + @oct2 * 65536 + @oct1 * 256 + @oct0;
    RETURN @Result;

END
但是

SELECT 
     OBJECTPROPERTYEX(OBJECT_ID('dbo.IP4toBIGINT'), 'IsDeterministic') as IsDeterministic 
    ,OBJECTPROPERTYEX(OBJECT_ID('dbo.IP4toBIGINT'), 'IsPrecise') as IsPrecise 
    ,OBJECTPROPERTYEX(OBJECT_ID('dbo.IP4toBIGINT'), 'IsSystemVerified') as IsSystemVerified 
    ,OBJECTPROPERTYEX(OBJECT_ID('dbo.IP4toBIGINT'), 'SystemDataAccess') as SystemDataAccess 
    ,OBJECTPROPERTYEX(OBJECT_ID('dbo.IP4toBIGINT'), 'UserDataAccess') as UserDataAccess 
返回(结果转置):

不确定0

i精度1

ISSystem1

SystemDataAccess 0

UserDataAccess 0

我多次尝试删除并重新创建该函数,以确保它不会出现缓存问题。这里的CAST应该是确定性的,因为我将它用于字符串->整数


我完全被难住了,有什么想法吗?

总而言之,PARSENAME是不确定的。是的,您正在确定性上下文中使用它,但我猜服务器不知道这一点。尝试替换PARSENAME并查看它是否更改。

是PARSENAME导致了问题。用硬编码字符串替换它会导致确定性。不知道为什么。。。parse name据说只是一个奇特的拆分函数

看看这个:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO    
ALTER FUNCTION [dbo].[IP4toBIGINT](
    @ip4 varchar(15)
) 
RETURNS bigint
WITH SCHEMABINDING
AS
BEGIN
    -- oc3 oc2 oc1 oc0
    -- 255.255.255.255
    -- Declared as BIGINTs to avoid overflows when multiplying later on         
    DECLARE @oct0 bigint, @oct1 bigint, @oct2 bigint, @oct3 bigint;
    DECLARE @Result bigint;

    SET @oct3 = CAST('1' as tinyint);
    SET @oct2 = CAST('2' as tinyint);
    SET @oct1 = CAST('3' as tinyint);
    SET @oct0 = CAST('4' as tinyint);

    -- Combine all values, multiply by 2^8, 2^16, 2^24 to bitshift.
    SET @Result = @oct3 * 16777216 + @oct2 * 65536 + @oct1 * 256 + @oct0

    RETURN @Result
END
GO

SELECT 
     OBJECTPROPERTYEX(OBJECT_ID('dbo.IP4toBIGINT'), 'IsDeterministic') as IsDeterministic 
    ,OBJECTPROPERTYEX(OBJECT_ID('dbo.IP4toBIGINT'), 'IsPrecise') as IsPrecise 
    ,OBJECTPROPERTYEX(OBJECT_ID('dbo.IP4toBIGINT'), 'IsSystemVerified') as IsSystemVerified 
    ,OBJECTPROPERTYEX(OBJECT_ID('dbo.IP4toBIGINT'), 'SystemDataAccess') as SystemDataAccess 
    ,OBJECTPROPERTYEX(OBJECT_ID('dbo.IP4toBIGINT'), 'UserDataAccess') as UserDataAccess
结果:

IsDeterministic IsPrecise IsSystemVerified  SystemDataAccess UserDataAccess
1               1         1                 0                0

嗯,是的,所以问题是PARSENAME的使用。它是确定性的。也许这是因为SQL假定您将读取DB模式?这可能意味着非决定论,但我只是猜测。

MSDN声明PARSENAME始终是决定论的。我没有尝试,但相信MSDN。否决票已取消且+1.:-)你说得对,是PARSENAME,我被MSDN甩了,MSDN明确地说: