ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SQL*Plus安装配置与运维实战:连接、命令与报错排查

SQL*Plus安装配置与运维实战:连接、命令与报错排查 干数据库这行的人大概率都得跟 SQL*Plus 打个照面。它看起来就是个黑乎乎的窗口敲几行命令跑 SQL很多人手头有 PL/SQL Developer、DBeaver、Navicat 这类图形工具平时连 sqlplus.exe 都不愿意碰。但真到了排查环境问题、写自动化脚本、服务器上只剩命令行界面、装完 Oracle 连不上监听的时候你绕不开它。这篇文章就是讲清楚 SQL*Plus 的安装、连接和日常使用。我按实操顺序走一遍先从选版本、下载、配环境变量说起然后讲三种登录方式再展开 show 命令、set 命令、格式化输出、脚本批量执行这些高频操作最后把连接报错、乱码、监听启动失败这些经典坑整理成速查表。不管你是在 Windows 上用 Instant Client 连远程库的开发者还是在 Linux 上做数据库维护的 DBA这份东西都能当个参考。1. 先说清楚SQL*Plus 是什么为什么绕不开1.1 一个被低估的命令行工具SQL*Plus 是 Oracle 自带的一个交互式客户端工具从早期的 Oracle 版本一路跟到现在界面变化极小。它的核心工作就一句话把你输入的 SQL 语句送到数据库服务器去执行再把结果按你指定的格式打出来。很多人觉得它原始是因为它没有代码补全、没有彩色高亮、没有表格可视化。但这恰恰是它的价值——它足够轻、足够稳而且在任何装了 Oracle 客户端的环境里都能用。你可以在笔记本上用它连远程数据库也可以在机房服务器上只开一个终端就完成状态检查。图形工具做不到的事交给它反而顺手。举个实际场景服务器发生了性能问题远程桌面连不上只能通过堡垒机开一个命令行窗口。你手头没有任何图形界面这时候想看看数据库还在不在、当前有哪些会话、参数有没有被改过SQL*Plus 就是你唯一的入口。这活儿不需要什么花哨界面能执行 SQL、能看返回结果就够了。1.2 和图形工具比差别在哪里我在日常工作里是图形工具和 SQL*Plus 混着用的。这里先给个直观对比方便你按场景选对比项SQL*PlusPL/SQL DeveloperDBeaverNavicat安装体积很小Instant Client 几百MB以内较大还要配 Oracle Client中等需要下载驱动中等自带驱动图形依赖无纯命令行有有有脚本化强天然支持 、spool一般一般一般代码补全没有有有有调试存储过程不方便方便较弱较弱适用场景服务器维护、自动化执行、应急排查开发调试跨数据库日常查询日常管理和查询图形工具确实提高了日常开发效率尤其是调试存储过程、阅读执行计划、看表结构的时候。但你会发现越是正规的项目环境越要求你把脚本沉淀下来。SQL*Plus 的价值就在于可以放进脚本、可以定时执行、可以重复跑这在自动化运维里是硬需求。1.3 从搜索热词看大家真正关心什么我梳理了一圈关于 Oracle 和 SQLPlus 的搜索词发现大家搜得最多的其实是这么几类安装下载类的Oracle 19c、21c 下载Instant Client 下载CentOS 上装 Oracle连接配置类的PL/SQL 连接配置、DBeaver 连接 Oracle、监听服务无法启动、修改默认监听端口命令用法类的sqlplus show 命令、show parameter 用法、格式化输出、spool 导出问题排查类的ORA- 报错、字符集乱码、连接超时业务应用类的分页查询、日期格式转换、过滤不可转数字的字符串、存储过程调试。你会发现这些问题没有一个绕得开 SQL*Plus。安装它解决的是工具从哪来的问题连接配置解决的是怎么进来的问题show 命令和格式化解决的是怎么看清状态的问题报错排查解决的是出问题怎么定位的问题。所以这篇文章就沿着这条线往下走。2. 安装版本选择、下载与环境变量2.1 先搞清楚你要装哪一种很多人一上来就问SQLPlus 去哪下载其实首先得想清楚你要的是哪种形态。SQLPlus 不是一个独立软件它依附在 Oracle 客户端或数据库安装包里常见获取方式有三种。第一种本机已经装了 Oracle 数据库。这种情况下最简单SQL*Plus 就在数据库软件的 bin 目录下比如$ORACLE_HOME/bin/sqlplus或C:\app\oracle\product\19c\dbhome_1\BIN\sqlplus.exe。你不需要做任何额外安装直接配置好环境变量就能用。第二种装一个 Oracle Instant Client。Instant Client 是 Oracle 官方的精简客户端包体积比完整客户端小很多不装就能用解压即可里面包含了 sqlplus 和相关连接库。如果你只是要连远程数据库、跑 SQL、做导出不需要完整开发环境这个方案最合适。第三种装完整版 Oracle Client。这个包体积大安装过程也啰嗦但它自带 SQL*Plus、ODBC 驱动、运行时库等完整组件。如果你还想用别的开发工具、程序连 Oracle装完整客户端通常更省心。我的建议很直接日常开发用完整客户端应急和轻量连接用 Instant Client。如果服务器上已经有数据库别再装客户端了直接用自带的避免环境变量打架。2.2 版本怎么选19c 优先Oracle 的版本命名经常把新手绕晕。当前主流稳定版本是 19c它是长期支持版很多生产环境都在用学习资料也好找。21c 属于创新版引入了一些新特性但生产环境使用比例还没到 19c 的级别。如果你只是学 SQL*Plus 本身19c 就够了。下载时需要区分两个概念一个是数据库介质包一个是客户端包。如果你只需要 SQL*Plus 连接远程库下载 Instant Client 包即可不需要下载完整数据库安装包。下载地址是 Oracle 官网的下载中心选择对应操作系统和架构。这里有个实际经验Windows 64 位系统就下载 64 位客户端不要混用。如果你的本机上同时有 32 位和 64 位程序要连 Oracle那得分别装对应位数的 Instant Client这是踩过坑之后才明白的。32 位程序没法直接加载 64 位的 Oracle 客户端库。2.3 环境变量配置决定你能不能顺利启动安装或解压完成后第一件事就是配置环境变量。常见的环境变量有三个ORACLE_HOME、PATH、TNS_ADMIN可选Windows 上还有一个NLS_LANG会影响字符集。先看 Windows 上的配置方式。假设你解压 Instant Client 到D:\instantclient_19_12系统环境变量里需要加ORACLE_HOMED:\instantclient_19_12 PATH%ORACLE_HOME%;%PATH% TNS_ADMIND:\instantclient_19_12\network\admin其中TNS_ADMIN指向tnsnames.ora文件所在目录。如果你不需要服务名连接这条路可以暂时不配但用到远程连接时最好先建好目录。Linux 上类似以解压到/opt/oracle/instantclient_19_12为例在.bash_profile或/etc/profile里追加export ORACLE_HOME/opt/oracle/instantclient_19_12 export LD_LIBRARY_PATH$ORACLE_HOME:$LD_LIBRARY_PATH export PATH$ORACLE_HOME:$PATH export NLS_LANGAMERICAN_AMERICA.AL32UTF8注意 Linux 上光加 PATH 不一定够还要加LD_LIBRARY_PATH否则 sqlplus 启动时可能报找不到 libclntsh.so一类错误。这个问题我遇到不下三次每次都是忘了导出LD_LIBRARY_PATH。配置好之后在命令行敲一下验证sqlplus -v如果看到版本号输出说明安装和环境变量都没问题了。如果提示sqlplus 不是内部或外部命令说明 PATH 没配好如果启动时报缺库文件多半是LD_LIBRARY_PATH的问题。2.4 初次进入先别急着连接第一次打开 SQL*Plus建议先创建一个空连接sqlplus /nolog/nolog参数表示只启动 SQL*Plus 界面不建立数据库连接。这时你会看到SQL提示符说明工具本身已经正常。接下来再根据需要连接数据库。这里有个小细节很多人以为sqlplus必须带着用户名密码才能启动其实不是。用/nolog进入后可以在工具里用connect命令切换连接这在排错时特别方便比如先用/nolog进入再逐个测试几种连接写法不用反复退出重开。3. 连接与基础命令从登录到跑通第一条 SQL3.1 三种连接写法对应不同场景SQL*Plus 的连接写法有讲究。别看就一行命令选错写法可能导致你明明装了客户端还是连不上。第一种是本地系统认证适合在数据库服务器本机上以管理员身份进入sqlplus / as sysdba这种写法不需要用户名密码用的是操作系统认证。Windows 下要注意如果当前 Windows 用户不在 ORA_DBA 组里这行命令会报权限不足。Linux 下则是看当前用户是否在 dba 组里。在服务器本机做维护时这是最常用的入口。第二种是局域网连接用服务名连接sqlplus scott/tigerorcl这里的orcl是tnsnames.ora里配置的网络服务名它映射到实际的 IP、端口、数据库服务名。这个写法最常用日常开发和运维都推荐这种方式因为服务名可以随时改指向程序里不用动。第三种是 Easy Connect 方式不需要 tnsnames.ora直接写地址sqlplus scott/tiger192.168.1.100:1521/orcl这种方式适合临时连一下或者环境里还没配置 tnsnames.ora 的场景。注意orcl是数据库的服务名不是实例名。在 19c 多租户架构下这里通常要写成 PDB 的服务名比如pdb1。3.2 登录后的第一件事用 show 命令看家底热搜词里有一条oracle sql plus show命令这个绝对是高频操作。登录之后你最先要了解的是自己身处什么环境show 命令就是干这个的。show user查看当前用户SQL show user USER is SYSshow con_name查看当前容器19c 多租户环境的常用操作SQL show con_name CON_NAME ------------------------------ CDB$ROOTshow parameter查看参数值这是运维中最常用的 show 用法。比如想看db_block_sizeSQL show parameter db_block_size它会返回所有名字里包含db_block_size的参数及当前值。想看审计日志开关就show parameter audit_trail想看进程数就show parameter processes。show sga查看内存结构SQL show sgashow recyclebin查看回收站。有一点要记住show不是 SQL 语句它是 SQL*Plus 的客户端命令。它只在这个工具里生效不能写进存储过程也不能在 JDBC 里执行。这是新手最容易混淆的地方。3.3 别急着跑 SQL先把 set 参数调好很多人第一次用 SQL*Plus 跑查询输出结果一团糟行被截断、分页混乱、存储过程的输出压根看不到。这通常是因为没设置会话参数。我习惯登录后先把常用的 set 命令批量执行一遍环境卫生先搞干净。set linesize 200 set pagesize 100 set serveroutput on set feedback on set trimspool on set colsep |这几个参数的作用分别是linesize一行显示的宽度。默认 80遇到宽字段就被截成两行很难受。一般我设 200 起步。pagesize每页显示的行数。设 0 表示不分页设 100 就是每 100 行显示一次表头。serveroutput on打开dbms_output.put_line的输出不打开这条你写匿名 PL/SQL 块时看不到打印结果。colsep列间分隔符。想导出成 CSV 风格时可以临时设成|或逗号。这些设置是会话级的退出 SQLPlus 就失效。如果你每次进去都要手工敲一遍可以把它们写进一个起头脚本。SQLPlus 启动时会自动读取glogin.sql放在ORACLE_HOME/sqlplus/admin目录下也可以自己维护一个脚本登录后执行setup.sql我常用后者因为不同项目可能有不同的输出偏好。3.4 跑第一条 SQL从 dual 开始准备工作做完跑一条最简单的 SQLSQL select sysdate from dual;这里就涉及dual表。很多初学者会困惑dual到底存的什么它其实是一张只有一行一列的虚表Oracle 专门用来执行那些不需要查表的表达式。比如取当前时间、做算术运算、调用函数都可以通过它来执行。select 1 1 from dual; select to_char(sysdate, yyyy-mm-dd hh24:mi:ss) from dual; select upper(hello) from dual;热搜词里有个oracle中dual最多存多大这个问题本身就说明对它理解有偏差。dual不是让你存数据的表它是表达式计算的载体。正常使用中不需要关心它的大小更不要往里插数据。看表结构用desc命令SQL desc users;它会列出表中的字段名、数据类型、是否可空。这个命令在 SQL*Plus 里的使用频率非常高快速确认字段名比猜着写靠谱得多。4. 把 SQL*Plus 用出效率感进阶实操4.1 会话与状态排查查 SID、杀会话热搜词里有oracle 查看会话sid这是运维场景的高频需求。当数据库出现锁、会话堆积、异常连接时你得先查出问题会话再决定要不要干掉它。在 SQL*Plus 里执行select sid, serial#, username, machine, sql_id, status from v$session where username is not null order by sid;v$session是动态性能视图信息比较全。sid是会话编号serial#是序列号两者合在一起才是唯一标识光记sid是不行的。确定要杀掉某个会话时alter system kill session 123, 456;这里的123是sid456是serial#。有个经验教训杀会话前确认一下这个会话是不是你自己手里的连接。我见过同事在测试库上杀会话手一抖把自己当前连接给杀了结果是 SQL*Plus 直接断开后面批处理脚本全挂。真要防一手就先执行查询把结果截图或记下来再挑选目标。4.2 分清分页显示和分页查询很多人搜oracle分页但没意识到这里其实有两个不同概念。在 SQL*Plus 语境下先说分页显示。默认pagesize是 14查询结果超过 14 行就会分页每页底部还有省略提示屏幕一直刷。想让它一口气全打出来就设置set pagesize 0pagesize 0表示不分页适合结果行数不多、你想完整抓取的情况。但这只影响显示不影响业务层查询。再说真正的分页查询。Oracle 12c 及以上可以用OFFSET ... FETCHselect * from employees order by employee_id offset 20 rows fetch next 10 rows only;这是返回第 21 到第 30 行。老版本用ROWNUM嵌套查询实现。这两个概念经常被混在一起实际工作中要分清楚set pagesize是 SQL*Plus 的输出设置OFFSET FETCH是 SQL 标准语法。在 SQL*Plus 里验证分页查询时可以用自带的hr示例用户或者自己建一个测试表插几十条数据反复调offset参数直观感受返回结果的变化。4.3 字符串和日期两个高频小场景热搜词里还有两条非常具体的问题一个是过滤不可转为数字的字符串另一个是毫秒转换日期格式。这俩在 SQLPlus 里执行和在图形工具里执行没有区别因为都是 SQL 层面的东西但 SQLPlus 能让你快速验证不用开重型工具。过滤不可转数字的字符串常见于你把外部数据导入临时表后发现某列混进了非数字内容。可以用REGEXP_LIKE判断是不是纯数字select * from temp_data where not regexp_like(column_a, ^[0-9]$);这会找出所有包含非数字字符的行。如果想把这些行里的非数字字符去掉再转数字select to_number(regexp_replace(column_a, [^0-9], )) from temp_data;毫秒转日期常见场景是数据处理时拿到的是 Unix 时间戳单位是毫秒。Oracle 里可以这样转select to_char( to_date(1970-01-01, yyyy-mm-dd) (1700000000000 / 86400000), yyyy-mm-dd hh24:mi:ss ) from dual;1700000000000是你要转换的毫秒值。除以86400000是因为一天有 86400 秒、1000 毫秒每秒。这个计算逻辑就是从 1970-01-01 开始把毫秒换算成天数然后加到日期上。如果你手头时间戳太新记得考虑时区偏移生产环境经常要写成 (1700000000000 / 86400000) - 8/24转成北京时间。4.4 存储过程、包状态检查与批量编译热搜词里oracle存储过程oracle package出现的频率很高SQL*Plus 也经常被用来做存储过程的日常检查。想看某用户下有没有无效对象尤其是包状态异常时select owner, object_name, object_type, status from dba_objects where status INVALID and owner APP_USER;热搜词里有一条包状态被丢弃实际含义通常是包的代码或依赖对象出问题导致包变为INVALID一般先查无效对象再重新编译。单个包编译可以这样alter package APP_USER.MY_PACKAGE compile;如果对象很多用手工一个个编译不现实SQL*Plus 的脚本化优势就出来了。可以把所有无效对象的编译语句拼接出来批量执行select alter || object_type || || owner || . || object_name || compile; from dba_objects where status INVALID and owner APP_USER;把这组结果复制出来执行一遍大部分无效对象都能恢复。这个技巧在处理发布后的对象失效问题上极其好用我在版本上线后用它兜底不知道多少次了。4.5 spool 导出别被图形工具牵着走数据导出是个高频需求。虽然开发工具都有导出功能但遇到大数据量或定时任务还是 SQL*Plus 的spool最可靠。它的逻辑很简单把接下来 SQL 的输出写入一个文件。set echo off set feedback off set heading off set trimspool on spool /tmp/export_data.txt select last_name || , || salary from employees; spool off走一遍流程你就明白了先关闭多余输出把结果打到文件里最后spool off结束写文件。这里有个很容易踩的坑colsep只对 SQL*Plus 的格式输出有效。如果你用默认格式导 CSV列与列之间可能是空格而不是逗号。要精确控制导出格式最稳的方式是用字符串拼接就像上面例子里的|| , ||。另外如果导出的内容是中文文件字符集和终端字符集如果不一致打开文件会乱码这时候回头查NLS_LANG的设置。5. 常见问题排查速查表把踩过的坑一次说透5.1 一表看懂连接报错数据库连接报错是所有人入门的第一个拦路虎。我把高频的 ORA- 错误整理成一张表方便你对照排查报错含义常见原因排查方向ORA-12560TNS 协议适配器错误监听未启动、本地服务名未注册先lsnrctl status看监听状态ORA-12541TNS 无监听器监听进程没起来或端口不对启动监听检查端口占用ORA-12154TNS 无法解析指定的连接标识符tnsnames.ora里没有这个服务名检查TNS_ADMIN和文件内容ORA-12505监听当前无法识别连接描述符中的服务服务名写错或数据库没注册到监听确认数据库服务名等实例启动完成ORA-01017用户名/口令无效密码错误或账号被锁检查凭据、账号状态ORA-28001口令已过期密码过期策略触发重置密码排查这类问题我有一套固定顺序先确认自己能 ping 通数据库主机再lsnrctl status看监听状态和注册的服务最后检查tnsnames.ora里的服务名拼写。绝大多数连接问题都死在服务名拼写或监听没起来这两个点上。5.2 乱码问题九成出在 NLS_LANGSQL*Plus 输出中文变成问号或乱码几乎都是字符集设置不一致导致的。Oracle 有一个客户端字符集环境变量NLS_LANG它告诉客户端应该用什么字符集解释数据如果和数据库服务器的字符集不一致要么乱码要么报字符集错误。检查服务器端字符集select userenv(language) from dual;然后设置客户端的NLS_LANG与之匹配。比如服务器返回AMERICAN_AMERICA.AL32UTF8客户端就设置export NLS_LANGAMERICAN_AMERICA.AL32UTF8Windows 则在系统环境变量里加同名变量。经验之谈很多老项目数据库字符集是ZHS16GBK而新程序默认用 UTF-8两者不统一就会乱码。建议先查数据库再反推客户端设置而不是凭感觉瞎设。设置完变量后要重新打开一个 SQL*Plus 窗口环境变量在已启动的进程里不会自动刷新。5.3 监听器启动失败与端口修改热搜词里oracle监听服务无法启动和oracle修改默认监听端口出现频率很高。这俩其实是同一类问题监听器和端口配置。监听器的启动和停止命令lsnrctl start lsnrctl status lsnrctl stopWindows 上还能从服务管理器里找到OracleOraDB19Home1TNSListener服务来启动。启动失败的常见原因有几种端口被占用、listener.ora写错、主机名解析异常。遇到端口被占用先看是谁占用了 1521netstat -ano | findstr 1521改端口的话要动listener.ora中监听的端口同时要改tnsnames.ora中对应服务名里的端口两边不一致必然连不上。Linux 下改完还要记得开防火墙端口。这个操作最好在变更窗口做别在业务高峰临时改容易把正在跑的会话全断掉。一旦改完重启监听再用新的端口测试连接。5.4 日常巡检用几条命令打底最后分享一套日常巡检用的 SQL*Plus 命令组合都是我平时用顺手的。不需要天天跑全套但每逢上线、版本变更、性能排查这套组合能帮你看清楚数据库的基本盘。先看实例状态select name, open_mode, database_role from v$database; select instance_name, status from v$instance;open_mode应该是READ WRITE或READ ONLYdatabase_role通常是PRIMARY。如果状态不对那问题大了先解决它再谈别的。再看连接数是否有异常堆积select count(*), status from v$session group by status;正常环境ACTIVE会话数是平稳的如果INACTIVE数量异常飙升很可能有连接泄漏需要进一步查machine和program。然后看安全相关的几个配置主要起自查作用。账号状态select username, account_status, lock_date from dba_users order by username;审计开关show parameter audit_trail;现在还建议加一条show pdbs。如果你的数据库是 19c 多租户架构这条命令能列出所有 PDB日常工作经常需要在 CDB 和 PDB 之间切换上下文alter session set containerxxx是基本操作。这套组合拳打下来数据库的健康状况基本就有数了。剩下的问题再针对性深挖。我个人用了这么多年 SQLPlus最大的体会是它虽然老但特别稳。你敲进去的每一条命令都是可重复、可追溯的出了任何问题你都能说清楚自己到底执行过什么。图形工具让你顺手SQLPlus 让你明白。最后分享一个提升效率的小习惯把你常用的巡检 SQL 存成脚本文件比如health_check.sql里面放一堆查询命令登录后一条/path/health_check.sql就能把所有检查项跑一遍输出集中在一个屏幕里。这套玩法配合spool落日志基本就是日常巡检的雏形了。说真的别嫌 SQL*Plus 土。在你最需要稳定和可追溯的时候它永远在。
返回列表