與編程語言中的函數相似,SQL Server 用戶定義函數是接受參數、執行操做(例如複雜計算)並將操做結果以值的形式返回的例程。 返回值能夠是單個標量值或結果集。sql
在函數中,將會區別處理致使語句被取消並繼續執行模塊(如觸發器或存儲過程)中的下一個語句的 Transact-SQL 錯誤。 在函數中,上述錯誤會致使中止執行函數。 接下來該操做致使取消調用該函數的語句。數據庫
BEGIN...END 塊中的語句不能有任何反作用。 函數反作用是指對具備函數外做用域(例如數據庫表的修改)的資源狀態的任何永久性更改。 函數中的語句惟一能作的更改是對函數上的局部對象(如局部遊標或局部變量)的更改。 不能在函數中執行的操做包括:對數據庫表的修改,對不在函數上的局部遊標進行操做,發送電子郵件,嘗試修改目錄,以及生成返回至用戶的結果集。編程
若是 CREATE FUNCTION 語句對在發出 CREATE FUNCTION 語句時不存在的資源產生反作用,SQL Server 將執行該語句。 但在調用函數時, SQL Server 不執行此函數。緩存
在查詢中指定的函數的實際執行次數在優化器生成的執行計劃間可能不一樣。 示例爲 WHERE 子句中的子查詢調用的函數。 子查詢及其函數執行的次數會因優化器選擇的訪問路徑的不一樣而異。安全
用戶定義標量函數返回在 RETURNS 子句中定義的類型的單個數據值。 對於內聯標量函數,沒有函數體;標量值是單個語句的結果。 對於多語句標量函數,定義在 BEGIN...END 塊中的函數體包含一系列返回單個值的 Transact-SQL 語句。 返回類型能夠是任何數據類型除外text, ntext, image, cursor,和timestamp。服務器
用戶定義表值函數返回table數據類型。 對於內聯表值函數,沒有函數主體;表是單個 SELECT 語句的結果集。網絡
SQL Server 提供了許多系統函數,可用於執行各類操做。 這些函數不能修改。 有關詳細信息,請參閱內置函數 (Transact-SQL)、系統存儲函數 (Transact-SQL) 和動態管理視圖和函數 (Transact-SQL)。編程語言
聚合函數
聚合函數對一組值執行計算,並返回單個值。 在 select 列表或 SELECT 語句的 HAVING 子句中容許使用它們。 能夠將聚合與 GROUP BY 子句結合使用,來計算行類別的聚合。 ide
使用 OVER 子句來計算特定範圍內的值的聚合。 OVER 子句不能跟在 GROUPING 或 GROUPING_ID 聚合後。模塊化
聚合函數對一組值執行計算,並返回單個值。 除了 COUNT 外,聚合函數都會忽略 Null 值。
全部聚合函數均爲肯定性函數。 換言之,每次使用一組特定的輸入值調用聚合函數時,它們所返回的值都是相同的。 有關函數肯定性的詳細信息,請參閱肯定性函數和不肯定性函數。
只能在如下位置將聚合函數做爲表達式使用:
SELECT 語句的選擇列表(子查詢或外部查詢)。
HAVING 子句。
分析函數
解析函數基於一組行計算聚合值。 不過,與聚合函數不一樣,分析函數可能針對每一個組返回多行。 可使用分析函數來計算移動平均線、運行總計、百分比或一個組內的前 N 個結果。
排名函數
排名函數爲分區中的每一行返回一個排名值。 根據所用函數的不一樣,某些行可能與其餘行接收到相同的值。 排名函數具備不肯定性。
行集函數
行集函數 返回可在 SQL 語句中像表引用同樣使用的對象。
標量函數
對單一值進行運算,而後返回單一值。 只要表達式有效,便可使用標量函數。
SQL Server 提供瞭如下組的系統函數:Always On 可用性組函數、變動數據捕獲函數、更改跟蹤函數、據收集器函數、Filestream 和 FileTable 函數、託管備份函數、sys.fn_get_sql、sys.fn_MSxe_read_event_stream、sys.fn_stmt_sql_handle_from_sql_stmt、sys.fn_validate_plan_guide、sys.fn_xe_file_target_read_file、sys.fn_backup_file_snapshots、語義全文搜索函數、系統元數據函數、系統安全函數、系統跟蹤函數。
動態管理視圖和函數返回可用於監視服務器實例的運行情況、診斷故障以及優化性能的服務器狀態信息。
動態管理視圖和函數分爲兩種類型:
服務器範圍內的動態管理視圖和函數。 此類型須要具備該服務器的 VIEW SERVER STATE 權限。
數據庫範圍內的動態管理視圖和函數。 此類型須要具備該數據庫的 VIEW DATABASE STATE 權限。
用戶定義函數採用零個或多個輸入參數並返回標量值或表。 一個函數最多能夠有 1024 個輸入參數。 若是函數的參數有默認值,則調用該函數時必須指定 DEFAULT 關鍵字,才能獲取默認值。 此行爲與在用戶定義存儲過程當中具備默認值的參數不一樣,在後一種狀況下,忽略參數一樣意味着使用默認值。
用戶定義函數不支持輸出參數。
標量函數返回的是一個數據類型值。
內聯表值函數返回的是一個table。
系統函數用戶執行指定操做,能夠返回數據類型值或者table。
具備重複代碼、功能和代碼塊的地方,應使用函數以使代碼具備更好的可維護性、可重用性和更少的複雜性。
須要對錶中數據進行簡單處理,例如數學計算時能夠考慮使用函數。
只有查詢功能時應優先考慮視圖,包含查詢和其餘操做的應優先考慮函數。
在 SQL Server 中使用用戶定義函數有如下優勢:
容許模塊化程序設計。
只需建立一次函數並將其存儲在數據庫中,之後即可以在程序中調用任意次。 用戶定義函數能夠獨立於程序源代碼進行修改。
執行速度更快。
與存儲過程類似,Transact-SQL 用戶定義函數經過緩存計劃並在重複執行時重用它來下降 Transact-SQL 代碼的編譯開銷。這意味着每次使用用戶定義函數時均無需從新解析和從新優化,從而縮短了執行時間。
和用於計算任務、字符串操做和業務邏輯的 Transact-SQL 函數相比,CLR 函數具備顯著的性能優點。 Transact-SQL 函數更適用於數據訪問密集型邏輯。
減小網絡流量。
基於某種沒法用單一標量的表達式表示的複雜約束來過濾數據的操做,能夠表示爲函數。 而後,此函數即可以在 WHERE 子句中調用,以減小發送至客戶端的數字或行數。
查詢中的 Transact-SQL 用戶定義函數只能針對單個線程執行(串行執行計劃)。
用戶自定義函數不能用於執行一系列改變數據庫狀態的操做。
能在函數中使用的語句有嚴格限制:
不支持create、ALTER、drop等DDL(Data Definition Language)命令。insert、delete、update只能用在臨時表上。不支持動態SQL。不支持「不肯定」的函數,好比經常使用的getdate。不肯定函數是指輸入參數相同,返回結果可能不一樣的函數。