sql服务器确定性用户定义的函数

问题描述 投票:0回答:2
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

我无法使用此功能在计算列上创建索引,因为它不是确定性的。 有人可以解释为什么它不是确定性的,最终如何修改以使其确定性? 谢谢

您只需要创建它。 

然后,SQL Server将验证它是否符合被视为确定性的标准(因为它无法访问任何外部表或使用非确定性功能,例如

with schemabinding
sql sql-server-2008 function calculated-columns non-deterministic
2个回答
63
投票
您可以验证它是否与

一起使用

getdate()

将Schemabinding选项添加到您的原始代码方面工作正常,但版本稍简单。

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

您需要声明用户定义的函数
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
安抚计算列上索引的“确定性”要求。 声明为a的函数

WITH SCHEMABINDING

将保留有关该函数中使用的对象依赖项的其他知识(例如表中的列),并且将防止对这些列的任何更改,除非事先删除函数本身。 确定功能还可以帮助SQL Server优化其执行计划,最著名的是HalloweenProtection
问题。

there是使用模式绑定函数在计算列上创建索引的一个示例:

12
投票

我的问题是相似的:)
我想在选择中使用我的功能,我想指定此功能是确定性的,因此它不需要计算每一行的SQL。

例如,下面的选择在每一行的第一列中返回同一时间,但在第二列中不返回。

可以在某个地方指定test()函数应该像plain getDate()一样工作吗? (我知道我可以将其保存到一个变量中,但是需要重写数百个查询,这不足以用dbo.getcetdate()every vernedecn :))

测试:

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

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.