一、SQLPlus简介与安装准备
1.1 什么是SQLPlus
SQLPlus是Oracle数据库自带的交互式命令行工具,用于执行SQL语句、PL/SQL块和SQLPlus命令。它是DBA和开发人员管理Oracle数据库的核心工具。
SQLPlus主要用途:
– 执行SQL查询和数据操作
– 执行数据库管理命令
– 运行SQL脚本
– 生成报表
– 执行数据库备份恢复操作
1.2 安装前准备
在CentOS上安装SQLPlus前,需要准备:
# 1. 检查系统版本
cat /etc/centos-release
uname -a
# 2. 检查内存和磁盘空间
free -h
df -h
# 3. 安装必要依赖
sudo yum install -y libaio bc flex
# 4. 创建oracle用户(推荐)
sudo groupadd oinstall
sudo groupadd dba
sudo useradd -g oinstall -G dba oracle
sudo passwd oracle
二、SQLPlus安装方法
2.1 方法一:安装Oracle Instant Client(推荐)
Oracle Instant Client是轻量级的Oracle客户端,包含SQLPlus工具。
步骤1:下载Oracle Instant Client
# 创建下载目录
mkdir -p /tmp/oracle_client
cd /tmp/oracle_client
# 下载Oracle Instant Client RPM包(以21c为例)
wget https://download.oracle.com/otn_software/linux/instantclient/2115000/oracle-instantclient-basic-21.15.0.0.0-1.el8.x86_64.rpm
wget https://download.oracle.com/otn_software/linux/instantclient/2115000/oracle-instantclient-sqlplus-21.15.0.0.0-1.el8.x86_64.rpm
wget https://download.oracle.com/otn_software/linux/instantclient/2115000/oracle-instantclient-devel-21.15.0.0.0-1.el8.x86_64.rpm
步骤2:安装RPM包
# 安装RPM包
sudo yum localinstall -y oracle-instantclient-*.rpm
# 检查安装位置
rpm -ql oracle-instantclient-basic | head -20
步骤3:配置环境变量
# 编辑/etc/profile
sudo nano /etc/profile
# 在文件末尾添加:
export ORACLE_HOME=/usr/lib/oracle/21/client64
export PATH=$PATH:$ORACLE_HOME/bin
export LD_LIBRARY_PATH=$ORACLE_HOME/lib
export TNS_ADMIN=$ORACLE_HOME/network/admin
# 使配置生效
source /etc/profile
# 验证安装
sqlplus -version
2.2 方法二:安装完整Oracle客户端
如果需要完整客户端功能,可以安装完整版:
# 1. 下载完整客户端安装包
# 从Oracle官网下载:linux.x64_193000_client.zip
# 2. 解压安装包
unzip linux.x64_193000_client.zip
cd client
# 3. 以oracle用户运行安装程序
./runInstaller
# 4. 按照图形界面提示安装(选择"管理员"类型)
2.3 方法三:使用Docker容器
如果不想在宿主机上直接安装,可以使用Docker:
# 1. 拉取Oracle Instant Client镜像
docker pull store/oracle/database-instantclient:21
# 2. 运行容器
docker run -it --rm store/oracle/database-instantclient:21 sqlplus
# 3. 或者自定义镜像
cat > Dockerfile << 'EOF'
FROM centos:7
RUN yum install -y wget libaio bc
RUN wget https://download.oracle.com/otn_software/linux/instantclient/2115000/oracle-instantclient-basic-21.15.0.0.0-1.el7.x86_64.rpm && \
wget https://download.oracle.com/otn_software/linux/instantclient/2115000/oracle-instantclient-sqlplus-21.15.0.0.0-1.el7.x86_64.rpm && \
yum localinstall -y oracle-instantclient-*.rpm && \
rm -f oracle-instantclient-*.rpm
ENV ORACLE_HOME=/usr/lib/oracle/21/client64
ENV PATH=$PATH:$ORACLE_HOME/bin
ENV LD_LIBRARY_PATH=$ORACLE_HOME/lib
EOF
docker build -t centos-sqlplus .
docker run -it --rm centos-sqlplus sqlplus -version
三、SQLPlus基础连接
3.1 连接本地数据库
# 方法1:使用操作系统认证(sysdba)
sqlplus / as sysdba
# 方法2:使用用户名密码
sqlplus system/password
# 方法3:使用服务名连接
sqlplus system/password@//localhost:1521/orcl
# 方法4:使用TNS别名
# 需要先配置tnsnames.ora
sqlplus system/password@orcl
3.2 连接远程数据库
# 方法1:使用EZCONNECT(最简单)
sqlplus system/password@//192.168.1.100:1521/orcl
# 方法2:配置tnsnames.ora
sudo mkdir -p $ORACLE_HOME/network/admin
sudo nano $ORACLE_HOME/network/admin/tnsnames.ora
# 添加以下内容:
ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.100)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl)
)
)
# 测试TNS连接
tnsping ORCL
# 使用TNS别名连接
sqlplus system/password@ORCL
3.3 解决连接常见问题
问题1:ORA-12154 – TNS:无法解析指定的连接标识符
# 检查TNS_ADMIN环境变量
echo $TNS_ADMIN
# 检查tnsnames.ora文件
cat $ORACLE_HOME/network/admin/tnsnames.ora
# 测试TNS解析
tnsping ORCL
问题2:ORA-12541 – TNS:无监听程序
# 检查数据库监听器状态(在数据库服务器上)
lsnrctl status
# 启动监听器
lsnrctl start
# 检查端口是否监听
netstat -tulnp | grep 1521
问题3:ORA-01034 – ORACLE not available
# 以sysdba登录
sqlplus / as sysdba
# 启动数据库
SQL> startup;
# 查看数据库状态
SQL> select status from v$instance;
四、SQLPlus常用命令
4.1 基础SQLPlus命令
-- 查看当前用户
SHOW USER;
-- 查看数据库版本
SELECT * FROM v$version;
-- 查看当前连接信息
SELECT sys_context('USERENV', 'DB_NAME') FROM dual;
SELECT sys_context('USERENV', 'HOST') FROM dual;
-- 执行操作系统命令(在sqlplus中)
HOST ls -la /tmp
HOST date
-- 清屏(Linux)
!clear
4.2 格式化查询结果
-- 设置行宽
SET LINESIZE 200;
-- 设置页面大小
SET PAGESIZE 50;
-- 设置列宽
COLUMN username FORMAT A20;
COLUMN tablespace_name FORMAT A20;
-- 设置数字格式
COLUMN salary FORMAT $999,999.99;
-- 关闭重复行显示
BREAK ON department_id;
-- 计算小计
COMPUTE SUM OF salary ON department_id;
4.3 执行SQL脚本
# 方法1:在sqlplus中执行脚本
sqlplus system/password@ORCL
SQL> @/tmp/query.sql
# 方法2:直接执行脚本
sqlplus system/password@ORCL @/tmp/query.sql
# 方法3:在shell脚本中使用
cat > query.sql << 'EOF'
SELECT username, created FROM dba_users WHERE account_status='OPEN';
EXIT;
EOF
sqlplus system/password@ORCL @query.sql
4.4 数据导出(SPOOL)
-- 使用SPOOL导出查询结果
SPOOL /tmp/output.csv
-- 设置导出格式
SET PAGESIZE 0
SET FEEDBACK OFF
SET HEADING ON
SET ECHO OFF
SET TERMOUT OFF
SET COLSEP ","
-- 执行查询
SELECT username, created FROM dba_users WHERE account_status='OPEN';
-- 关闭SPOOL
SPOOL OFF
-- 查看导出文件
HOST cat /tmp/output.csv
五、SQLPlus高级操作
5.1 使用绑定变量
-- 定义绑定变量
VARIABLE b_empno NUMBER
VARIABLE b_ename VARCHAR2(20)
-- 给绑定变量赋值
EXEC :b_empno := 7788;
EXEC :b_ename := 'SCOTT';
-- 在查询中使用绑定变量
SELECT * FROM emp WHERE empno = :b_empno;
SELECT * FROM emp WHERE ename = :b_ename;
-- 查看绑定变量值
PRINT b_empno
PRINT b_ename
5.2 使用替换变量
-- 定义替换变量
DEFINE dept_id = 10
-- 在查询中使用替换变量
SELECT * FROM emp WHERE deptno = &dept_id;
-- 使用&&(避免重复提示)
SELECT * FROM dept WHERE deptno = &dept_id;
SELECT * FROM emp WHERE deptno = &dept_id;
-- 查看已定义的变量
DEFINE
-- 清除变量
UNDEFINE dept_id
5.3 执行PL/SQL块
-- 执行匿名PL/SQL块
BEGIN
DBMS_OUTPUT.PUT_LINE('Hello from PL/SQL!');
END;
/
-- 启用DBMS_OUTPUT
SET SERVEROUTPUT ON
-- 创建存储过程
CREATE OR REPLACE PROCEDURE get_emp_count(
p_deptno IN NUMBER,
p_count OUT NUMBER
) AS
BEGIN
SELECT COUNT(*) INTO p_count FROM emp WHERE deptno = p_deptno;
END;
/
-- 调用存储过程
VARIABLE emp_count NUMBER
EXEC get_emp_count(10, :emp_count);
PRINT emp_count
六、SQLPlus脚本自动化
6.1 编写SQLPlus脚本
-- 创建备份脚本:backup_users.sql
cat > backup_users.sql << 'EOF'
-- 备份用户脚本
SPOOL /backup/users_backup_&&backup_date..sql
SELECT 'CREATE USER ' || username ||
' IDENTIFIED BY "' || password || '"' ||
' DEFAULT TABLESPACE ' || default_tablespace ||
' TEMPORARY TABLESPACE ' || temporary_tablespace || ';'
FROM dba_users
WHERE account_status = 'OPEN';
SPOOL OFF
EXIT;
EOF
-- 执行脚本
sqlplus system/password@ORCL @backup_users.sql
6.2 在Shell脚本中使用SQLPlus
#!/bin/bash
# backup_script.sh
# 定义变量
ORACLE_SID=orcl
DB_USER=system
DB_PASS=password
DB_SID=ORCL
BACKUP_DIR=/backup
DATE=$(date +%Y%m%d)
# 执行SQL
sqlplus $DB_USER/$DB_PASS@$DB_SID << EOF
SPOOL $BACKUP_DIR/backup_$DATE.log
-- 查询用户信息
SELECT username, created, profile FROM dba_users WHERE account_status='OPEN';
-- 查询表空间使用率
SELECT tablespace_name,
ROUND(used_space * 100 / total_space, 2) AS used_pct
FROM (
SELECT a.tablespace_name,
a.bytes_alloc / 1024 / 1024 AS total_space,
NVL(b.bytes_free, 0) / 1024 / 1024 AS free_space,
(a.bytes_alloc - NVL(b.bytes_free, 0)) / 1024 / 1024 AS used_space
FROM (SELECT tablespace_name, SUM(bytes) AS bytes_alloc
FROM dba_data_files GROUP BY tablespace_name) a,
(SELECT tablespace_name, SUM(bytes) AS bytes_free
FROM dba_free_space GROUP BY tablespace_name) b
WHERE a.tablespace_name = b.tablespace_name(+)
);
SPOOL OFF
EXIT
EOF
echo "Backup completed at $(date)"
6.3 定时执行SQLPlus脚本
# 使用crontab定时执行
crontab -e
# 添加以下行(每天凌晨2点执行备份)
0 2 * * * /home/oracle/scripts/backup_script.sh > /tmp/backup.log 2>&1
# 查看crontab
crontab -l
七、SQLPlus性能优化
7.1 优化查询性能
-- 1. 增大ARRAYSIZE(减少网络往返)
SET ARRAYSIZE 500;
-- 2. 使用并行查询
SELECT /*+ PARALLEL(emp, 4) */ COUNT(*) FROM emp;
-- 3. 查看执行计划
EXPLAIN PLAN FOR
SELECT * FROM emp WHERE deptno = 10;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
-- 4. 收集表统计信息
EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT', 'EMP');
7.2 优化SQLPlus设置
-- 1. 关闭不必要的输出
SET TERMOUT OFF
SET ECHO OFF
SET FEEDBACK OFF
-- 2. 使用直接路径读取(如果支持)
ALTER SESSION SET "_SERIAL_DIRECT_READ" = TRUE;
-- 3. 增加排序区大小
ALTER SESSION SET SORT_AREA_SIZE = 1048576;
-- 4. 使用绑定变量(减少硬解析)
-- 参见第五章第1节
八、SQLPlus安全加固
8.1 避免在命令行中暴露密码
# 不安全的方式(密码可见)
sqlplus system/password@ORCL
# 安全方式1:使用提示输入密码
sqlplus system@ORCL
# 安全方式2:使用Oracle Wallet
mkstore -wrl /u01/app/oracle/wallet -create
mkstore -wrl /u01/app/oracle/wallet -createCredential ORCL system "password"
# 配置sqlnet.ora
echo "WALLET_LOCATION=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=/u01/app/oracle/wallet)))" >> $ORACLE_HOME/network/admin/sqlnet.ora
echo "SQLNET.WALLET_OVERRIDE=TRUE" >> $ORACLE_HOME/network/admin/sqlnet.ora
# 使用Wallet连接(无需密码)
sqlplus /@ORCL
8.2 限制SQLPlus访问
-- 1. 创建仅必要权限的用户
CREATE USER app_user IDENTIFIED BY "AppPass123!";
GRANT CREATE SESSION TO app_user;
GRANT SELECT ON scott.emp TO app_user;
-- 2. 使用数据库 Vault(Oracle 10g+)
BEGIN
DBMS_MACADM.ENABLE_DATABASE_VAULT;
END;
/
-- 3. 创建IP限制触发器
CREATE OR REPLACE TRIGGER check_client_ip
AFTER LOGON ON DATABASE
DECLARE
v_ip VARCHAR2(50);
BEGIN
SELECT SYS_CONTEXT('USERENV', 'IP_ADDRESS') INTO v_ip FROM DUAL;
IF v_ip NOT IN ('192.168.1.100', '192.168.1.101') THEN
RAISE_APPLICATION_ERROR(-20001, 'Access denied from this IP');
END IF;
END;
/
-- 4. 使用防火墙限制访问
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="1521" accept'
sudo firewall-cmd --reload
九、SQLPlus常见问题排查
9.1 中文显示乱码
# 查看数据库字符集
sqlplus / as sysdba
SQL> SELECT * FROM nls_database_parameters WHERE parameter LIKE '%CHARACTERSET%';
# 设置NLS_LANG环境变量(与数据库字符集一致)
# 如果数据库是AL32UTF8:
export NLS_LANG="AMERICAN_AMERICA.AL32UTF8"
# 如果数据库是ZHS16GBK:
export NLS_LANG="AMERICAN_AMERICA.ZHS16GBK"
# 永久设置(写入/etc/profile)
echo 'export NLS_LANG="AMERICAN_AMERICA.AL32UTF8"' >> /etc/profile
source /etc/profile
9.2 sqlplus:command not found
# 查找sqlplus可执行文件
find /usr -name "sqlplus" 2>/dev/null
# 创建符号链接
sudo ln -s /usr/lib/oracle/21/client64/bin/sqlplus /usr/local/bin/sqlplus
# 或者添加到PATH
echo 'export PATH=/usr/lib/oracle/21/client64/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
# 验证
which sqlplus
sqlplus -version
9.3 脚本执行报错SP2-0734
# 1. 检查脚本编码和换行符
file script.sql
dos2unix script.sql # 转换Windows换行符
# 2. 使用@命令执行脚本
sqlplus system/password@ORCL
SQL> @script.sql
# 3. 调试脚本(显示每行执行的命令)
SET ECHO ON
@script.sql
十、总结
在CentOS中使用SQLPlus,需要掌握以下核心技能:
- 安装配置:正确安装Oracle Instant Client并配置环境变量
- 连接数据库:掌握本地连接、远程连接、TNS配置等方法
- 常用命令:熟练使用SQLPlus格式化、脚本执行、数据导出等功能
- 高级操作:使用绑定变量、替换变量、PL/SQL块等高级特性
- 自动化:编写Shell脚本实现SQLPlus自动化运维
- 性能优化:优化查询性能和SQLPlus设置
- 安全加固:保护密码、限制访问、审计操作
- 问题排查:解决中文乱码、连接失败、脚本错误等常见问题
核心要点:
– 使用EZCONNECT简化远程连接(无需配置tnsnames.ora)
– 使用SPOOL导出数据,使用sqlplus命令行执行脚本实现自动化
– 设置正确的NLS_LANG环境变量解决中文乱码
– 使用Oracle Wallet保护密码,避免在命令行中暴露
– 使用绑定变量减少硬解析,提升性能
通过本文的指南,你可以在CentOS上熟练使用SQLPlus进行Oracle数据库管理和开发工作。
注:本文基于CentOS 7/8和Oracle 19c/21c编写,具体配置可能因版本差异而略有不同。