打開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所示。