Sql Server deterministic user-defined function Sql Server deterministic user-defined function sql sql

Sql Server deterministic user-defined function


You just need to create it with schemabinding.

SQL Server will then verify whether or not it meets the criteria to be considered as deterministic (which it does as it doesn't access any external tables or use non deterministic functions such as getdate()).

You can verify that it worked with

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

Adding the schemabinding option to your original code works fine but a slightly simpler version would be.

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


You need to declare the User Defined Function WITH SCHEMABINDING to appease the 'deterministic' requirement of an index on the computed column.

A function declared WITH SCHEMABINDING will retain additional knowledge about the object dependencies used in the function (e.g. columns in the table), and will prevent any changes to these columns, unless the function itself is dropped beforehand.

Deterministic functions can also assist Sql Server in optimizing its execution plans, most notably the Halloween Protection problem.

Here's an example of creating an index on a computed column using a schema bound function:

create function [dbo].[FullNameLastFirst] (     @IsPerson bit,     @LastName nvarchar(100),     @FirstName nvarchar(100) ) returns nvarchar(201) with schemabindingas 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))goinsert into person(isperson, lastname, firstname) values (1,'Firstname', 'Surname')gocreate index ix1_person on person(fullname)goselect fullname from Person with (index=ix1_person) where fullname = 'Firstname Surname'go