您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“SQL Server怎么創建用戶定義函數”,內容詳細,步驟清晰,細節處理妥當,希望這篇“SQL Server怎么創建用戶定義函數”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
和存儲過程很相似,用戶自定義函數也是一組有序的T-SQL語句,UDF被預先優化和編譯并且可以作為一個單元來進行調用。
UDF和存儲過程的主要區別在于返回結果的方式:
使用UDF時可傳入參數,但不可傳出參數。輸出參數的概念被更為健壯的返回值取代了。
和系統函數一樣,可以返回標量值,這個值的好處是它并不像在存儲過程中那樣只限于整形數據類型,而是可以返回大多數SQL Server數據類型。
UDF有以下兩種類型:
返回標量值的UDF。
返回表的UDF。
創建語法:
CREATE FUNCTION [<schema name>.]<function name> ( [ <@parameter name> [AS] [<schema name>.]<data type> [= <default value> [READONLY]] [,...n] ] ) RETURNS { <scalar type> | TABLE [(<table definition>)] } [ WITH [ENCRYPTION] | [SCHEMABINDING] | [RETURNS NULL ON NULL INPUT | CALLED ON NULL INPUT ] | [EXECUTE AS {CALLER|SELF|OWNER|<'user name'>}] [AS] { EXTERNAL NAME <externam method> | BEGIN [<function statements>] {RETURN <type as defined in RETURNS clause | RETURN (<SELECT statement>)} END}[;]
這種類型的UDF和大多數SQL Server內置函數一樣,會向調用腳本或存儲過程返回標量值,像GETDATE()或USER()函數就會返回標量值。
UDF的返回值并不限于整數,而是可以返回除了BLOB、游標(cursor)和時間戳以外的任何有效的SQL Server數據類型(包括用戶自定義類型)。
與存儲過程不同,用戶自定義函數返回值的目的是提供有意義的數據(而對于存儲過程來說,返回值只能說明成功或失敗,如果失敗,則會提供一些關于失敗性質的特定信息。)
可在查詢中內聯執行函數(如作為SELECT語句的一部分),而用存儲過程則不行。
CREATE FUNCTION DateOnly(@Date DateTime) RETURNS varchar(12) AS BEGIN RETURN CONVERT(varchar(12),@Date,102) END
然后試著,運用一下:
SELECT * FROM Nx_comment WHERE dbo.DateOnly(com_posttime) = '2012.04.28' --注意前面的dbo是必須的。
其實以上SQL語句相當于:
SELECT * FROM Nx_comment WHERE CONVERT(varchar(12),com_posttime,102) = '2012.04.28'
SELECT Name,Age, (SELECT AVG(Age) FROM Person) AS AvgAge, Age - (SELECT AVG(Age) FROM Person) AS Difference FROM Person
這里要說明一下,列的意思分別是,姓名,年齡,平均年齡以及與平均年齡的差值。
下面我們用UDF來實現,先定義兩個UDF如下:
CREATE FUNCTION dbo.AvgAge() RETURNS int AS BEGIN RETURN (SELECT AVG(Age) FROM Person) END GO CREATE FUNCTION dbo.AgeDifference(@Age int) RETURNS int AS BEGIN RETURN @Age - dbo.AvgAge(); --在一個UDF內引用另外一個UDF,好華麗的說 END
然后執行查詢:
SELECT Name,Age,dbo.AvgAge() AS AvgAge,dbo.AgeDifference(Age) as Difference FROM Person
SQL Server中的用戶自定義函數并不只限于返回標量值,也可以返回表。返回的表在很大程度上和其他表是一樣的。
可以對返回 表的UDF執行JOIN,甚至對結果應用WHERE條件。
改為用表作為返回值并不難,對于UDF來說,表就像任何其他SQL Server數據類型一樣。
CREATE FUNCTION dbo.fnContactName() RETURNS TABLE AS RETURN ( SELECT Id,LastName + ',' + FirstName AS Name FROM Man )
然后我們就可以像表一樣地用UDF了。
SELECT * FROM dbo.fnContactName()
CREATE FUNCTION dbo.fnNameLike(@LName varchar(20)) RETURNS TABLE AS RETURN ( SELECT Id,LastName + ',' + FirstName AS Name FROM Man WHERE LastName Like @LName + '%' )
然后查詢的時候可以這樣用:
SELECT * FROM dbo.fnNameLike('劉')
沒有WHERE子句,沒有過濾SELECT列表,就可以反復使用該函數,而不需要進行"剪切和粘貼"。
語法:
CREATE FUNCTION Funtion_name ( --這里定義傳入參數及類型 ) RETURNS @table_name TABLE ( --這里定義@table_name的列名 ) AS BEGIN --這里寫sql語句并且將最終需要返回的結果集塞到@table_name 這張表里面 RETURN END GO
這個函數通過傳入一個十進制的數字,分別返回對應的二進制、八進制、十六進制。
Create FUNCTION F_TConversion ( @NUM INT ) RETURNS @t_table TABLE ( [Binary] varchar(64), Octal varchar(16), Hexadecimal varchar(8) ) AS BEGIN DECLARE @RESULT2 VARCHAR(500)='',@RESULT8 VARCHAR(500)='',@RESULT16 VARCHAR(500)=''; WITH CTE AS( SELECT @NUM/2 D2,@NUM%2 S2,@NUM/8 D8,@NUM%8 S8,@NUM/16 D16,@NUM%16 S16,1 [INDEX] UNION ALL SELECT D2/2 , D2%2,D8/8 , D8%8,D16/16 , D16%16,[INDEX]+1 FROM CTE WHERE D2>0 ) SELECT @RESULT2+=CAST(S2 AS VARCHAR(1)) ,@RESULT8+=CASE WHEN D8=0 AND S8=0 THEN '' ELSE CAST(S8 AS VARCHAR(1)) END ,@RESULT16+=CASE WHEN D16=0 AND S16=0 THEN '' ELSE CASE CAST(S16 AS VARCHAR(5)) WHEN '10' THEN 'A' WHEN '11' THEN 'B' WHEN '12' THEN 'C' WHEN '13' THEN 'D' WHEN '14' THEN 'E' WHEN '15' THEN 'F' ELSE CAST(S16 AS VARCHAR(5)) END END FROM CTE ORDER BY [INDEX] DESC INSERT INTO @t_table SELECT @RESULT2,@RESULT8,@RESULT16 RETURN END GO
用戶自定義函數可以是確定性的也可以是非確定性的。如果給定了一組特定的有效輸入,每次函數就都能返回相同的結果,那么就說該函數是確定性的。
SUM()就是一個確定性的內置函數。3、5、10的總合永遠都是18,而GETDATE()的值就是非確定性的,因為每次調用它的時候GETDATE()都會改變。
如果視圖或計算列引用非確定性函數,則在該視圖或列上將不允許建立任何索引。
如果判定函數是否是確定性的?除了上面描述的規則外,這些信息存儲在對象的IsDeterministic屬性中,可以利用OBJECTPROPERTY屬性檢查。
SELECT OBJECTPROPERTY(OBJECT_ID('DateOnly'),'IsDeterministic'); --只是剛才的那個自定義函數
輸出結果如下:
居然是非確定性的。原因在于之前在定義該函數的時候,并沒有加上這個"WITH SCHEMABINDING"。
ALTER FUNCTION dbo.DateOnly(@Date date) RETURNS date WITH SCHEMABINDING --當我們加上這一句之后 AS BEGIN RETURN @Date END
在執行查詢,該函數就是確定性的了。
讀到這里,這篇“SQL Server怎么創建用戶定義函數”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。