Как сделать детерминированную детерминированную функцию детерминированной? [Дубликат]

27
задан opaera 6 September 2010 в 14:04
поделиться

2 ответа

Вам просто нужно создать его 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
43
ответ дан Martin Smith 22 August 2018 в 16:14
поделиться
  • 1
    Я создал свой указатель, указав на вычисленный столбец. У меня также есть вид, который относится к моей таблице. Я думаю, что я должен указать SchemaBinding в представлении, чтобы создать индекс в том же столбце. Об этом, если моя базовая таблица как индекс в вычисленном столбце, избыточно, создает другой индекс в представлении? – opaera 6 September 2010 в 14:57
  • 2
    @opaera - Да - вам не нужно будет индексировать этот столбец в представлении. – Martin Smith 6 September 2010 в 15:07
  • 3
  • 4
    @opaera - Нет, он должен использовать значения сохраняемых столбцов автоматически, если включены ARITHABORT или ANSI_WARNINGS. Вы можете проверить план выполнения, чтобы определить это. – Martin Smith 6 September 2010 в 15:19
  • 5
    отметьте этот ответ как правильный ответ – swe 5 April 2016 в 08:27

Вам нужно объявить функцию, определенную пользователем WITH SCHEMABINDING, чтобы успокоить «детерминированное» требование индекса в вычисленном столбце.

Функция, объявленная WITH SCHEMABINDING, сохранит дополнительные знания об объектных зависимостях (например, столбцы в таблице) и предотвратит любые изменения этих столбцов, если только сама функция не будет удалена заранее.

Детерминированные функции также могут помочь Sql Server в оптимизации его планов выполнения, большинство особенно проблема защиты Хэллоуина .

Вот пример создания индекса в вычисленном столбце с использованием связанной с схемой функции:

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
5
ответ дан StuartLC 22 August 2018 в 16:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: