用户定义函数(UDF)是执行计算并返回一个值(标量值或表)的一段程序。Microsoft SQL Server 2000引入了UDF,你可以用T-SQL编写UDF并应用于查询、计算列(computed column)和约束。SQL Server 2005又引入了公共语言运行时(CLR)集成,你可以使用任意 .NET语言编写UDF及其他程序和对象。
本章讲述SQL Server所支持的两种UDF:返回单个值的标量值UDF和返回一个表的表值UDF(内联和多语句)。我会提供C# 和Microsoft Visual Basic两种语言的CLR UDF示例代码。
本书中所有的 .NET程序都由Dejan Sarka开发。
注意 这本书共有三章讲述CLR程序 (6、7、8),
本章是其中的第1章。生成和部署CLR代码所需的一些步骤对于在SQL
Server中创建任何类型的CLR程序都是通用的,而且它们都很肤浅。为了避免在正文中重复这些肤浅的步骤,让你专注于程序代码,我把所有CLR程序的相关信息整理在附录A中。
在附录A中,你可以找到创建CLRUtilities测试数据库的脚本,该数据库用于测试这三章中所有的CLR程序。你还可以找到用于开发、生成、部署和测试所有CLR程序的循序渐进的操作指南。
附录还把分散在这三章的CLR程序代码整理到了一起。我建议在继续阅读本章内容之前,先按附录A中的操作指南,创建在这三章用到的所有程序。然后再回到本章继续阅读,并重点关注CLR程序代码而不是那些通用的简单步骤。
2.1 关于UDF
UDF可以嵌入到查询、约束和计算列中。定义UDF的代码不能影响函数范围之外的数据库状态,也就是说,UDF代码不能修改表中的数据或调用会产生副作用(side effect)的函数(例如,RAND)。另外,UDF的代码只能创建表变量,不能创建或访问临时表,也不允许使用动态执行。
创建或修改UDF时,你可以在函数头指定函数选项。T-SQL UDF支持ENCRYPTION和 SCHEMABINDING选项,这些选项我已经在前面讨论视图时介绍过了。T-SQL UDF和CLR UDF时可以使用EXECUTE AS子句创建,该子句允许你定义执行函数的安全性。该选项不能用于内联表值类型的UDF。内联表值UDF与视图非常相似,唯一的区别是它可以接收参数。它由一条查询语句组成,该语句定义函数要返回的表。对于标量值UDF(包含T-SQL和CLR),你还可以指定下面的选项之一:RETURNS NULL ON NULL INPUT 或 CALLED ON NULL INPUT (默认值)。第一个选项通知SQL Server,如果参数值为NULL则不调用该函数,直接返回NULL。第二个选项通知SQL Server,即使输入参数为NULL也需要调用该函数。
在创建所有的UDF时都指定SCHEMABINDING 和 RETURNS NULL ON NULL INPUT选项是一个很好的习惯。SCHEMABINDING 可以防止删除基础的对象和修改引用列。RETURNS NULL ON NULL INPUT会在输入参数为NULL时绕过函数逻辑直接返回NULL,以提高代码的性能。当期望这样并使用该选项时,在函数体内不必使用显式的代码来检查输入参数是否为NULL。在本章的代码示例中,为简单起见,我没有使用这些选项。