SQL*Plus 執行於子進程,其變數無法直接導出至父 Shell 環境。需透過 **標準輸出捕獲** 或 **Host 命令寫入暫存檔/環境變數** 實現跨進程傳值。
#!/bin/ksh
# a.sh
sqlplus -S "/ as sysdba" << !
SET HEADING OFF
COL today NOPRINT
COLUMN today NEW_VALUE dat
SELECT TO_CHAR(sysdate, 'yyyy-mm-dd') today FROM dual;
HOST echo 'today is ' &dat
EXIT
!
# 執行結果:today is 2024-01-15
COLUMN ... NEW_VALUE 將查詢結果存入 SQL*Plus 替換變數 &dat。HOST 命令在資料庫伺服器端執行 Shell 指令,將值輸出至標準輸出。#!/bin/ksh
# a.sh
VALUE=$(sqlplus -S "/ as sysdba" << END
SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF
SELECT MAX(sequence#) FROM v\$log_history;
EXIT
END
)
if [ -z "$VALUE" ]; then
echo "No rows returned from database"
exit 0
else
echo "Max Sequence Number: $VALUE"
fi
# 執行結果:Max Sequence Number: 17
$(...) 或反引號捕獲 SQL*Plus 標準輸出(需關閉所有格式化輸出)。VALUE,後續邏輯判斷極其方便。v\$log_history 中 `$` 需轉義,避免 Shell 先行解析。| SET 選項 | 作用 |
|---|---|
| -S / -SILENT | 抑制版權標語、提示符、回顯 |
| PAGESIZE 0 | 禁用分頁標題 |
| FEEDBACK OFF | 隱藏「n rows selected」 |
| VERIFY OFF | 隱藏新舊值替換提示 |
| HEADING OFF | 隱藏欄位標題 |
| ECHO OFF | 隱藏腳本指令回顯 |
# 以分隔符輸出,Shell 端用 read -d '|' 解析
sqlplus -S "/ as sysdba" << END
SET PAGESIZE 0 FEEDBACK OFF HEADING OFF
SELECT col1 || '|' || col2 || '|' || col3 FROM t WHERE rownum=1;
EXIT
END
模式一適合「資料庫端主動觸發 OS 動作」,模式二適合「Shell 主導流程、攝取資料庫結果」。實務中常混合使用:Shell 驅動 SQL*Plus 取值 → 邏輯判斷 → 再呼叫 SQL*Plus 執行 DDL/DML。