MS SQL Server 计算列用到自定义函数 创建索引

 

MS SQL Server2005

 

有一计算列用到了自定义函数

函数代码如下:

 

ExpandedBlockStart.gif View Code
CREATE  FUNCTION  [ dbo ]. [ f_RecommendCondition ]
    (
       @Views  INT ,
       @Replies  INT ,
       @Digest  TINYINT
    )
RETURNS  INT
AS 
     BEGIN
         DECLARE  @returnValue  INT
         SELECT  @returnValue = @Digest + @Replies + @Views;
         IF (  @Digest  IN (  12310 )
              AND  @Views  >  99
              AND  @Replies  >  9
           ) 
             SET  @returnValue  =  1
         ELSE 
             SET  @returnValue  =  0
        
         RETURN  @returnValue
     END

 然后在此列上创建索引提示错误:

不能在此列上创建索引,因为此列不具有确定性。

 于是在MSDN上查了一下,计算列加索引的要求如下:

1、所有权要求
       计算列中的所有函数引用必须与表具有相同的所有者。

2、确定性要求
        如果对于一组指定的输入表达式始终返回相同的结果,则说明表达式具有确定性。          
      computed_column_expression 必须具有确定性。如果下列一项或多项为真,则 computed_column_expression 具有确定性:
     A、表达式引用的所有函数都具有确定性,并且是精确的。这些函数包括用户定义 函数和内置函数。

     B、表达式引用的所有列都来自包含计算列的表。

     C、没有列引用从多行中请求数据。例如,聚合函数(如 SUM 或 AVG)依靠来自多行的数据,这使 计算列表达式 具有不确定性。

     D、没有系统数据访问或用户数据访问。

3、精度要求

     A、表达式的数据类型不是 float 或 real。

     B、表达式定义中没有使用 float 或 real 数据类型。

4、数据类型要求    

    为计算列定义的 computed_column_expression 的值不能为 text、ntext 或 image 数据类型。

    只要计算列的数据类型可以作为索引键列,从 image、ntext、text、varchar(max)、nvarchar(max)、varbinary(max) 和 xml 数据类型派生的计算列上就可以创建索引。

5、SET 选项要求

NUMERIC_ROUNDABORT 选项必须设置为 OFF,

且下列选项必须设置为 ON:

ANSI_NULLS

ANSI_PADDING

ANSI_WARNINGS

ARITHABORT

CONCAT_NULL_YIELDS_NULL

QUOTED_IDENTIFIER

 

我仔细看了看这几项要求。都没有违背这些要求,特别是2的确定性要求。

为了证明我的函数没有违反确定性要求,我把函数改为:

ExpandedBlockStart.gif View Code
CREATE  FUNCTION  [ dbo ]. [ f_return1 ]
    ()
RETURNS  INT
AS 
     BEGIN
         RETURN  1
     END

 仍然错误。

后来想到Leader曾经讲索引视图时 好像要加一个什么关键字。

查了下关于索引视图的sql 里面有个

WITH SCHEMABINDING
把之前的函数改成:

 

ExpandedBlockStart.gif View Code
CREATE  FUNCTION  [ dbo ]. [ f_RecommendConditionWith ]
    (
       @Views  INT ,
       @Replies  INT ,
       @Digest  TINYINT
    )
RETURNS  INT
WITH SCHEMABINDING
AS 
     BEGIN
         DECLARE  @returnValue  INT
         SELECT  @returnValue = @Digest + @Replies + @Views;
         IF (  @Digest  IN (  12310 )
              AND  @Views  >  99
              AND  @Replies  >  9
           ) 
             SET  @returnValue  =  1
         ELSE 
             SET  @returnValue  =  0
        
         RETURN  @returnValue
     END

 之后创建索引成功

 


  

 

转载于:https://www.cnblogs.com/zhaoguo435/archive/2012/07/11/2586749.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值