將常用或複雜的 T-SQL 邏輯預先編譯、以指定名稱儲存在資料庫中,呼叫時僅需 `EXEC 程序名` 即可執行。核心優勢:
| 類型 | 前綴 | 用途 |
|---|---|---|
| 系統預存程序 | sp_ | 系統設定、資訊查詢、管理工作 (如 `sp_help`) |
| 擴展預存程序 | xp_ | 呼叫作業系統功能 (如 `xp_cmdshell 'ping 10.8.16.1'`) |
| 使用者自訂預存程序 | 無固定前綴 | 業務邏輯核心 (本文重點) |
CREATE PROCEDURE procedure_name
@parameter data_type [OUTPUT]
[WITH {RECOMPILE | ENCRYPTION}]
AS
BEGIN
sql_statement
END;
OUTPUT:標記輸出參數,呼叫端可接收回傳值。WITH RECOMPILE:每次執行重新編譯,適用參數嗅探導致計畫不穩定情境。WITH ENCRYPTION:加密程序定義,隱藏原始碼 (非高強度加密)。| 機制 | 資料類型 | 接收方式 |
|---|---|---|
| RETURN | INT | 批次腳本中用變數接收 |
| OUTPUT 參數 | 任意純量類型 | 批次腳本中用變數接收 |
| Resultset | 資料集 | 用戶端應用程式接收 (ADO.NET SqlDataReader 等) |
CREATE PROC query_book
AS
SELECT * FROM book;
GO
EXEC query_book;
CREATE PROC insert_book
@id CHAR(10),
@title VARCHAR(20),
@price MONEY,
@total_price MONEY OUTPUT
WITH ENCRYPTION
AS
BEGIN
INSERT INTO book(編號, 書名, 價格) VALUES (@id, @title, @price);
SELECT @total_price = SUM(價格) FROM book;
END;
GO
-- 呼叫範例
DECLARE @total MONEY;
EXEC insert_book '003', 'Delphi 控件開發指南', 100, @total OUTPUT;
PRINT '總金額為 ' + CAST(@total AS VARCHAR);
CREATE PROC temp_sale
AS
BEGIN
SELECT a.產品編號, a.產品名稱, b.客戶名, b.客戶訂金,
a.客戶訂數 * b.客戶訂金 AS 總金額
INTO #temptable
FROM Product a INNER JOIN [Order] b ON a.產品編號 = b.產品編號;
IF @@ERROR = 0
PRINT 'Good';
ELSE
PRINT 'Fail';
END;
GO
BEGIN TRY
BEGIN TRAN;
-- 多步驟操作
COMMIT TRAN;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK TRAN;
-- 記錄錯誤資訊 ERROR_NUMBER(), ERROR_MESSAGE() 等
RAISERROR(...);
END CATCH;
GRANT EXEC ON dbo.insert_book TO [AppUser];
DENY SELECT ON dbo.book TO [AppUser]; -- 僅能透過程序存取
預存程序是 SQL Server 封裝業務邏輯、強化安全性與提升效能的核心機制。掌握參數設計、輸出機制、動態 SQL 安全用法、交易錯誤處理與權限控制,能構建健壯且可維護的資料存取層。