在自動化運維、ETL 腳本、定時報表等場景中,Shell + DB2 CLI 是輕量級數據抽取的經典組合。本文提供可直接落地的範本,涵蓋查詢解析、錯誤處理、行迭代、計數統計、更新執行與 SQLCODE/SQLSTATE 捕獲等核心模式。
#!/bin/ksh
# 1. 定義 SQL(建議使用 HERE 文檔提升可讀性)
SQL="SELECT AAA, BBB, CCC FROM MYTBL1"
# 2. 執行並捕獲輸出(含標題、分隔線、數據、統計行)
SDATA=$(db2 "$SQL")
# 3. 返回值檢查
if [ $? -ne 0 ]; then
echo "SQL 執行失敗:$SDATA" >&2
exit 1
fi
# 4. 解析數據行(跳過前 3 行標題/分隔線,過濾空行)
echo "$SDATA" | sed -e '4,/^$/!d;/^$/d' | \
while read AAA BBB CCC; do
echo "處理:AAA=$AAA, BBB=$BBB, CCC=$CCC"
# 此處可接入業務邏輯:寫檔、調用 API、載入目標表等
done
# 5. 獲取筆數(從統計行提取)
CNT=$(echo "$SDATA" | sed -n -e '/^$/{1,3d;n;s/[^0-9]*\([0-9]*\)[^0-9]*/\1/;p;}')
echo "抽取筆數:$CNT"
exit 0
SQL="UPDATE MYTBL1 SET AAA='2005', BBB='05', CCC='12'"
# -a 顯示 SQLCA 結構化輸出,便於解析
SDATA=$(db2 -a "$SQL")
# 提取 SQLCODE
SQLCODE=$(echo "$SDATA" | sed -n -e 's/^.*sqlcode: \([-,0-9][0-9]*\).*/\1/p')
echo "SQLCODE: $SQLCODE"
# 提取 SQLSTATE
SQLSTATE=$(echo "$SDATA" | sed -n -e 's/^.*sqlstate: \([-,0-9][0-9]*\).*/\1/p')
echo "SQLSTATE: $SQLSTATE"
# 提取更新筆數(SQLERRD(3))
UPDCNT=$(echo "$SDATA" | sed -n -e '/sqlerrd/s/^.*(3) \([-,0-9][0-9]*\).*/\1/p')
echo "更新筆數: $UPDCNT"
# 提取 SQLERRD(5)(通常為自增鍵值或內部標識)
SQLERRD5=$(echo "$SDATA" | sed -n -e '/sqlerrd/{n;s/^.*(5) \([-,0-9][0-9]*\).*/\1/;p;}')
echo "SQLERRD(5): $SQLERRD5
| 技術點 | 說明 | 避坑指南 |
|---|---|---|
命令替換 $(...) | 優於反引號,支援巢狀、可讀性強 | 注意子 Shell 變量作用域,循環內修改的變量外部不可見 |
db2 -a | 輸出 SQLCA 結構,包含 sqlcode、sqlstate、sqlerrd 陣列 | 更新/刪除/插入必須加 -a,否則無 SQLCA 輸出 |
| sed 正則提取 | 針對 DB2 固定格式輸出解析 | 不同 DB2 版本/語系輸出微異,部署前必須實測調整正則 |
| while read 循環 | 逐行處理數據 | 管道右側在子 Shell,若需外部變量改用「重定向輸入」或「陣列」 |
db2 connect ...,結尾 db2 connect reset,避免重複認證開銷。logrotate。SQLCODE->業務含義 對照表,關鍵錯誤(如 -911 鎖超時、-803 唯一鍵衝突)發送告警。flock 或 DB2 應用鎖 (db2 "SELECT ... FOR UPDATE") 防止重複執行。Shell 抽取 DB2 數據的核心在於「捕獲結構化輸出(-a)→ 正則精準解析 → 異常即時感知」。掌握上述兩個範本並根據實際輸出微調正則,即可覆蓋 90% 以上的自動化抽取/更新場景。