Sql Server确定性用户定义函数
我有以下用户定义的功能:Sql Server确定性用户定义函数,sql,sql-server-2008,function,calculated-columns,non-deterministic,Sql,Sql Server 2008,Function,Calculated Columns,Non Deterministic,我有以下用户定义的功能: 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 @
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
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
我无法使用此函数在计算列上创建索引,因为它不是确定性的。
有人可以解释为什么它不是确定性的,以及最终如何修改以使它具有确定性?
谢谢您只需要使用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
您需要使用SCHEMABINDING声明用户定义的函数
,以满足计算列上索引的“确定性”要求
使用SCHEMABINDING声明的函数将保留有关函数中使用的对象依赖关系(例如表中的列)的附加知识,并将防止对这些列进行任何更改,除非函数本身事先被删除
确定性函数还可以帮助SQLServer优化其执行计划,尤其是问题
下面是使用模式绑定函数在计算列上创建索引的示例:
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
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
我创建了指向计算列的索引。我还有一个指向我的表的视图。我认为我还必须在视图上指定SchemaBinding,以便在同一列上创建索引。关于这一点,如果我的基表作为计算列的索引,是否多余?在视图上创建另一个索引?@opera-是-您不需要在视图中为该列编制索引。如果可以,最后一个问题。我有一个sp,它对视图(引用索引表的视图)进行查询。我可以/应该在查询from子句中指定索引名?e、 g.从MyView(使用MyTableIndex)中选择*。。。也许我这样做有一些好处?@opera-不,只要启用了ARITHABORT
或ANSI_WARNINGS
,它就应该自动使用持久化列值。您可以检查执行计划以确定这一点。