天天看點

SQL Function 自定義函數

目錄

産生背景(已經有了存儲過程,為什麼還要使用自定義函數)

發展曆史

構成

使用方法

适用範圍

注意事項

疑問

内容

産生背景(已經有了存儲過程,為什麼還要使用自定義函數)

與存儲過程的差別(存在的意義):

1.     能夠在select等SQL語句中直接使用自定義函數,存儲過程不行。

2.     自定義函數可以調用其他函數,也可以調用自己(遞歸)

3.     可以在表列和 CHECK 限制中使用自定義函數來實作特殊列或限制

4.       自定義函數不能有任何副作用。函數副作用是指對具有函數外作用域(例如資料庫表的修改)的資源狀态的任何永久性更改。函數中的語句唯一能做的更改是對函數上的局部對象(如局部遊标或局部變量)的更改。不能在函數中執行的操作包括:對資料庫表的修改,對不在函數上的局部遊标進行操作,發送電子郵件,嘗試修改 目錄,以及生成傳回至使用者的結果集。存儲過程沒有此限制

5.       函數隻能傳回一個變量。而存儲過程可以傳回多個

發展曆史

SqlServer 2000之後都支援使用者自定義函數

構成

在SQL Server 2000 中根據函數傳回值形式的不同将使用者自定義函數分為三種類型:标量函數(Scalar Function)、内嵌表值函數(Inline Function)、多聲明表值函數(Multi-Statement Function)

标量函數:标量函數是對單一值操作,傳回單一值。能夠使用表達式的地方,就可以使用标量函數。像我們經常使用的left、getdate等,都屬于标量函數。系統函數中的标量函數包括:數學函數、日期和時間函數、字元串函數、資料類型轉換函數等

内嵌表值函數:内嵌表值函數的功能相當于一個參數化的視圖。它傳回的是一個表,内聯表值型函數沒有由BEGIN-END 語句括起來的函數體。其傳回的表由一個位于RETURN 子句中的SELECT 指令段從資料庫中篩選出來。

作用

多聲明表值函數:可以看作标量型和内嵌表值型函數的結合體。它的傳回值是一個表,但它和标量型函數一樣有一個用BEGIN-END 語句括起來的函數體,傳回值的表中的資料是由函數體中的語句插入的。由此可見,它可以進行多次查詢,對資料進行多次篩選與合并,彌補了内聯表值型函數的不足。

使用方法

SQL Server 為三種類型的使用者自定義函數 提供了不同的指令建立格式。

  (1) 建立标量型使用者自定義函數(Scalar functions) 其文法如下:

SQL Function 自定義函數

  各參數說明如下:

owner_name :指定使用者自定義函數的所有者。 

function_name:指定使用者自定義函數的名稱。database_name.owner_name.function_name 應是惟一的。 

@parameter_name:定義一個或多個參數的名稱。一個函數最多可以定義1024 個參數每個參數前用“@”符号标明。參數的作用範圍是整個函數。參數隻能替代常量,不能替代表 名、列名或其它資料庫對象的名稱。使用者自定義函數不支援輸出參數。  

scalar_parameter_data_type:指定标量型參數的資料類型,可以為除TEXT、 NTEXT、 IMAGE、 CURSOR、TIMESTAMP 和TABLE類型外的其它資料類型。  

scalar_return_data_type:指定标量型傳回值的資料類型,可以為除TEXT、 NTEXT、 IMAGE、 CURSOR、TIMESTAMP 和TABLE 類型外的其它資料類型。  

scalar_expression:指定标量型使用者自定義函數傳回的标量值表達式。 

function_body:指定一系列的Transact-SQL 語句,它們決定了函數的傳回值。  

ENCRYPTION:加密選項。讓SQL Server 對系統表中有關CREATE FUNCTION 的聲明加密,以防止使用者自定義函數作為SQL Server 複制的一部分被釋出(Publish) 。 

 SCHEMABINDING:計劃綁定選項将使用者自定義函數綁定到它所引用的資料庫對象如果指定 了此選項,則函數所涉及的資料庫對象從此将不能被删除或修改,除非函數被删除或去掉此選項。應注意的是,要綁定的資料庫對象必須與函數在同一資料庫中。  

SQL Function 自定義函數
SQL Function 自定義函數

  (2)建立内聯表值型使用者自定義函 數(Inline Table-valued Functions)

其文法如下:

SQL Function 自定義函數

  各參數說明如下:

TABLE:指定傳回值為一個表。

select-stmt:單個SELECT 語句,确定傳回的表的資料。

  其餘參數與标量型使用者自定義函數相同。

SQL Function 自定義函數
SQL Function 自定義函數

  (3) 建立多聲明表值型使用者自定義函數

其文法如下:

SQL Function 自定義函數

  各參數說明如下:

@return_variable :一個TABLE 類型的變量,用于存儲和累積傳回的表中的資料行。 其餘參數與标量型使用者自定義函數相同。

  在多聲明表值型使用者自定義函數的函數體中允許使用下列Transact-SQL 語句。 指派語句(Assignment statements); 流程控制語句(Control-of-Flow statements); 定義作用範圍在函數内的變量和 遊标的DECLARE 語句; SELECT 語句; 編輯函數中定義的表變量的INSERT、 UPDATE 和DELETE 語句; 在函數中允許涉及諸如聲明遊 标、打開遊标、關閉遊标、釋放遊标這樣的遊标操作,對于讀取遊标而言,除非在FETCH 語句中使用INTO 從句來對某一變量指派,否則不允許在函數中使用FETCH 語句來向用戶端傳回資料。此 外不确定性函數(Non-deterministic functions) 不能在使用者自定義函數中使 用。所謂不确定性函數是指那些使用相同的調用參數在不同時刻調用得到的傳回值不同的函數。這些函數如表13-3 所示(全局變量也可以視為一種函數)。

SQL Function 自定義函數
SQL Function 自定義函數
SQL Function 自定義函數

适用範圍

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後面不跟任何變量。

疑問:自定義函數不能修改資料庫,但它可以調用存儲過程,那麼在自定義函數中調用一個有修改資料庫的操作的存儲過程,這個自定義函數能不能執行?

答:自定義函數隻能調用擴充存儲過程,但是SQL Server 2008的後續版本将删除該功能,不再支援擴充存儲過程,是以應避免在開發中使用擴充存儲過程。是以,可以得出結論是:實際開發中,函數不會去調用存儲過程,也就無法對資料庫進行修改操作了。

參考:

http://technet.microsoft.com/zh-tw/library/ms186755.aspx

http://msdn.microsoft.com/zh-cn/library/ms175200.aspx

http://www.cnblogs.com/Athrun/archive/2007/07/27/833416.html

轉載:http://www.cnblogs.com/xueyuangudiao/archive/2011/08/03/2126580.html