預存程序 是一組預先編譯、儲存在資料庫伺服器端的 SQL 與流程控制語句集合,透過特定名稱調用。它不只是「一堆 SQL」,而是**封裝業務邏輯、減少網路交互、提升效能、強化安全**的核心資料庫程式設計單元。
COMMIT/ROLLBACK 保證 ACID,簡化應用端錯誤處理。EXECUTE ON PROCEDURE 權限而非底層表 INSERT/UPDATE 權限,實現「最小權限原則」,防 SQL 注入。| 類型 | 前綴 | 用途 | 範例 |
|---|---|---|---|
| 系統預存程序 | SP_ | 系統配置、資訊查詢、管理任務 | SP_HELP, SP_TABLES |
| 擴展預存程序 | XP_ | 呼叫作業系統功能 (需高權限,慎用) | XP_CMDSHELL 'ping 192.168.1.1' |
| 使用者自定義 | 無固定前綴 | **業務邏輯核心**,我們開發的重點 | PROC_CALC_MONTHLY_SALES |
註:SP_/XP_ 命名慣例源自 Sybase/SQL Server,DB2 官方不強制前綴,但建議遵循命名規範區分用途。
LANGUAGE SQL,無需編譯器,部署簡單,效能最佳,支援完整流程控制 (IF/WHILE/FOR/CASE)、動態 SQL、條件處理。首選。LANGUAGE C/JAVA/COBOL,需編譯成 DLL/Shared Library/JAR,部署複雜,適用於極其複雜運算、調用外部庫、既有資產重用場景。IN:輸入參數OUT:輸出參數INOUT:雙向參數
CREATE PROCEDURE GET_EMP_BY_DEPT (IN p_dept CHAR(3), OUT p_count INTEGER)
LANGUAGE SQL
DYNAMIC RESULT SETS 1 -- 宣告返回 1 個結果集
BEGIN
DECLARE c1 CURSOR WITH RETURN TO CALLER FOR
SELECT * FROM EMPLOYEE WHERE WORKDEPT = p_dept;
OPEN c1; -- 打開游標即返回結果集給調用者
SET p_count = (SELECT COUNT(*) FROM EMPLOYEE WHERE WORKDEPT = p_dept);
END;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS CONDITION 1
v_sqlstate = RETURNED_SQLSTATE,
v_msg = MESSAGE_TEXT;
INSERT INTO ERROR_LOG VALUES (v_sqlstate, v_msg, CURRENT TIMESTAMP);
RESIGNAL; -- 重新拋出或自定義錯誤
END;
CALL PROC_NAME(?, ?)CallableStatement cs = conn.prepareCall("{CALL PROC_NAME(?, ?)}");SQLExecDirect(hstmt, "{CALL PROC_NAME(?, ?)}", SQL_NTS);PREPARE/EXECUTE,注意參數標記防注入。DROP/CREATE 或 ALTER PROCEDURE (DB2 支援替換)。MON_GET_ROUTINE 表函數監控執行次數、耗時、排序溢出等。