DB2 在工具易用性、SQL 方言、存儲過程語義上與 Oracle/SQL Server 差異極大。以下 8 大知識點是新手從「能跑」到「用對」的分水嶺。
-- 錯誤
CREATE VIEW v1 AS SELECT a,b,c FROM t1 ORDER BY a;
-- 正確:巢狀子查詢
CREATE VIEW v1 AS SELECT * FROM (SELECT a,b,c FROM t1 ORDER BY a) AS tab;
需打補丁支援(V8+ 固包 APAR)
-- 2004-02-29 + 1 MONTH → 2004-03-29 (合法)
-- 但 2004-01-31 + 1 MONTH → 2004-02-31 (不存在) → SQLSTATE 01506
**替代方案**:取「當月 1 號」為基準再加減月份
SET v_first = DATE(TRUNC(current_date, 'MONTH'));
SET v_next_month = v_first + 1 MONTH;
-- 不推薦
SELECT col INTO :v FROM t WHERE ...;
-- 推薦:標量子查詢賦值 (V9.7+ 完整支援)
SET v = (SELECT col FROM t WHERE ...);
具體範例:
CREATE FUNCTION SXFM.ISORDERSUBMITDATE(IN_ROW_ID DECIMAL(16,0))
RETURNS DATE LANGUAGE SQL
BEGIN ATOMIC
DECLARE V_SUBMIT_DATE DATE;
DECLARE V_SELL_ID DECIMAL(16,0);
DECLARE V_BUY_ID DECIMAL(16,0);
SET V_SELL_ID = (SELECT COALESCE(RECEIVE_ID,-1) FROM IS_ORDER WHERE ROW_ID=IN_ROW_ID);
SET V_BUY_ID = (SELECT COALESCE(PAY_ID,-1) FROM IS_ORDER WHERE ROW_ID=IN_ROW_ID);
SET V_SUBMIT_DATE = (
SELECT DATE(MAX(A.SUBMIT_DATE))
FROM AM_AUDIT_QUEUE A, SM_USER B, SM_USER C
WHERE A.TABLE_CODE='IS_ORDER'
AND A.TABLE_ROW_ID=IN_ROW_ID
AND A.AUDIT_EMP_ID=C.ROW_ID AND C.BRANCH_ID=V_BUY_ID
AND A.SUBMIT_EMP_ID=B.ROW_ID AND B.BRANCH_ID=V_SELL_ID
);
RETURN V_SUBMIT_DATE;
END
DB2 嚴格、強型別、偏向標準 SQL——習慣差異是新手最大障礙,掌握這 8 點即可避開 90% 入門坑。