创建用户定义函数(数据库引擎)

可分别使用 CREATE FUNCTION、ALTER FUNCTION 以及 DROP FUNCTION 语句来分别实现用户定义函数的创建、修改和删除。每个完全限定用户定义函数名称 (schema_name.function_name) 必须唯一。

指导方针

在函数中,区别处理导致语句被删除并继续模块(如触发器或存储过程)中下一条语句的 Transact-SQL 错误。在函数中,上述错误会导致停止执行函数。接下来该操作导致取消调用该函数的语句。

BEGIN...END 块中的语句不能有任何副作用。函数副作用是指对具有函数外作用域(例如数据库表的修改)的资源状态的任何永久性更改。函数中的语句唯一能做的更改是对函数上的局部对象(如局部游标或局部变量)的更改。不能在函数中执行的操作包括:对数据库表的修改,对不在函数上的局部游标进行操作,发送电子邮件,尝试修改目录,以及生成返回至用户的结果集。

注意注意

如果 CREATE FUNCTION 语句对在发出 CREATE FUNCTION 语句时不存在的资源产生副作用,SQL Server 将执行该语句。但在调用函数时,SQL Server 不执行此函数。

在查询中指定的函数的实际执行次数在优化器生成的执行计划间可能不同。示例为 WHERE 子句中的子查询调用的函数。子查询及其函数执行的次数会因优化器选择的访问路径的不同而异。

函数中的有效语句

函数中的有效语句的类型包括:

  • DECLARE 语句,该语句可用于定义函数局部的数据变量和游标。

  • 为函数局部对象的赋值,如使用 SET 为标量和表局部变量赋值。

  • 游标操作,该操作引用在函数中声明、打开、关闭和释放的局部游标。不允许使用 FETCH 语句将数据返回到客户端。仅允许使用 FETCH 语句通过 INTO 子句给局部变量赋值。

  • TRY...CATCH 语句以外的流控制语句。

  • SELECT 语句,该语句包含具有为函数的局部变量赋值的表达式的选择列表。

  • INSERT、UPDATE 和 DELETE 语句,这些语句修改函数的局部表变量。

  • EXECUTE 语句,该语句调用扩展存储过程。

内置系统函数

下列具有不确定性的内置函数可以在 Transact-SQL 用户定义函数中使用。

CURRENT_TIMESTAMP

@@MAX_CONNECTIONS

GET_TRANSMISSION_STATUS

@@PACK_RECEIVED

GETDATE

@@PACK_SENT

GETUTCDATE

@@PACKET_ERRORS

@@CONNECTIONS

@@TIMETICKS

@@CPU_BUSY

@@TOTAL_ERRORS

@@DBTS

@@TOTAL_READ

@@IDLE

@@TOTAL_WRITE

@@IO_BUSY

 

下列不确定性内置函数不能在 Transact-SQL 用户定义函数中使用。

NEWID

RAND

NEWSEQUENTIALID

TEXTPTR

有关具有确定性和不确定性的内置系统函数的列表,请参阅 确定性函数和不确定性函数

绑定到架构的函数

CREATE FUNCTION 支持 SCHEMABINDING 子句,后者可将函数绑定到它引用的任何对象(如表、视图和其他用户定义函数)的架构。尝试更改或删除绑定到架构的函数所引用的任何对象失败。

必须满足以下条件才能在 CREATE FUNCTION 中指定 SCHEMABINDING:

  • 该函数引用的所有视图和用户定义函数必须是绑定到架构的视图和函数。

  • 该函数引用的所有对象必须与该函数位于同一数据库中。必须使用由一部分或两部分构成的名称来引用对象。

  • 必须具有该函数中引用的所有对象(表、视图和用户定义函数)的 REFERENCES 权限。

可使用 ALTER FUNCTION 删除架构绑定。ALTER FUNCTION 语句会在不指定 WITH SCHEMABINDING 的情况下重新定义函数。

指定参数

用户定义函数采用零个或多个输入参数并返回标量值或表。一个函数最多可以有 1024 个输入参数。如果函数的参数有默认值,则调用该函数时必须指定 DEFAULT 关键字,才能获取默认值。此行为与在用户定义存储过程中具有默认值的参数不同,在后一种情况下,忽略参数同样意味着使用默认值。用户定义函数不支持输出参数。