建立使用者定義函數 (Database Engine)
建立使用者自訂函數是使用 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 陳述式。只允許使用 INTO 子句指派值給本機變數的 FETCH 陳述式。
除了 TRY...CATCH 陳述式以外的流程控制陳述式。
含有選取清單及指派值給對函數而言為本機變數之運算式的 SELECT 陳述式。
修改對函數而言為本機之資料表變數的 UPDATE、INSERT 及 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 關鍵字。此一行為不同於使用者自訂預存程序中有預設值的參數,在這些預存程序中省略參數亦意謂著省略預設值。使用者自訂函數不支援輸出參數。