Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Server确定性用户定义函数_Sql_Sql Server 2008_Function_Calculated Columns_Non Deterministic - Fatal编程技术网

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
,它就应该自动使用持久化列值。您可以检查执行计划以确定这一点。