SQL Server 自定義函數
簡介
SQL Server自定義函數分為三種類型:標量函數(Scalar Function)、內聯表值函數(Inline Function)、多語句表值函數(Multi-Statement Function)
標量函數:標量函數返回一個確定類型的標量值,返回值類型為除TEXT、NTEXT、IMAGE、CURSOR、TIMESTAMP和TABLE類型外的其它數據類型。函數體語句定義在BEGIN-END語句內,在 RETURNS 子句中定義返回值的數據類型,並且函數的最後一條語句必須為Return語句
內聯表值函數:內聯表值型函數以表的形式返回一個返回值,即它返回的是一個表。內聯表值型函數沒有由BEGIN-END 語句括起來的函數體。其返回的表是由一個位於 RETURN 子句中的 SELECT 命令從數據庫中篩選出來。內聯表值型函數功能相當於一個參數化的視圖
多語句表值函數:多語句表值函數可以看作標量函數和內聯表值函數的結合體。它的返回值是一個表,但它和標量型函數一樣有一個用 BEGIN-END 語句括起來的函數體,返回值的表中的數據是由函數體中的語句插入的。由此可見,它可以進行多次查詢,對數據進行多次篩選與合並,彌補了內聯表值函數的不足
標量函數
創建標量函數的語法:
create function [函數的所有者].函數名(標量參數 [as] 標量參數類型 [=默認值]) returns 標量返回值類型 begin 函數體(即 Transact-SQL 語句) return 變量/標量表達式 end
案例:將字符串‘001.002.003.004’按照指定分隔符進行分割,返回分割後的個數
create function dbo.Fun_GetStrListLeng ( @originlStr varchar(500), --要分割的字符串 @split varchar(10) --分隔符 ) returns int as begin declare @location int,--定義起始位置 @start int,--定義從第幾個開始 @length int;--定義變量,用於接收計算元素的個數 set @originlStr=ltrim(rtrim(@originlStr))--去掉左右兩邊的空格 set @location=charindex(@split,@originlStr) --分割符號在字符串中第一次出現的位置(索引從1開始計數) set執行用戶自定義標量函數:@length=1 while @location<>0 begin set @start=@location+1 set @location=charindex(@split,@originlStr,@start) set @length=@length+1 end return @length end
select dbo.Fun_GetStrListLeng(‘001.002.003.004.005‘,‘.‘) --返回5
創建函數時指定了函數所有者,那麽調用的時候也必須指定函數的所有者。(一般都為 dbo)
調用自定義函數時如果想不傳入參數而使用默認值,那麽必須使用 default 關鍵字。如果自定義函數的參數沒有默認值,那麽會返回 null。
內聯表值函數
創建內聯表值函數的語法:
create function [函數的所有者].函數名(標量參數 [as] 標量參數類型 [=默認值]) returns table [with {Encryption | Schemabinding }] [as] return(單個 SELECT 語句,確定返回的表的數據。)
案例:查詢指定學號的學生的選課情況(包括學號、姓名、課程號和成績),然後調用該函數查詢某位學生的選課情況
create function dbo.Fun_GetList(@學號 char(5)) returns table return( select student.sno,student.sname,course.cno,score.degree from student,course,score where student.sno=score.sno and score.cno=course.cno and student.sno=@學號 )
調用語法:
select * from dbo.Fun_GetList(‘2001‘)
多語句表值函數
創建多語句函數的語法:
create function [函數的所有者].函數名(標量參數 [as] 標量參數類型 [=默認值]) returns @表變量 table 表的定義(即列的定義和約束) begin 函數體(即 Transact-SQL 語句) return end
案列:將字符串‘001.002.003.004’按照指定分隔符進行分割,然後返回
alter FUNCTION [dbo].[Fun_SplitStr] ( @originalStr VARCHAR(8000), --要分割的字符串 @split varchar(100) --分隔符號 ) RETURNS @temp TABLE(Result VARCHAR(100)) AS BEGIN DECLARE @result AS VARCHAR(100); --定義變量用於接收單個結果 SET @originalStr = @originalStr + @split ; WHILE (@originalStr <> ‘‘) BEGIN SET @result = LEFT(@originalStr, CHARINDEX(@split, @originalStr) -1) ; INSERT @temp VALUES(@result) ; --STUFF()函數用於刪除指定長度的字符,並可以在指定的起點處插入另一組字符。 SET @originalStr = STUFF(@originalStr, 1, CHARINDEX(@split, @originalStr), ‘‘); END RETURN END
調用方式跟內聯函數相同
適用範圍
1. 只查詢,不修改數據庫的狀態(修改、刪除表中記錄等)
2. 結果集需要通過遞歸等方法得到時,可以使用函數,函數比較靈活
3. 結果集需要直接被引用時,可以使用函數。需要對結果集進行再加工(指放在select語句中等),可以使用函數,函數可以嵌在select等sql語句中。
註意事項:
用戶自定義函數不能用於執行一系列改變數據庫狀態的操作
在編寫自定義函數時需要註意的:
對於標量函數:
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後面不跟任何變量。
參考:
https://www.cnblogs.com/Brambling/p/6686947.html
SQL Server 自定義函數