原文鏈接:https://blog.csdn.net/lanxingbudui/article/details/81736402
前言:
在SQL server中不僅可以可以使用系統自帶的函數(時間函數、聚合函數、字符串函數等等),還可以根據需要自定義函數。
一、定義:
用戶自定義函數的類型:
1、標量值函數(返回一個標量值)
2、表格值函數(內聯表格值函數、多語句表值函數,返回一個結果集即返回多個值)
二、三種自定函數的異同點
1、同點:
創建定義相同:
CREATE FUNCTION F_NAME(傳入的參數名稱 傳入參數的類型) RETURNS 返回值類型 AS
2、異點:
a.標量值函數返回的是一個數據類型值,
內聯表值函數返回的是一個table,而多語句表值函數返回的是一個table的變量(類似前面兩個的結合);
b.語法的結構:標量值函數和多語句表值函數都是要有begin.........................end,內聯表值函數就沒有;
c.調用:標量函數要寫成在dbo.function_name;
三、函數參數
參數可以是常量、表中的某個列、表達式或其他類型的值。在函數中有三種類型的參數。
1、輸入:指必須輸入一個值。
2、可選值:在執行該參數時,可以選擇不輸入參數。
3、默認值:函數中默認有值存在,調用時可以不指定該值。
四、舉例說明:
1、標量值函數定義格式:
拿個具體的例子說事:
准備數據:之前有一篇博文寫了新建表和插入數據的語句,可參考:
https://mp.csdn.net/postedit/81702708
想要輸入時間得到名字的函數
CREATE FUNCTION dbo.func_date_get_name(@date_into varchar(8)) --CREATE FUNCTION 函數名稱(@參數名 參數的數據類型) RETURNS varchar(20) --返回返回值的數據類型 --[WITH ENCRYPTION] --如果指定了 encryption 則函數被加密 as BEGIN declare @result_name varchar(20) select @result_name = Value_name from test_ceshi where statdate = @date_into RETURN @result_name END --select dbo.func_date_get_name('20180808') name; --select * from test_ceshi;
測試這個自定義函數:func_date_get_name ,即可得到name的結果為:Test1

以下是test_ceshi表的全量數據。

例子二:這個函數使用了if...else條件語句
--編寫一個函數,該函數,可以通過輸入借書時間來判斷是否到期,當借閱時間大於30天,返回已經過期;否則返回還未到期。
CREATE FUNCTION IsDateout(@BDate datetime) returns nvarchar(20) AS BEGIN DECLARE @myresult nvarchar(20) IF (datediff(day,@BDate,getdate())>30) BEGIN SET @myresult='已過期' end else begin set @myresult='未到期' end RETURN (@myresult) END SELECT dbo.IsDateout(cast('2018-01-01' AS datetime))--結果已過期 SELECT dbo.IsDateout(cast('2018-08-01' AS datetime))--結果未到期
2、內聯表格值函數定義格式:
特點:內聯表格值函數支持在WHERE子句中使用參數
CREATE FUNCTION function_name(@parameter_name parameter_data_type) --CREATE FUNCTION 函數名稱(@參數名 參數的數據類型) RETURNS table --返回一個表 [WITH ENCRYPTION] --如果指定了 encryption 則函數被加密 [AS] RETURN (一條SQL語句)
有了格式,寫個實例:
CREATE FUNCTION dbo.func_date_get_table(@date_into varchar(8)) RETURNS table --[WITH ENCRYPTION] --如果指定了 encryption 則函數被加密 as RETURN select statdate,Value_name from test_ceshi where statdate = @date_into --select * from dbo.func_date_get_table('20180808') ;
得到如下的結果:

3、多語句表值函數定義格式:
多語句表值函數跟內聯表值函數都是表值函數,它們返回的結果都是Table類型。多語句表值函數通過多條語句來創建Table類型的數據。這里不同於內聯表值函數,內聯表值函數的返回結果是由函數體內的SELECT語句來決定。而多語句表值函數,則是需要指定具體的Table類型的結構。也就是說返回的Table已經定義好要哪些字段返回。所以它能夠支持多條語句的執行來創建Table數據。
CREATE FUNCTION function_name(@parameter_name parameter_data_type) --CREATE FUNCTION 函數名稱(@參數名 參數的數據類型) RETURNS @Table_Variable_Name table (Column_1 culumn_type,Column_2 culumn_type) --RETURNS @表變量 table 表的定義(即列的定義和約束) [WITH ENCRYPTION] --如果指定了 encryption 則函數被加密 [AS] BEGIN 函數體(即 Transact-SQL 語句) RETURN END
因為此類型的自定義函數在實際工作中使用最多,我多舉幾個例子說明,有些是別人寫的內容:
例子1:
CREATE FUNCTION dbo.func_date_get_table_test(@date_into varchar(8)) RETURNS @table_test table(date varchar(8),ID varchar(20),name varchar(20)) --[WITH ENCRYPTION] --如果指定了 encryption 則函數被加密 as begin insert @table_test select statdate,value_id,Value_name from test_ceshi where statdate = @date_into RETURN end --select * from dbo.func_date_get_table_test(20180808);
測試函數dbo.func_date_get_table_test(),結果如下圖:

例子2:出處--海盜船長 https://www.cnblogs.com/baidawei/p/4732969.html
create function dbo.Test() returns @temp table ( name varchar(20), sex char(2), age int ) as begin insert into @temp (name,sex,age) values ('多語句','嘛',18) insert into @temp (name,sex,age) select name,sex,age from student where age > 18 return end
五、修改和刪除自定義函數
1、使用alter語句修改自定義函數:
--格式:
alter function 函數名(參數) returns table
as
return(一條SQL語句)
2、使用drop語句刪除:
drop function func_date_get_name
六、注意事項:
在編寫自定義函數時需要注意的:
標量函數:
1. 所有的入參前都必須加@
2. create后的返回,單詞是returns,而不是return
3. returns后面的跟的不是變量,而是返回值的類型,如:int,char等。
4. 在begin/end語句塊中,是return。
內聯表格值函數:
1. 只能返回table,所以returns后面一定是TABLE
2. AS后沒有begin/end,只有一個return語句來返回特定的記錄。
多語句表值函數:
1. returns后面直接定義返回的表類型,首先是定義表名,表明前面要加@,然后是關鍵字TABLE,最后是表的結構。
2. 在begin/end語句塊中,直接將需要返回的結果insert到returns定義的表中就可以了,在最后return時,會將結果返回。
3. 最后只需要return,return后面不跟任何變量。
