觸發(fā)器是特殊的存儲過程,存儲過程需要程序調用,而觸發(fā)器會自動執(zhí)行;你所說的函數(shù)是自定義函數(shù)吧,函數(shù)是根據輸入產生輸出,自定義只不過輸入輸出的關系由用戶來定義。在什么時候用觸發(fā)器?要求系統(tǒng)根據某些操作自動完成相關任務,比如,根據買掉的產品的輸入數(shù)量自動扣除該產品的庫存量。什么時候用存儲過程?存儲過程就是程序,它是經過語法檢查和編譯的SQL語句,所以運行特別快。
存儲過程和用戶自定義函數(shù)具體的區(qū)別
先看定義:
存儲過程
存儲過程可以使得對數(shù)據庫的管理、以及顯示關于數(shù)據庫及其用戶信息的工作容易得多。存儲過程是 SQL 語句和可選控制流語句的預編譯集合,以一個名稱存儲并作為一個單元處理。存儲過程存儲在數(shù)據庫內,可由應用程序通過一個調用執(zhí)行,而且允許用戶聲明變量、有條件執(zhí)行以及其它強大的編程功能。
存儲過程可包含程序流、邏輯以及對數(shù)據庫的查詢。它們可以接受參數(shù)、輸出參數(shù)、返回單個或多個結果集以及返回值。
可以出于任何使用 SQL 語句的目的來使用存儲過程,它具有以下優(yōu)點:
· 可以在單個存儲過程中執(zhí)行一系列 SQL 語句。
· 可以從自己的存儲過程內引用其它存儲過程,這可以簡化一系列復雜語句。
· 存儲過程在創(chuàng)建時即在服務器上進行編譯,所以執(zhí)行起來比單個 SQL 語句快。
用戶定義函數(shù)
函數(shù)是由一個或多個 Transact-SQL 語句組成的子程序,可用于封裝代碼以便重新使用。Microsoft? SQL Server? 2000 并不將用戶限制在定義為 Transact-SQL 語言一部分的內置函數(shù)上,而是允許用戶創(chuàng)建自己的用戶定義函數(shù)。
可使用 CREATE FUNCTION 語句創(chuàng)建、使用 ALTER FUNCTION 語句修改、以及使用 DROP FUNCTION 語句除去用戶定義函數(shù)。每個完全合法的用戶定義函數(shù)名 (database_name.owner_name.function_name) 必須唯一。
必須被授予 CREATE FUNCTION 權限才能創(chuàng)建、修改或除去用戶定義函數(shù)。不是所有者的用戶在 Transact-SQL 語句中使用某個函數(shù)之前,必須先給此用戶授予該函數(shù)的適當權限。若要創(chuàng)建或更改在 CHECK 約束、DEFAULT 子句或計算列定義中引用用戶定義函數(shù)的表,還必須具有函數(shù)的 REFERENCES 權限。
在函數(shù)中,區(qū)別處理導致刪除語句并且繼續(xù)在諸如觸發(fā)器或存儲過程等模式中的下一語句的 Transact-SQL 錯誤。在函數(shù)中,上述錯誤會導致停止執(zhí)行函數(shù)。接下來該操作導致停止喚醒調用該函數(shù)的語句。
用戶定義函數(shù)的類型
SQL Server 2000 支持三種用戶定義函數(shù):
· 標量函數(shù)
· 內嵌表值函數(shù)
· 多語句表值函數(shù)
用戶定義函數(shù)采用零個或更多的輸入參數(shù)并返回標量值或表。函數(shù)最多可以有 1024 個輸入參數(shù)。當函數(shù)的參數(shù)有默認值時,調用該函數(shù)時必須指定默認 DEFAULT 關鍵字才能獲取默認值。該行為不同于在存儲過程中含有默認值的參數(shù),而在這些存儲過程中省略該函數(shù)也意味著省略默認值。用戶定義函數(shù)不支持輸出參數(shù)。
標量函數(shù)返回在 RETURNS 子句中定義的類型的單個數(shù)據值??梢允褂盟袠肆繑?shù)據類型,包括bigint和sql_variant。不支持timestamp數(shù)據類型、用戶定義數(shù)據類型和非標量類型(如table或cursor)。在 BEGIN...END 塊中定義的函數(shù)主體包含返回該值的 Transact-SQL 語句系列。返回類型可以是除text、ntext、image、cursor和timestamp之外的任何數(shù)據類型。
表值函數(shù)返回table。對于內嵌表值函數(shù),沒有函數(shù)主體;表是單個 SELECT 語句的結果集。對于多語句表值函數(shù),在 BEGIN...END 塊中定義的函數(shù)主體包含 TRANSACT-SQL 語句,這些語句可生成行并將行插入將返回的表中。有關內嵌表值函數(shù)的更多信息,請參見內嵌用戶定義函數(shù)。有關表值函數(shù)的更多信息,請參見返回 table 數(shù)據類型的用戶定義函數(shù)。
BEGIN...END 塊中的語句不能有任何副作用。函數(shù)副作用是指對具有函數(shù)外作用域(例如數(shù)據庫表的修改)的資源狀態(tài)的任何永久性更改。函數(shù)中的語句唯一能做的更改是對函數(shù)上的局部對象(如局部游標或局部變量)的更改。不能在函數(shù)中執(zhí)行的操作包括:對數(shù)據庫表的修改,對不在函數(shù)上的局部游標進行操作,發(fā)送電子郵件,嘗試修改目錄,以及生成返回至用戶的結果集。
函數(shù)中的有效語句類型包括:
· DECLARE 語句,該語句可用于定義函數(shù)局部的數(shù)據變量和游標。
· 為函數(shù)局部對象賦值,如使用 SET 給標量和表局部變量賦值。
· 游標操作,該操作引用在函數(shù)中聲明、打開、關閉和釋放的局部游標。不允許使用 FETCH 語句將數(shù)據返回到客戶端。僅允許使用 FETCH 語句通過 INTO 子句給局部變量賦值。
· 控制流語句。
· SELECT 語句,該語句包含帶有表達式的選擇列表,其中的表達式將值賦予函數(shù)的局部變量。
· INSERT、UPDATE 和 DELETE 語句,這些語句修改函數(shù)的局部table變量。
· EXECUTE 語句,該語句調用擴展存儲過程。
在查詢中指定的函數(shù)的實際執(zhí)行次數(shù)在優(yōu)化器生成的執(zhí)行計劃間可能不同。示例為 WHERE 子句中的子查詢喚醒調用的函數(shù)。子查詢及其函數(shù)執(zhí)行的次數(shù)會因優(yōu)化器選擇的訪問路徑而異。
用戶定義函數(shù)中不允許使用會對每個調用返回不同數(shù)據的內置函數(shù)。用戶定義函數(shù)中不允許使用以下內置函數(shù):
@@CONNECTIONS
@@PACK_SENT
GETDATE
@@CPU_BUSY
@@PACKET_ERRORS
GetUTCDate
@@IDLE
@@TIMETICKS
NEWID
@@IO_BUSY
@@TOTAL_ERRORS
RAND
@@MAX_CONNECTIONS
@@TOTAL_READ
TEXTPTR
@@PACK_RECEIVED
@@TOTAL_WRITE
架構綁定函數(shù)
CREATE FUNCTION 支持 SCHEMABINDING 子句,后者可將函數(shù)綁定到它引用的任何對象(如表、視圖和其它用戶定義函數(shù))的架構。嘗試對架構綁定函數(shù)所引用的任何對象執(zhí)行 ALTER 或 DROP 都將失敗。
必須滿足以下條件才能在 CREATE FUNCTION 中指定 SCHEMABINDING:
· 該函數(shù)所引用的所有視圖和用戶定義函數(shù)必須是綁定到架構的。
· 該函數(shù)所引用的所有對象必須與函數(shù)位于同一數(shù)據庫中。必須使用由一部分或兩部分構成的名稱來引用對象。
· 必須具有對該函數(shù)中引用的所有對象(表、視圖和用戶定義函數(shù))的 REFERENCES 權限。
可使用 ALTER FUNCTION 刪除架構綁定。ALTER FUNCTION 語句將通過不帶 WITH SCHEMABINDING 指定函數(shù)來重新定義函數(shù)。
調用用戶定義函數(shù)
當調用標量用戶定義函數(shù)時,必須提供至少由兩部分組成的名稱:
SELECT *, MyUser.MyScalarFunction()FROM MyTable
可以使用一個部分構成的名稱調用表值函數(shù):
SELECT *FROM MyTableFunction()
然而,當調用返回表的 SQL Server 內置函數(shù)時,必須將前綴 :: 添加至函數(shù)名:
SELECT * FROM ::fn_helpcollations()
可在 Transact-SQL 語句中所允許的函數(shù)返回的相同數(shù)據類型表達式所在的任何位置引用標量函數(shù),包括計算列和 CHECK 約束定義。例如,下面的語句創(chuàng)建一個返回 decimal 的簡單函數(shù):
CREATE FUNCTION CubicVolume-- Input dimensions in centimeters (@CubeLength decimal(4,1), @CubeWidth decimal(4,1), @CubeHeight decimal(4,1) )RETURNS decimal(12,3) -- Cubic Centimeters.ASBEGIN RETURN ( @CubeLength * @CubeWidth * @CubeHeight )END
然后可以在允許整型表達式的任何地方(如表的計算列中)使用該函數(shù):
CREATE TABLE Bricks ( BrickPartNmbr int PRIMARY KEY, BrickColor nchar(20), BrickHeight decimal(4,1), BrickLength decimal(4,1), BrickWidth decimal(4,1), BrickVolume AS ( dbo.CubicVolume(BrickHeight, BrickLength, BrickWidth) ) )
dbo.CubicVolume 是返回標量值的用戶定義函數(shù)的一個示例。RETURNS 子句定義由該函數(shù)返回的值的標量數(shù)據類型。BEGIN...END 塊包含一個或多個執(zhí)行該函數(shù)的 Transact-SQL 語句。該函數(shù)中的每個 RETURN 語句都必須具有一個參數(shù),可返回具有在 RETURNS 子句中指定的數(shù)據類型(或可隱性轉換為 RETURNS 中指定類型的數(shù)據類型)的數(shù)據值。RETURN 參數(shù)的值是該函數(shù)返回的值。