2009-07-24 32 views
607

我一直在學習函數和存儲過程很長一段時間,但我不知道爲什麼以及何時應該使用函數或存儲過程。他們看起來和我一樣,也許是因爲我有點新手。函數與SQL Server中的存儲過程

有人能告訴我爲什麼嗎?

+2

http://venkatsqlinterview.blogspot.com/2011/05/what-is-difference-between-user-defined .html – Freelancer 2013-05-24 09:21:50

+0

http://wiki.answers.com/Q/What_is_difference_between_function_and_stored_procedure_in_sql_server – Freelancer 2013-05-24 09:22:10

+0

http://searchsqlserver.techtarget.com/tip/Stored-procedures-vs-functions – Freelancer 2013-05-24 09:22:36

回答

507

函數是計算值,不能對SQL Server執行永久環境更改(即不允許INSERT或UPDATE語句)。

函數可以在SQL語句中內聯使用,如果它返回標量值或可以在返回結果集時加入。

值得注意的一點從評論中總結了答案。由於@Seanķ安德森:

  • 功能按照該計算機sciency定義他們必須返回值,不能改變他們接受作爲參數 (參數)的數據。函數不允許改變任何東西,必須 至少有一個參數,並且它們必須返回一個值。存儲 procs不必具有參數,可以更改數據庫對象, 並且不必返回值。

+11

基本上不允許DML? – 2013-04-25 07:53:48

+122

函數遵循計算機的權限定義,它們必須返回一個值並且不能改變它們作爲參數(參數)接收到的數據。函數不允許改變任何東西,必須至少有一個參數,並且它們必須返回一個值。存儲過程不必具有參數,可以更改數據庫對象,也不必返回值。 – 2013-05-14 02:30:52

+16

事實上,您可以在函數中使用INSERT,UPDATE和DELETE語句來修改本地表變量。 – Ani 2014-03-27 07:39:28

52

時要計算並返回在其他SQL語句中使用的值寫用戶定義的函數;在你想要的時候編寫一個存儲過程,而不是將一組可能複雜的SQL語句分組。畢竟這是兩種截然不同的用例!

5

要決定何時使用何種以下幾點可能會幫助 -

  1. 存儲過程不能返回表變量,其中的功能可以做到這一點。

  2. 您可以使用存儲過程來更改服務器環境參數,其中使用不能使用的功能。

歡呼

18

一個用戶定義函數可用到SQL Server程序員的一個重要工具。您可以在SQL語句中內嵌使用它像這樣

SELECT a, lookupValue(b), c FROM customers 

其中lookupValue將是一個UDF。使用存儲過程時,這種功能是不可能的。同時你不能在UDF內部做某些事情。這裏要記住的基本的事情是,UDF的:

  • 不能創建永久更改
  • 不能改變數據

存儲過程可以做這些事情。

對我來說,UDF的內聯使用是UDF最重要的用法。

174

函數和存儲過程服務於不同的目的。雖然這不是最好的比喻,但函數可以從字面上看作任何其他編程語言中使用的函數,但存儲過程更像個別程序或批處理腳本。

功能通常具有輸出和可選輸入。然後,輸出可用作另一個函數(內置SQL Server,例如DATEDIFF,LEN等)的輸入或作爲SQL查詢的謂詞 - 例如SELECT a, b, dbo.MyFunction(c) FROM tableSELECT a, b, c FROM table WHERE a = dbo.MyFunc(c)

存儲過程用於在一個事務中將SQL查詢綁定在一起,並與外界交互。 ADO.NET等框架不能直接調用函數,但可以直接調用存儲過程。

功能確實有隱患,但:他們可能被誤用而造成相當惡劣的性能問題:考慮這個查詢:

SELECT * FROM dbo.MyTable WHERE col1 = dbo.MyFunction(col2) 

凡MyFunction的聲明爲:

CREATE FUNCTION MyFunction (@someValue INTEGER) RETURNS INTEGER 
AS 
BEGIN 
    DECLARE @retval INTEGER 

    SELECT localValue 
     FROM dbo.localToNationalMapTable 
     WHERE nationalValue = @someValue 

    RETURN @retval 
END 

這裏會發生什麼是表MyTable中的每一行都調用函數MyFunction。如果MyTable具有1000行,那麼對數據庫的另外1000個即席查詢。同樣,如果函數在column spec中被指定時被調用,那麼將爲SELECT返回的每一行調用該函數。

所以你確實需要小心編寫函數。如果你從一個函數的表中做SELECT,你需要問自己,在父存儲過程還是其他一些SQL構造(例如CASE ... WHEN ... ELSE ...結束)。

4

像遊標一樣,SQL Server函數是用來作爲最後一個武器的!它們確實存在性能問題,因此應儘可能地避免使用表值函數。談論性能是指在中級硬件服務器上託管超過1,000,000條記錄的表格;否則你不需要擔心功能造成的性能損失。

  1. 不要使用函數返回一個結果集到外部代碼(如ADO.Net)
  2. 使用視圖/存儲的特效組合儘可能。您可以使用DTA(數據庫優化顧問)爲您提供的建議(如索引視圖和統計信息) - 有時可以從未來的增長性能問題中恢復過來。

進一步參考見:http://databases.aspfaq.com/database/should-i-use-a-view-a-stored-procedure-or-a-user-defined-function.html

0
  • 函數可以在SELECT語句中作爲其中的程序無法使用。

  • 存儲過程同時接受輸入和輸出參數,但函數僅接受輸入參數。

  • 函數無法返回類型爲text,ntext,image的值& timestamps其中as過程可以。

  • 函數可以在create table中用作用戶定義的數據類型,但程序不能。

***例如:-create table <tablename>(name varchar(10),salary getsal(name))

這裏getsal是用戶定義的函數返回一個薪水類型,創建表時沒有存儲被分配用於薪金類型,getsal功能也是不但是當我們從這個表中獲取一些值時,gets函數get會被執行,並且返回類型作爲結果集返回。

416

SP和UDF下面列出的區別:

​​
47

存儲過程和用戶​​定義的函數之間的差異:

  • 存儲過程不能在選擇語句中使用。
  • 存儲過程支持延遲名稱解析。
  • 存儲過程通常用於執行業務邏輯。
  • 存儲過程可以返回任何數據類型。
  • 存儲過程可以接受比用戶定義的功能更多的輸入參數。存儲過程最多可以有21,000個輸入參數。
  • 存儲過程可以執行動態SQL。
  • 存儲過程支持錯誤處理。
  • 非確定性函數可用於存儲過程。

  • 用戶定義的函數可以在選擇語句中使用。
  • 用戶定義的函數不支持延遲名稱解析。
  • 用戶定義的函數通常用於計算。
  • 用戶定義的函數應該返回一個值。
  • 用戶定義的函數不能返回圖像。
  • 用戶定義的函數接受比存儲過程更少數量的輸入參數。 UDF最多可以有1,023個輸入參數。
  • 臨時表格不能用於用戶定義的功能。
  • 用戶定義的函數不能執行動態SQL。
  • 用戶定義的函數不支持錯誤處理。 UDF中不允許使用RAISEERROR@@ERROR
  • 非確定性函數不能在UDF中使用。例如,GETDATE()不能用於UDF。
2

以返回單個值的函數開始。好的是,您可以將經常使用的代碼放入函數中,並將它們作爲結果集中的列返回。

然後,您可以使用一個函數作爲參數化的城市列表。 dbo.GetCitiesIn(「NY」)返回一個可以用作連接的表。

這是一種組織代碼的方式。知道何時可重複使用以及何時浪費時間只能通過反覆試驗和經驗來獲得。

此外,函數是SQL Server中的一個好主意。它們速度更快,而且可以非常強大。內聯和直接選擇。小心不要過度使用。

1
  • 函數返回一個值,而不是存儲過程是強制性的。
  • 僅在UDF中接受選擇語句,而不需要DML語句。
  • 存儲過程接受任何語句以及DML語句。
  • UDF只允許輸入而不允許輸出。
  • 存儲過程允許輸入和輸出。
  • 捕獲塊不能在UDF中使用,但可以在存儲過程中使用。
  • 在UDF中的函數中不允許交易,但在存儲過程中允許它們。
  • 只有表變量可以用於UDF而不是臨時表。
  • 存儲過程允許表變量和臨時表。
  • UDF不允許從函數調用存儲過程,而存儲過程允許調用函數。
  • UDF用於連接子句中,而存儲過程不能用於連接子句中。
  • 存儲過程將始終允許歸零。相反,UDF具有必須回到預定點的價值。
17

根本差異

函數必須返回一個值,但在存儲過程是可選的(程序可以返回零或正的值)。

函數只能有輸入參數,而程序可以有輸入/輸出參數。

函數採用一個輸入參數是強制性的,但存儲過程可能需要O與N的輸入參數..

函數可以從程序被調用,而程序不能從函數調用。

推進差異

程序允許選擇和DML(INSERT/UPDATE/DELETE)在其聲明中,而功能只允許SELECT語句中它。

程序不能在SELECT語句中使用,而函數可以嵌入在SELECT語句中。

存儲過程不能用於WHERE/HAVING/SELECT部分​​中任何位置的SQL語句,而Function可以。

返回表的函數可以視爲另一個行集。這可以在與其他表的JOIN中使用。

內聯函數可以作爲視圖的參數,並且可以在JOIN和其他行集操作中使用。

異常可以通過一個過程中的try-catch塊來處理,而try-catch塊不能在函數中使用。

我們可以在程序中進行事務管理,但我們不能進入函數。

source

4

存儲過程:

  • 就像SQL Server的一個縮影程序。
  • 可以像選擇語句一樣簡單,也可以像添加,刪除,更新和/或讀取數據庫中多個表中的數據的長 腳本一樣複雜。
  • (可實現循環和遊標,都允許您與 較小的結果工作或數據按行操作行。)
  • 應該使用EXECEXECUTE語句來調用。
  • 返回表變量,但我們不能使用OUT參數。
  • 支持交易。

功能:

  • 不能用於更新,刪除或添加記錄到數據庫中。
  • 只需返回單個值或表格值。
  • 只能用於選擇記錄。但是,它可以從標準的SQL內調用 非常容易,如:

    SELECT dbo.functionname('Parameter1') 
    

    SELECT Name, dbo.Functionname('Parameter1') FROM sysObjects 
    
  • 對於簡單的可重複使用的選擇的操作,功能可以簡化代碼。 只是在你的函數中使用JOIN子句時要小心。如果您 函數有一個JOIN條款,並從另一個選擇 語句返回多個結果調用它,函數調用JOIN 這些表一起每個線在結果集返回。所以 儘管它們可以有助於簡化某些邏輯,但如果它們使用不當,它們也可能會成爲一個 性能瓶頸。

  • 使用OUT參數返回值。
  • 不支持交易。
-1

存儲過程和用戶​​之間的差異定義函數

enter image description here

12

存儲過程被用作腳本。他們爲您運行一系列命令,您可以安排它們在特定時間運行。

功能被用作方法。你傳遞一些東西並返回結果。應該小而快 - 在飛行中進行。

-2

在SQL Server中,函數和存儲過程是兩種不同類型的實體。

功能:在SQL Server數據庫中,函數用於執行某些操作,並且操作立即返回結果。 功能有兩種類型:

  1. 系統定義

  2. 用戶自定義

存儲過程:在SQL Server中,存儲過程都存儲在服務器它可以返回零,單個和多個值。 存儲過程有兩種類型:

  1. 系統存儲過程
  2. 用戶定義的過程
0

這裏有一個實際的理由,更喜歡在存儲過程的功能。如果您有一個需要另一個存儲過程的結果的存儲過程,則必須使用insert-exec語句。這意味着您必須創建臨時表並使用exec語句將存儲過程的結果插入到臨時表中。這很混亂。與此有關的一個問題是insert-execs cannot be nested

如果您遇到調用其他存儲過程的存儲過程,您可能會遇到這種情況。如果嵌套存儲過程只是簡單地返回一個數據集,那麼它可以用一個表值函數替換,而不會再出現這個錯誤。

這是另一個原因,我們應該保持業務邏輯出了數據庫)的