系統性整理 T-SQL 預存程序核心知識:概念優勢、系統預存程序常用清單、使用者程序完整語法變體(無參、輸入/輸出參數、預設值、通配符、加密、重新編譯、游標參數、分頁),以及 RAISERROR 進階用法。
EXEC proc_name params,而非完整 T-SQL 批次。EXECUTE 權限而非底層物件權限,實現資料存取控制與封裝。| 程序 | 功能 |
|---|---|
sp_databases | 列出所有資料庫 |
sp_tables | 列出資料表/檢視表 |
sp_columns 'table' | 列出資料行定義 |
sp_helpindex 'table' | 列出索引資訊 |
sp_helpconstraint 'table' | 列出約束條件 |
sp_rename 'old', 'new' | 重命名表/索引/欄位 |
sp_renamedb 'old', 'new' | 重命名資料庫 |
sp_helptext 'proc' | 檢視程序定義(支援系統物件) |
sp_helpdb | 資料庫詳細資訊 |
系統程序儲於 master,以 sp_ 開頭,所有資料庫可直接呼叫。
CREATE PROC proc_name [@param type = default [OUTPUT]] ... AS sql_statements;
ALTER PROC proc_name ... AS ...;
DROP PROC IF EXISTS proc_name;
CREATE PROC proc_get_student AS SELECT * FROM student;
CREATE PROC proc_find_stu @startId INT = 1, @endId INT = 100
AS SELECT * FROM student WHERE id BETWEEN @startId AND @endId;
CREATE PROC proc_get_info @id INT, @name VARCHAR(20) OUTPUT, @age INT OUT
AS SELECT @name = name, @age = age FROM student WHERE id = @id;
呼叫端:DECLARE @n VARCHAR(20), @a INT; EXEC proc_get_info 1, @n OUT, @a OUT;
CREATE PROC proc_find_name @name VARCHAR(20) = '%j%', @next VARCHAR(20) = '%'
AS SELECT * FROM student WHERE name LIKE @name AND name LIKE @next;
CREATE PROC proc_dynamic WITH RECOMPILE AS SELECT * FROM student WHERE ...;
適用參數敏感度極高、計畫重用反而有害的情境。
CREATE PROC proc_secret WITH ENCRYPTION AS SELECT * FROM student;
sp_helptext 將回傳加密提示,**無法反編譯**,原始碼請自行版控管理。
CREATE PROC proc_cursor @cur CURSOR VARYING OUTPUT AS
BEGIN
SET @cur = CURSOR FORWARD_ONLY STATIC FOR SELECT id, name, age FROM student;
OPEN @cur;
END;
-- 呼叫端
DECLARE @c CURSOR, @id INT, @name VARCHAR(20), @age INT;
EXEC proc_cursor @cur = @c OUTPUT;
FETCH NEXT FROM @c INTO @id, @name, @age;
WHILE @@FETCH_STATUS = 0 BEGIN ... FETCH NEXT ... END
CLOSE @c; DEALLOCATE @c;
CREATE PROC proc_page @pageIndex INT, @pageSize INT AS
BEGIN
DECLARE @startRow INT = (@pageIndex - 1) * @pageSize + 1;
DECLARE @endRow INT = @startRow + @pageSize - 1;
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS rn FROM student
) t WHERE t.rn BETWEEN @startRow AND @endRow;
END;
RAISERROR ({msg_id | msg_str | @var}, severity, state [, args...] ) [WITH option...]
msg_id:sys.messages 登錄訊息 ID(自訂 ≥ 50000)。severity:0-10 資訊/警告(不進 CATCH);11-19 使用者錯誤(進 CATCH);20-25 系統嚴重錯誤(需 WITH LOG、sysadmin)。state:1-127,區分同一錯誤不同拋出點。WITH LOG:寫入 SQL/Windows 錯誤記錄檔。WITH NOWAIT:立即送達用戶端(進度回報)。範例:RAISERROR(33003, 16, 1); 使用系統訊息;RAISERROR('Custom error', 16, 1); 直接字串。
預存程序是 SQL Server 伺服器端邏輯封裝的核心單元。掌握參數模式(INPUT/OUTPUT/DEFAULT/READONLY TVP)、計畫快取控制(RECOMPILE)、安全封裝(ENCRYPTION/EXECUTE 權限)、分頁標準寫法,能構建高效能、可維護、安全的資料存取層。