打开Microsoft SQL Server Management Studio,展开任意一个数据库节点下的【可编程性】节点,如图4.27所示。读者会发现该节点下,除【函数】节点还没有介绍以外,其他【可编程性】功能已全部介绍过了。本节着重对SQL Server提供的函数功能进行介绍。
图4.27 【函数】节点
用户自定义函数(User Defined Functions,UDFs)是SQL Server提供的另一强大功能。借助UDFs,数据库开发人员可以实现复杂的运算操作,例如实现功能更加强大的聚合运算。UDFs返回的结果可以是一个单一数值(即标量值函数),也可以是一个数据集(即表值函数)。实际上,前面介绍的存储过程和触发器概念都可以被归为用户自定义函数。
SQL Server从其2000版本开始就已向数据库开发人员提供了用户自定义函数功能。开发人员可以使用Transact-SQL根据需要开发自己所需的自定义函数。而进入SQL Server 2005后,与存储过程、触发器以及自定义类型一样,自定义函数也可以由CLR实现,即通过高级语言实现自定义函数。由此可见,CLR功能极大地扩展了SQL Server数据的编程能力。
SQL Server 2005为数据库开发人员提供了一些自带的用户自定义函数。其中,一些用户自定义函数由SQL Server数据库服务器自身以及SQL Server Management Studio等数据库管理工具,数据库服务器以及客户端所使用。下面简要介绍一些常见的用户自定义函数。与大部分存储过程不一样,用户无法修改这些用户自定义函数。很多情况下,用户甚至无法使用存储过程sp_help或sp_helptext来查看这些函数的Transact-SQL脚本代码。SQL Server为用户自定义函数提供了专门的系统数据表syscomments来保存这些用户自定义函数的定义信息。
SQL Server提供的内置系统函数的前缀分为两类,即dm_和fn_。其中fn_为常见的函数(function)缩写,而前缀dm_则是SQL Server 2005新添加的功能——动态管理(Dynamic Management)功能的缩写。SQL Server 2005提供的动态管理功能包括两类,即动态管理视图(Dynamic Management View,DMV)和动态管理函数(Dynamic Management Function,DMV)。
提示 利用SQL Server 2005提供的动态管理视图和函数可以方便地查看SQL Server 2005中各实例的相关信息,便于数据库管理人员了解当前数据库进程的阻塞信息(使用sys.dm_exec_requests)以及用户登录情况(sys.dm_exec_sessions)等,详细内容请参见Microsoft提供的联机帮助文档。
对于DBA(数据库管理员)来说,SQL Server 2005提供的另外一个强大的函数是fn_get_sql。通过该函数,数据库管理员和开发人员可以很轻松地获取正在被一个SQL进程执行的SQL文本。因此,如果需要诊断或调试出现的某种死锁或阻塞问题,使用该函数将显得非常有用。fn_get_sql的语法约定如下所示。
fn_get_sql ( SqlHandle )
其中SqlHandle为指定的SQL句柄。函数将返回指定SQL句柄的文本。SQL Server 2005的系统视图Sys.SysPRocesses中包含着当前Microsoft SQL Server实例中运行的所有进程信息。其中包含了cmd字段,即当前执行的命令,以及sqlhandle字段,即当前正在执行的批处理语句或对象的句柄。除此之外,SQL Server中还提供了一个名为sys.dm_exec_requests的动态管理视图。该视图中包含当前SQL Server的每一个请求的相关信息,其中包括字段sql_handle。通过访问这两个视图Sys.Sysprocesses和sys.dm_exec_requests,就可以获取与指定sql_handle相关的所有信息,具体设置过程如下。
DECLARE @Handle VARBINARY(64); SELECT @handle = sql_handle FROM master.dbo.sysprocesses WHERE spid = @@SPID SELECT * FROM ::fn_get_sql(@Handle); GO
图4.34 运行结果
提示 上述代码中变量@@SPID为当前正在执行的SPID,显然,该SPID应指向查询语句SELECT @handle = sql_handle FROM master.dbo.sysprocesses WHERE spid =@@SPID。在通过上述查询语句获得一个sql_handle后,就可以使用系统函数fn_get_sql来获得该sql_handle所指定的进程的SQL文本了,如图4.35所示。