首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

DB2 SQL 預存程序語法全景圖:從 CREATE PROCEDURE 到實戰範例的完整導航

     編輯:DB2 教學

DB2 SQL 預存程序(`CREATE PROCEDURE (SQL)`)功能強大,但語法選項繁多,官方文件鐵軌圖讓人望而卻步。本文將完整語法拆解為 13 個核心子句,逐一說明語意、限制與最佳實務,並附上可直接執行的「中位數薪資查詢」實戰範例,做你開發時的隨身語法導航儀。

完整語法鐵軌圖(簡化版)


CREATE PROCEDURE procedure-name
    ( [ IN | OUT | INOUT parameter-name data-type [, ...] ] )
    [ SPECIFIC specific-name ]
    [ DYNAMIC RESULT SETS integer ]
    [ CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA ]
    [ DETERMINISTIC | NOT DETERMINISTIC ]
    [ CALLED ON NULL INPUT ]
    [ INHERIT SPECIAL REGISTERS ]
    [ OLD SAVEPOINT LEVEL | NEW SAVEPOINT LEVEL ]
    LANGUAGE SQL
    [ EXTERNAL ACTION | NO EXTERNAL ACTION ]
    [ PARAMETER CCSID ASCII | UNICODE ]
    SQL-procedure-body

13 大核心子句深度解析

#子句關鍵語意與限制建議/預設
1procedure-name同一 Schema 下「名稱+參數個數」必須唯一,參數型別不同也視為重複。採用動詞+名詞命名,如 GET_EMP_STATS
2IN/OUT/INOUT parameter-name data-typeIN 輸入、OUT 輸出、INOUT 雙向。parameter-name 程序內唯一。不支援 LONG VARCHAR/VARGRAPHIC、DATALINK、REFERENCE、UDT。明確指定 IN/OUT,避免預設 IN 造成誤解
3SPECIFIC specific-name唯一別名,用於 `DROP`、`COMMENT`、`GRANT`,不能用於 CALL。未指定時系統產生時間戳名稱。強烈建議指定,如 GET_EMP_STATS_V1
4DYNAMIC RESULT SETS integer宣告程序可傳回的結果集最大數量(游標)。雖無 `RETURN` 語句,但可透過 `WITH RETURN` 游標回傳。需回傳結果集時設 >=1,預設 0
5SQL 存取層級CONTAINS SQL:不讀寫資料;READS SQL DATA:唯讀;MODIFIES SQL DATA:可增刪改(預設)。最小權限原則:能 READS 就別 MODIFIES
6DETERMINISTIC / NOT DETERMINISTIC相同輸入必得相同輸出為 Deterministic,優化器可快取結果。含亂數、時間、序列則為 NOT DETERMINISTIC。預設 NOT DETERMINISTIC,能標 DETERMINISTIC 盡量標
7CALLED ON NULL INPUT固定語法,表示無論輸入參數是否 NULL 皆可呼叫,NULL 檢查由程序內部邏輯處理。固定寫上
8INHERIT SPECIAL REGISTERS繼承呼叫端的特殊暫存器(如 CURRENT DATE、CURRENT USER、PATH 等)。預設繼承,建議保留
9Savepoint 層級OLD SAVEPOINT LEVEL(預設):程序內 savepoint 不對外可見;NEW SAVEPOINT LEVEL:建立新層級,程序內 savepoint 可被外部 `RELEASE/ROLLBACK TO`。多為預設
10LANGUAGE SQL固定寫法,指定主體為 SQL PL。必填
11外部動作EXTERNAL ACTION(預設):可能執行非資料庫動作(寫檔、發 HTTP),優化器保守;NO EXTERNAL ACTION:純資料庫操作,優化器可激進優化。純 SQL 操作請加 NO EXTERNAL ACTION
12PARAMETER CCSID輸出字串編碼。Unicode 資料庫預設 UNICODE,其他預設 ASCII (CCSID 3)。跨編碼環境才需調整
13SQL-procedure-body程序主體:單一或多條 SQL PL 陳述式,以 `BEGIN ... END` 包裹。見下方實戰範例

實戰範例:回傳「薪資高於中位數員工」結果集

場景:Sample 資料庫 `STAFF` 表,輸出中位數薪資(OUT 參數)與高於中位數員工清單(結果集)。


CREATE PROCEDURE MEDIAN_RESULT_SET
(
    OUT medianSalary DOUBLE
)
RESULT SETS 1
LANGUAGE SQL
NO EXTERNAL ACTION
READS SQL DATA
BEGIN
    -- 變數宣告
    DECLARE v_numRecords INT DEFAULT 1;
    DECLARE v_counter    INT DEFAULT 0;
    
    -- 游標 1:按薪資排序,用於算中位數
    DECLARE c1 CURSOR FOR
        SELECT CAST(salary AS DOUBLE)
        FROM staff
        ORDER BY salary;
    
    -- 游標 2:回傳結果集,WITH RETURN TO CALLER 關鍵字
    DECLARE c2 CURSOR WITH RETURN TO CALLER FOR
        SELECT name, job, CAST(salary AS INTEGER)
        FROM staff
        WHERE salary > medianSalary
        ORDER BY salary;
    
    -- 例外處理:找不到資料時給預設值
    DECLARE EXIT HANDLER FOR NOT FOUND
        SET medianSalary = 6666;
    
    SET medianSalary = 0;
    SELECT COUNT(*) INTO v_numRecords FROM STAFF;
    
    OPEN c1;
    WHILE v_counter < (v_numRecords / 2 + 1) DO
        FETCH c1 INTO medianSalary;
        SET v_counter = v_counter + 1;
    END WHILE;
    CLOSE c1;
    
    OPEN c2;  -- 不關閉,直接回傳給呼叫端
END

關鍵實務提醒

  • 結果集游標必須 `WITH RETURN TO CALLER` (或 `TO CLIENT`),且 `OPEN` 後不可 CLOSE,引擎會自動傳遞給呼叫端。
  • DYNAMIC RESULT SETS 數值必須 ≥ 實際開啟的 `WITH RETURN` 游標數。
  • 變數命名建議加前綴 `v_`,游標加 `c_`,提升可讀性。
  • 錯誤處理用 `DECLARE ... HANDLER FOR SQLEXCEPTION / NOT FOUND / SQLSTATE 'xxxxx'`。
  • 部署後用 `CALL MEDIAN_RESULT_SET(?)` 測試,驗證 OUT 參數與結果集雙重回傳。

收藏價值:這 13 條子句涵蓋 99% 開發場景。下次寫預存程序時,對著這張表逐項勾選、填寫,即可產出語法正確、語意清晰、效能友善的 DB2 SQL Procedure。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved