복붙노트

[SQL] SQL 서버 결정적 사용자 정의 함수

SQL

SQL 서버 결정적 사용자 정의 함수

나는 다음과 같은 사용자 정의 기능을 가지고 :

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

나는 그것이 결정적 아니다 원인이 기능을 사용하여 계산 된 열에서 인덱스를 만들 수 없습니다. 누군가가 왜 결정하지 설명 할 수 결국 어떻게 결정하도록 수정? 감사

해결법

  1. ==============================

    1.당신은 SCHEMABINDING로를 만들어야합니다.

    당신은 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. ==============================

    2.당신은 계산 된 컬럼에 인덱스의 '결정'요구 사항을 달래기 위해 SCHEMABINDING로 사용자 정의 함수를 선언해야합니다.

    당신은 계산 된 컬럼에 인덱스의 '결정'요구 사항을 달래기 위해 SCHEMABINDING로 사용자 정의 함수를 선언해야합니다.

    SCHEMABINDING로 선언 된 기능 (테이블의 예를 들어, 열) 기능에 사용되는 개체 종속성에 대한 자세한 지식을 유지하며, 함수 자체가 사전에 삭제하지 않는 한, 이러한 열을 변경 방지 할 수 있습니다.

    결정적 함수는 또한 실행 계획, 특히 할로윈 보호 문제를 최적화는 SQL 서버를 지원할 수 있습니다.

    여기 스키마 경계 기능을 이용하여 계산 된 열 인덱스를 생성하는 예이다 :

    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
    
  3. from https://stackoverflow.com/questions/3651662/sql-server-deterministic-user-defined-function by cc-by-sa and MIT license