Почему SQL 2005 говорит, что эта определяемая пользователем функция недетерминирована?

У меня есть следующая функция:

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

Точность 1

IsSystemVerified 1

Доступ к системным данным 0

Доступ к данным пользователя 0

Я несколько раз пытался удалить и воссоздать функцию, чтобы убедиться, что это не проблема с кэшированием. CAST здесь должен быть детерминированным, поскольку я использую его для строк-> целых чисел.

Я совсем запутался, есть идеи?


person Serguei    schedule 20.02.2009    source источник


Ответы (3)


PARSENAME в целом недетерминирован. Да, вы используете его в детерминированном контексте, но я предполагаю, что сервер этого не знает. Попробуйте заменить PARSENAME и посмотрите, изменится ли оно.

person Craig Stuntz    schedule 20.02.2009
comment
MSDN утверждает, что PARSENAME всегда является детерминированным - person MicSim; 20.02.2009
comment
Не пробовал, но поверил MSDN. Понижение ушло и +1. :-) - person MicSim; 20.02.2009
comment
Да, вы правы, это PARSENAME, меня скинул MSDN, в котором прямо сказано, что это: msdn.microsoft.com/en-us/library/ms178091(SQL.90).aspx - person Serguei; 21.02.2009

Это PARSENAME вызывает проблемы. Замена его жестко заданной строкой приводит к детерминизму. Понятия не имею, почему... имя синтаксического анализа якобы просто причудливая функция разделения.

Проверь это:

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
person user53794    schedule 20.02.2009

Хм, да, проблема действительно в использовании PARSENAME. MSDN явно говорит, что это детерминировано. Возможно, это связано с тем, что SQL предполагает, что вы будете читать схему БД? Что предполагает недетерминизм, но я просто размышляю.

person Serguei    schedule 20.02.2009