用戶自定義函數
在使用SQL server的時候,除了其內置的函數之外,還允許用戶根據需要自己定義函數。根據用戶定義函數返回值的類型,可以將用戶定義的函數分為三個類別:
- 返回值為可更新表的函數
如果用戶定義函數包含了單個select語句且語句可更新,則該函數返回的表也可更新,這樣的函數稱為內嵌表值函數。
- 返回值不可更新表的函數
如果用戶定義函數包含多個select語句,則該函數返回的表不可更新。這樣的函數稱為多語句表值函數。
- 返回標量值的函數
用戶定義函數返回值為標量值,這樣的函數稱為標量函數。
在這里需要說明一下,用戶定義的函數是可以接受零個或多個輸入參數的,函數的返回值可以是一個數值,也可以是一個表。用戶定義的函數不支持輸出函數;
利用alter function可以對用戶定義函數進行修改,用drop function 可以刪除用戶定義函數(當然,也可以直接通過圖形界面操作進行刪除,但這里不多累述);
標量函數的定義與調用
標量函數定義的語法格式如下:
1 create function [owner_name] function_name 2 ([{@parameter_name [as] scalar_parameter_date_type [=default]}[,…n]]) 3 returns scalar_return_data_type [with encryption] [as] 4 begin 5 function_body 6 return scalar_expression 7 end
其中的含義分別如下:
- owner_name : 數據庫所有名。
- function_name:用戶定義函數名,函數名必須符合標示符規范,對其所有者來說,該用戶名在數據庫中必須是唯一的。
- @parameter_name:用戶定義函數的形參名, create function 語句中可以申明一個或多個參數,用@符號作為第一個字符來指定形參名 ,每個函數的參數局部作用於該函數。
- scalar_parameter_data_type:參數的數據類型,可為系統支持的基本標量類型,不能為 timestamp 類型、用戶定義數據類型、非標量類型(如 cursor 和 tabel)。
- default:指定默認值。
- with 子句指出了創建函數的選項,如果指出了 encryption 參數,則創建的函數是被加密的,函數定義的文本將以不可讀的形式存儲在 syscomments 表中,任何人都不能查看該函數的定義,包括函數的創建者和系統管理員。
- begin 和 end 之間定義了函數題,該函數體中必須包括一條 return語句,用於返回一個值。函數返回 scalar_expression 表達式的值。
- scalar_return_data_type:用戶定義函數的返回類型,可以是 SQL Server 支持的基本標量類型,但 text 、nterxt 、image 和 timestamp 除外。
根據上面的解釋不妨來自定義一個函數,用來做一個統計 ——
統計學院學生的機試與筆試的平均成績。
假設已經有一個 exam 表,表中有 stuno 字段,便於查詢。
還有筆試成績字段 written 和機試字段 lab ,且已經有記錄存在。
1 create function getScore(@stuno varchar(20)) 2 returns float as 3 begin 4 declare @Score float 5 set @Score = -1; 6 selecet @Score = (isnull(written,0)+isnull(lab,0))/2 7 from exam 8 where stuno = @stuno 9 return @Score 10 end
標量函數的調用:
當調用用戶定義函數的時候,必須要提供至少有兩個部分組成的所有名稱 (所有者.函數名)。調用用戶定義函數的方法有兩種:
1.在 SELECT 語句中調用 ——
owner_name.function_name (@parameter_name1, 2 ……)
參數可為賦值的局部變量或表達式,例如:調用用戶定義函數 getScore.
select dbo.getScore('123456789');
2.用 EXEC 語句執行
用 T-SQL 的 execute 語句調用自定義函數的時候,實參的標識次序與函數定義中的參數標識次序可以不同,其具體調用形式為:
owner_name.function_name @parameter_name1 , .... @parameter_name_n
或
owner_name.function_name @fparameter_name 1 = @aparameter_name1, .... @fparameter_name_n = @aparameter_name_n
前者實參順序應該要與函數定義的形參順序一致,后者實參順序可以與函數定義的形參書訊不一致。
如果函數的參數有默認值,在調用該函數的時候必須指定 default 關鍵字才能獲得默認值 , 這不同於存儲過程中有默認值的參數,在存儲過程中省略參數意味着使用默認值。