一、环境配置技巧
1.1 自动加载配置文件
SQLPlus启动时自动读取login.sql文件,可预设常用参数:
# 创建login.sql
cat > $ORACLE_HOME/sqlplus/admin/glogin.sql << 'EOF'
-- 格式化输出
SET PAGESIZE 50
SET LINESIZE 200
SET FEEDBACK ON
SET TIMING ON
SET SQLPROMPT '_USER@_CONNECT_IDENTIFIER> '
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
EOF
# 或用户级配置
cat > ~/login.sql << 'EOF'
SET TERMOUT ON
SET ECHO OFF
SET VERIFY OFF
DEFINE _EDITOR = vim
EOF
1.2 环境变量优化
# 添加到 ~/.bashrc
export ORACLE_HOME=/usr/lib/oracle/21/client64
export PATH=$ORACLE_HOME/bin:$PATH
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
export SQLPATH=$ORACLE_HOME/sqlplus/admin
# 别名设置
alias sql='sqlplus / as sysdba'
alias sqlhr='sqlplus hr/hr@//localhost:1521/orclpdb1'
二、输出格式化技巧
2.1 列格式化
-- 设置列宽和标题
COLUMN employee_name FORMAT A20 HEADING '员工姓名'
COLUMN salary FORMAT $99,999.99 HEADING '薪资'
COLUMN hire_date FORMAT A10 HEADING '入职日期'
-- 清除列格式
COLUMN employee_name CLEAR
-- 查看当前列设置
COLUMN
2.2 报表美化
-- 设置页面大小和行宽
SET PAGESIZE 100
SET LINESIZE 200
-- 添加标题
TTITLE CENTER '员工薪资报表' SKIP 1 -
LEFT '部门: ' dept_name SKIP 2
BTITLE CENTER '=== 第 ' SQL.PNO ' 页 ===' SKIP 1
-- 添加分隔线
BREAK ON department_id SKIP 1
COMPUTE SUM OF salary ON department_id
-- 关闭标题
TTITLE OFF
BTITLE OFF
2.3 HTML输出
-- 生成HTML报表
SET MARKUP HTML ON SPOOL ON PREFORMAT OFF ENTMAP ON -
HEAD '<style>table{border-collapse:collapse}td,th{border:1px solid #ccc;padding:5px}</style>' -
BODY '<h1>数据库报表</h1>' -
TABLE 'class="report"'
SPOOL /tmp/report.html
SELECT * FROM employees WHERE rownum <= 20;
SPOOL OFF
SET MARKUP HTML OFF
三、脚本执行技巧
3.1 命令行执行脚本
# 静默执行SQL脚本
sqlplus -S username/password@db @script.sql
# 传递参数
sqlplus -S username/password@db @query.sql DEPARTMENT_ID=10
# script.sql中使用参数
-- SELECT * FROM employees WHERE department_id = &1;
3.2 脚本中调用脚本
-- main.sql
@@init_setup.sql -- 同目录下的脚本
@/path/to/other.sql -- 绝对路径脚本
-- 条件执行
COLUMN today NEW_VALUE v_today
SELECT TO_CHAR(SYSDATE, 'YYYYMMDD') today FROM dual;
SPOOL report_&v_today..txt
@@generate_report.sql
SPOOL OFF
3.3 批量执行
# 批量执行多个脚本
for f in /scripts/*.sql; do
echo "Executing $f..."
sqlplus -S user/pass@db @$f
done
# 使用Here Document
sqlplus -S user/pass@db << EOF
SET FEEDBACK OFF
SET HEADING OFF
SELECT count(*) FROM employees;
EXIT;
EOF
四、数据导出技巧
4.1 CSV导出
-- 快速CSV导出
SET FEEDBACK OFF
SET HEADING OFF
SET PAGESIZE 0
SET LINESIZE 32767
SET TRIMSPOOL ON
SET COLSEP ','
SPOOL /tmp/employees.csv
SELECT employee_id || ',' || first_name || ',' || last_name || ',' || salary
FROM employees;
SPOOL OFF
4.2 JSON导出
-- Oracle 12c+ JSON导出
SET FEEDBACK OFF
SET HEADING OFF
SET PAGESIZE 0
SET LINESIZE 32767
SPOOL /tmp/employees.json
SELECT JSON_ARRAYAGG(
JSON_OBJECT(
'id' VALUE employee_id,
'name' VALUE first_name || ' ' || last_name,
'salary' VALUE salary
)
) FROM employees;
SPOOL OFF
五、编辑与历史技巧
5.1 行编辑器
-- 查看缓冲区
LIST
-- 修改指定行
LIST 3
CHANGE /old_value/new_value
-- 添加新行
INPUT
SELECT * FROM departments;
-- 删除行
DEL 3
-- 追加文本到当前行
APPEND ORDER BY salary DESC
5.2 使用外部编辑器
-- 设置编辑器为vim
DEFINE _EDITOR = vim
-- 编辑缓冲区
EDIT
-- 编辑指定脚本
EDIT my_query.sql
5.3 历史命令(rlwrap)
# 安装rlwrap
sudo apt install rlwrap -y
# 使用rlwrap启动SQLPlus
rlwrap sqlplus username/password@db
# 添加别名到.bashrc
alias sqlplus='rlwrap sqlplus'
# 现在支持上下键浏览历史命令
六、性能监控技巧
6.1 执行计划查看
-- 查看执行计划
EXPLAIN PLAN FOR
SELECT * FROM employees WHERE department_id = 10;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
-- 更详细的执行计划
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(FORMAT=>'ALL +PEEKED_BINDS +OUTLINE'));
6.2 自动追踪
-- 开启AUTOTRACE
SET AUTOTRACE ON
-- 只看统计信息
SET AUTOTRACE TRACEONLY STATISTICS
-- 只看执行计划
SET AUTOTRACE TRACEONLY EXPLAIN
-- 关闭
SET AUTOTRACE OFF
6.3 计时与统计
-- 开启计时
SET TIMING ON
-- 查看执行时间
SELECT COUNT(*) FROM large_table;
-- 输出: Elapsed: 00:00:03.42
-- 开启性能统计
SET STATISTICS ALL
七、高级技巧
7.1 动态SQL生成
-- 生成批量SQL
SET FEEDBACK OFF
SET HEADING OFF
SET PAGESIZE 0
SET LINESIZE 200
SPOOL /tmp/grant_scripts.sql
SELECT 'GRANT SELECT ON ' || table_name || ' TO readonly_role;'
FROM user_tables
WHERE table_name LIKE 'EMP%';
SPOOL OFF
-- 执行生成的脚本
@/tmp/grant_scripts.sql
7.2 绑定变量
-- 定义绑定变量
VARIABLE v_dept_id NUMBER
VARIABLE v_count NUMBER
-- 赋值
EXEC :v_dept_id := 10
-- 使用绑定变量(性能更优)
SELECT COUNT(*) INTO :v_count
FROM employees
WHERE department_id = :v_dept_id;
-- 打印结果
PRINT v_count
7.3 条件判断
-- 使用WHENEVER控制错误处理
WHENEVER SQLERROR EXIT SQL.SQLCODE
WHENEVER OSERROR EXIT FAILURE
-- 嵌入PL/SQL块
BEGIN
IF TO_CHAR(SYSDATE, 'DY') = 'MON' THEN
DBMS_OUTPUT.PUT_LINE('周一执行维护任务');
-- 执行维护代码
END IF;
END;
/
八、Debian特有技巧
8.1 后台执行
# 使用nohup后台执行
nohup sqlplus -S user/pass@db @long_query.sql > output.log 2>&1 &
# 使用screen/tmux
tmux new -s dbwork
sqlplus user/pass@db
# Ctrl+B D 分离会话
# tmux attach -t dbwork 重新连接
8.2 定时任务
# crontab定时执行SQL脚本
crontab -e
# 每天凌晨2点执行
0 2 * * * /usr/lib/oracle/21/client64/bin/sqlplus -S user/pass@db @/scripts/daily_report.sql >> /var/log/db_report.log 2>&1
九、常见问题解答
Q1: SQLPlus中如何输入多行SQL?
A: 输入完一行后按回车,SQLPlus会显示行号继续输入,以分号;或斜杠/结尾执行。
Q2: 如何取消正在执行的SQL?
A: 按 Ctrl+C 中断当前执行。若无效,另开会话执行 ALTER SYSTEM KILL SESSION 'sid,serial#';
Q3: 输出内容被截断怎么办?
A: 增大LINESIZE和PAGESIZE:SET LINESIZE 32767 PAGESIZE 50000
总结
掌握SQLPlus技巧能显著提升数据库运维效率。环境配置和格式化输出是基础,脚本执行和数据导出是日常高频操作,性能监控和高级技巧则帮助处理复杂场景。建议将常用配置写入login.sql,配合rlwrap和别名设置,打造高效的SQLPlus工作环境。
注:本文基于Oracle 21c + Debian 12环境整理,大部分技巧适用于Oracle 11g及以上版本。