Подтвердить что ты не робот

Определяемая пользователем функция Sql Server

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

create function [dbo].[FullNameLastFirst]
(
    @IsPerson bit,
    @LastName nvarchar(100),
    @FirstName nvarchar(100)
)
returns nvarchar(201)
as
begin
    declare @Result nvarchar(201)
    set @Result = (case when @IsPerson = 0 then @LastName else case when @FirstName = '' then @LastName else (@LastName + ' ' + @FirstName) end end)
    return @Result
end

Я не могу создать индекс в вычисленном столбце, используя эту функцию, потому что он не детерминирован. Кто-то может объяснить, почему он не детерминирован и в конце концов, как изменить, чтобы сделать его детерминированным? Благодаря

4b9b3361

Ответ 1

Вам просто нужно создать его with schemabinding.

Затем SQL Server проверяет, соответствует ли он критериям, которые считаются детерминированными (что он делает, поскольку он не имеет доступа к каким-либо внешним таблицам или использует не детерминированные функции, такие как getdate()).

Вы можете проверить, что он работал с

SELECT OBJECTPROPERTY(OBJECT_ID('[dbo].[FullNameLastFirst]'), 'IsDeterministic')

Добавление опции schemabinding в исходный код работает отлично, но будет немного более простая версия.

CREATE FUNCTION [dbo].[FullNameLastFirst] (@IsPerson  BIT,
                                           @LastName  NVARCHAR(100),
                                           @FirstName NVARCHAR(100))
RETURNS NVARCHAR(201)
WITH SCHEMABINDING
AS
  BEGIN
      RETURN CASE
               WHEN @IsPerson = 0
                     OR @FirstName = '' THEN @LastName
               ELSE @LastName + ' ' + @FirstName
             END
  END

Ответ 2

Вам нужно объявить пользовательскую функцию с помощью SchemaBinding

create function [dbo].[FullNameLastFirst] 
( 
    @IsPerson bit, 
    @LastName nvarchar(100), 
    @FirstName nvarchar(100) 
) 
returns nvarchar(201) 
with schemabinding
as 
begin 
    declare @Result nvarchar(201) 
    set @Result = (case when @IsPerson = 0 then @LastName else case when @FirstName = '' then @LastName else (@LastName + ' ' + @FirstName) end end) 
    return @Result 
end 


create table Person
(
isperson bit,
lastname nvarchar(100),
firstname nvarchar(100),
fullname as [dbo].[FullNameLastFirst] (isperson, lastname, firstname)
)
go
insert into person(isperson, lastname, firstname) values (1,'Firstname', 'Surname')
go

create index ix1_person on person(fullname)
go

select fullname from Person with (index=ix1_person) where fullname = 'Firstname Surname'
go