1. 程式人生 > >SQL Server 自定義函數

SQL Server 自定義函數

alt 數據 null 種類 sql 定義 arc itl 參數化

簡介

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 自定義函數