确定性和不确定函数

每当使用一组特定的输入值调用时,确定性函数始终返回相同的结果,并给出相同的数据库状态。 即使访问的数据库状态保持不变,非确定函数每次使用一组特定的输入值调用它们时都可能会返回不同的结果。 例如,函数 AVG 始终返回与上面所述的限定条件相同的结果,但返回当前日期/时间值的 GETDATE 函数始终返回不同的结果。

用户定义的函数有多个属性,这些属性决定了 SQL Server 数据库引擎能够通过调用函数的计算列上的索引,或通过引用函数的索引视图为函数的结果编制索引。 函数的确定性是这样的属性。 例如,如果视图引用任何不确定函数,则无法在视图上创建聚集索引。 有关函数的属性(包括确定性)的详细信息,请参阅 User-Defined 函数

本主题标识内置系统函数的确定性,以及当用户定义函数包含对扩展存储过程的调用时的确定性属性的影响。

内置函数确定性

不能影响任何内置函数的确定性。 每个内置函数都是确定性的或不确定的,具体取决于 SQL Server 如何实现函数。 例如,在查询中指定 ORDER BY 子句不会更改该查询中使用的函数的确定性。

所有字符串内置函数都是确定性的。 有关这些函数的列表,请参阅字符串函数(Transact-SQL)。

字符串函数以外的内置函数类别中的以下内置函数始终是确定性的。

ABS DATEDIFF 电源
ACOS (阿科斯) 弧度
ASIN(亚马逊标准识别号) 学位 圆形
ATAN EXP(经验值) 标识
ATN2 地板
天花板 ISNULL (判断是否为空) 广场
合并 ISNUMERIC SQRT
COS 日志
婴儿床 LOG10 年份
数据长度
日期加法函数 (DATEADD) NULLIF

以下函数并不总是确定性的,但在以确定性方式指定索引视图或计算列上的索引时,可以使用这些函数。

功能 注释
所有聚合函数 除非使用 OVER 和 ORDER BY 子句指定所有聚合函数,否则所有聚合函数都是确定性的。 有关这些函数的列表,请参阅聚合函数(Transact-SQL)。
是确定性的,除非与datetimesmalldatetimesql_variant一起使用。
转换 ``` 是确定的,除非存在以下条件之一: ```

源类型为 sql_variant.

目标类型是 sql_variant 且其源类型是不确定的。

源或目标类型为 datetimesmalldatetime,其他源或目标类型为字符串,并且指定了不确定样式。 要确定性,样式参数必须是常量。 此外,小于或等于 100 的样式是不确定的,但样式 20 和 21 除外。 大于 100 的样式是确定性的,但样式 106、107、109 和 113 除外。
校验和 除了 CHECKSUM 以外,都是确定性的。
ISDATE 只有在与 CONVERT 函数一起使用时,并且指定了 CONVERT 样式参数且样式不等于 0、100、9 或 109 时,才是确定性的。
兰德公司 (RAND Corporation) 仅当指定 种子 参数时,RAND 才具有确定性。

所有配置、游标、元数据、安全性和系统统计函数都是不确定的。 有关这些函数的列表,请参阅 Configuration Functions(Transact-SQL)游标函数(Transact-SQL)元数据函数(Transact-SQL)、安全功能函数(Transact-SQL系统统计函数(Transact-SQL)。

其他类别中的以下内置函数始终是不确定的。

@@连接 GETDATE
@@CPU_BUSY 获取UTC日期
@@DBTS 获取传输状态
@@IDLE 延迟
@@IO_BUSY 最后值
@@MAX_CONNECTIONS 领先
@@包裹已接收 MIN_ACTIVE_ROWVERSION
@@PACK_SENT NEWID
@@PACKET_ERRORS NEWSEQUENTIALID
@@TIMETICKS 下一个值
@@TOTAL_ERRORS NTILE
@@TOTAL_READ PARSENAME
@@TOTAL_WRITE PERCENTILE_CONT
CUME_DIST 百分位数_离散 (PERCENTILE_DISC)
当前时间戳 百分等级
DENSE_RANK 兰德公司 (RAND Corporation)
FIRST_VALUE 排名
ROW_NUMBER
TEXTPTR

从函数调用扩展存储过程

调用扩展存储过程的函数是不确定的,因为扩展存储过程可能会对数据库造成副作用。 副作用是对数据库的全局状态(例如对表的更新)或外部资源(例如文件或网络)的更改;例如,修改文件或发送电子邮件。 从用户定义的函数执行扩展存储过程时,不应依赖返回一致的结果集。 不建议使用对数据库产生副作用的用户定义函数。

从函数内部调用时,扩展存储过程无法将结果集返回给客户端。 任何向客户端返回结果集的 Open Data Services API 都将具有 FAIL 的返回代码。

扩展存储过程可以重新连接到 SQL Server。 但是,该过程无法联接与调用扩展存储过程的原始函数相同的事务。

与批处理或存储过程的调用类似,扩展存储过程在运行 SQL Server 的 Microsoft Windows 安全帐户的上下文中执行。 向其他用户授予执行该过程的权限时,扩展存储过程的所有者应考虑这一点。