預存程序是將常用 T-SQL 邏輯封裝在資料庫端的強大工具,能減少網路往返、提升效能並強化安全性。本文透過五個層層遞進的實例,涵蓋無參數查詢、輸入/輸出參數、加密、多表聯查、萬用字元查詢等核心技巧。
bankMoney| Id | userID | Sex | Money |
|---|---|---|---|
| 001 | Zhangsan | 男 | 30 |
| 002 | Wangwu | 男 | 50 |
| 003 | Zhangsan | 男 | 40 |
CREATE PROCEDURE sp_query_bankMoney
AS
SELECT * FROM bankMoney;
GO
EXEC sp_query_bankMoney;
應用端只需呼叫程序名稱,SQL 細節完全封裝於資料庫端。
需求:新增一筆存款,並回傳指定用戶的總餘額。
CREATE PROC insert_bank
@param1 CHAR(10), -- id
@param2 VARCHAR(20), -- userID
@param3 VARCHAR(20), -- sex
@param4 INT, -- Money
@param5 INT OUTPUT -- 總餘額輸出
WITH ENCRYPTION -- 加密程序定義
AS
INSERT INTO bankMoney (id, userID, sex, Money)
VALUES (@param1, @param2, @param3, @param4);
SELECT @param5 = SUM(Money) FROM bankMoney WHERE userID = 'Zhangsan';
GO
DECLARE @total_price INT;
EXEC insert_bank '004', 'Zhangsan', '男', 100, @total_price OUTPUT;
PRINT '總餘額為 ' + CAST(@total_price AS VARCHAR);
GO
| 機制 | 資料型別 | 接收端 | 適用場景 |
|---|---|---|---|
| RETURN | INT | 批次變數 | 狀態碼、錯誤代碼 |
| OUTPUT 參數 | 任意純量型別 | 批次變數 | 單一計算結果、旗標 |
| RESULT SET | 資料集 | 用戶端(應用程式) | 查詢結果、報表資料 |
USE pubs;
GO
IF EXISTS (SELECT * FROM sysobjects WHERE name = 'au_info_all' AND type = 'P')
DROP PROCEDURE au_info_all;
GO
CREATE PROCEDURE au_info_all
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors a
INNER JOIN titleauthor ta ON a.au_id = ta.au_id
INNER JOIN titles t ON t.title_id = ta.title_id
INNER JOIN publishers p ON t.pub_id = p.pub_id;
GO
EXECUTE au_info_all;
CREATE PROCEDURE au_info
@lastname VARCHAR(40),
@firstname VARCHAR(20)
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors a
INNER JOIN titleauthor ta ON a.au_id = ta.au_id
INNER JOIN titles t ON t.title_id = ta.title_id
INNER JOIN publishers p ON t.pub_id = p.pub_id
WHERE au_fname = @firstname
AND au_lname = @lastname;
GO
-- 三種等價呼叫
EXECUTE au_info 'Dull', 'Ann';
EXECUTE au_info @lastname = 'Dull', @firstname = 'Ann';
EXECUTE au_info @firstname = 'Ann', @lastname = 'Dull';
CREATE PROCEDURE au_info2
@lastname VARCHAR(30) = 'D%', -- 預設值含萬用字元
@firstname VARCHAR(18) = '%'
AS
SELECT au_lname, au_fname, title, pub_name
FROM authors a
INNER JOIN titleauthor ta ON a.au_id = ta.au_id
INNER JOIN titles t ON t.title_id = ta.title_id
INNER JOIN publishers p ON t.pub_id = p.pub_id
WHERE au_fname LIKE @firstname
AND au_lname LIKE @lastname;
GO
-- 多種呼叫組合
EXECUTE au_info2; -- 全部
EXECUTE au_info2 'Wh%'; -- 姓氏 Wh 開頭
EXECUTE au_info2 @firstname = 'A%'; -- 名字 A 開頭
EXECUTE au_info2 '[CK]ars[OE]n'; -- 正則樣式
EXECUTE au_info2 'Hunter', 'Sheryl'; -- 精確比對
EXECUTE au_info2 'H%', 'S%'; -- 雙邊前綴
EXECUTE 權限,不直接給資料表權限。CREATE/ALTER PROCEDURE 腳本納入原始碼管理。