CentOS 中 SQL*Plus 与常见工具的集成方法
一 环境准备与基础配置
- 安装 Oracle Instant Client 或相应客户端,确保命令可用;在用户环境(如 ~/.bash_profile 或 ~/.bashrc)中配置关键变量:ORACLE_HOME、PATH、LD_LIBRARY_PATH、SQLPATH、TNS_ADMIN、NLS_LANG。示例:
- export ORACLE_HOME=/opt/oracle/client
- export PATH=$ORACLE_HOME/bin:$PATH
- export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
- export SQLPATH=$HOME/sql:$ORACLE_HOME/sql
- export TNS_ADMIN=$ORACLE_HOME/network/admin
- export NLS_LANG=AMERICAN_AMERICA.UTF8
- 为提升交互体验,可安装 rlwrap 并创建别名:alias sqlplus=‘rlwrap sqlplus’(支持历史与方向键)。SQL*Plus 启动后会自动读取 glogin.sql 与 login.sql(按当前目录、SQLPATH 顺序),可用来统一格式与常用设置。
二 与 Shell 脚本的集成
- 基本调用与静默输出:使用 -S /nolog 静默模式,通过 here-document 传入命令,结合 set 命令控制输出格式,便于后续解析。
- 示例:
- sqlplus -S /nolog >result.log <<‘EOF’
set heading off feedback off pagesize 0 verify off echo off
conn u_test/iamwangnc
select * from tab;
exit
EOF
- 将查询结果返回给 Shell 变量:
- 方式一(命令替换):将查询结果捕获到变量,注意等号两侧不能有空格,且需处理换行与空格。
- VALUE=$(sqlplus -S /nolog <<‘EOF’
set heading off feedback off pagesize 0 verify off echo off numwidth 4
conn u_test/iamwangnc
select count(*) from tab;
exit
EOF
)
- 方式二(NEW_VALUE + exit 返回码):用 col xxx new_value v_xxx 将查询值写入替换变量,再以 exit v_xxx 让 SQL*Plus 以该值作为退出码,Shell 用 $? 获取。
- sqlplus -S /nolog <<‘EOF’
set heading off feedback off pagesize 0 verify off echo off numwidth 4
conn u_test/iamwangnc
col cnt new_value v_cnt
select count(*) cnt from tab;
exit v_cnt
EOF
VALUE=$?
- 向 SQL 传递 Shell 参数:在 here-document 中直接引用 ${变量}。
- 示例:
- NAME=“$1”
sqlplus -S u_test/iamwangnc <<EOF
select * from tab where tname = upper(‘${NAME}’);
exit
EOF
- 安全处理密码:交互式输入或读取受限权限文件,避免明文写在命令行。
- 交互式:
- read -s -p "Enter password: " PASS; sqlplus -S /nolog <<EOF
conn u_test/$PASS
select 1 from dual;
exit
EOF
- 文件方式(权限仅用户可读写):
- echo ‘iamwangnc’ > u_test.txt && chmod 600 u_test.txt
PASS=$(cat u_test.txt)
sqlplus -S /nolog <<EOF
conn u_test/$PASS
select 1 from dual;
exit
EOF
- 导出为 CSV 或文本:使用 SPOOL 与格式化命令,便于被其他工具(如 awk、Python、BI)消费。
- 示例:
- sqlplus -S u_test/iamwangnc <<‘EOF’
SET COLSEP ‘,’
SET LINESIZE 2000
SET PAGESIZE 50000
SET FEEDBACK OFF
SET HEADING ON
SPOOL /tmp/out.csv
SELECT object_name, object_type FROM user_objects WHERE rownum <= 10;
SPOOL OFF
EXIT
EOF
三 与 Python 的集成
- 方式一(推荐)使用 cx_Oracle 直连 Oracle,性能与可维护性更好,适合复杂数据处理与参数化查询。
- 示例:
- import cx_Oracle
conn = cx_Oracle.connect(“u_test/iamwangnc@//host:1521/service”)
cur = conn.cursor()
cur.execute(“select object_name from user_objects where rownum <= 5”)
for r in cur: print®
cur.close(); conn.close()
- 方式二 通过 subprocess 调用 sqlplus,适合沿用既有 .sql 脚本或需要 sqlplus 特有功能的场景。
- 示例:
- import subprocess
def run_sqlplus(sql):
p = subprocess.Popen([‘sqlplus’, ‘-S’, ‘/nolog’],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
p.stdin.write(“connect u_test/iamwangnc\n”)
p.stdin.write(sql + “\nexit\n”)
out, err = p.communicate()
return out, err
print(run_sqlplus(“select sysdate from dual;”)[0])
四 与定时任务及运维工具的集成
- 定时执行与日志轮转:将 Shell 脚本加入 crontab,并结合 logrotate 管理输出日志。
- 示例(每天 02:00 执行):
- 0 2 * * * /opt/scripts/run_report.sh >>/var/log/sql_report.log 2>&1
- 在脚本中统一设置环境并静默执行:
- 示例:
- #!/bin/bash
. ~/.bash_profile
exec >>/var/log/sql_report.log 2>&1
sqlplus -S /nolog <<‘EOF’
set heading off feedback off pagesize 0 verify off echo off
conn u_test/iamwangnc
select count(*) from tab;
exit
EOF
- 运维与 DBA 场景:以 sqlplus /nolog 进入后执行 conn / as sysdba,使用 startup / shutdown immediate 完成启停;也可配合 dbstart / dbshut 与 /etc/oratab 实现开机自启与有序关停。
五 实践建议与常见问题
- 输出可解析性:在 sqlplus 中使用 set 命令(如 heading off、pagesize 0、feedback off、colsep ‘,’)以获得干净、结构化的输出,便于 Shell/Python 解析与导入 CSV。
- 字符集与全球化:设置 NLS_LANG(如 AMERICAN_AMERICA.UTF8)以避免中文乱码;必要时在客户端与数据库侧统一字符集。
- 脚本查找路径:将公共脚本放入 SQLPATH 指定目录,SQL*Plus 会自动在 当前目录、SQLPATH 及其子目录 中查找 login.sql 与脚本文件。
- 安全性:避免在命令行暴露密码;优先使用交互输入或权限受限的密码文件;必要时采用 Wallet 或 OS 认证 等更安全机制。
- 可维护性:为 sqlplus 配置 glogin.sql/login.sql 统一格式;在 Shell 中统一日志、错误码与告警;Python 场景优先选择 cx_Oracle,仅在必须沿用 sqlplus 脚本时再调用子进程。