ora-01940报错根本原因是v$session中存在active或inactive会话(含schemaname匹配、调度作业、监听器直连等隐式连接),需先锁用户阻断新连接,再查杀所有相关会话(含os进程),最后drop user cascade。

ORA-01940 错误不是因为“用户还在操作”,而是 Oracle 检测到该用户名下仍有 v$session 记录(状态为 ACTIVE 或 INACTIVE),哪怕客户端已断开、连接池没 close,只要会话未被彻底清理,就拒绝 DROP USER CASCADE。
查不到会话却仍报 ORA-01940,怎么办?
常见现象:执行 SELECT * FROM v$session WHERE username = 'XXX' 返回空,但 DROP USER XXX CASCADE 依然失败。
- 检查大小写 —— Oracle 默认将用户名转为大写,查询必须用
WHERE username = 'XXX',不能写小写或混合大小写 - 查
schemaname而非username:SELECT sid, serial#, program, status FROM v$session WHERE schemaname = 'XXX',某些 JDBC 连接池或后台作业可能不填username但填了schemaname - 检查调度作业:
SELECT job_name FROM dba_scheduler_jobs WHERE owner = 'XXX',未完成的 JOB 会隐式维持会话上下文 - 确认监听器直连或外部代理(如 Oracle Wallet、Oracle RAC VIP)是否残留连接,这类连接有时
username为空,但实际以该用户身份执行
ALTER SYSTEM KILL SESSION 执行后仍删不掉用户
执行 ALTER SYSTEM KILL SESSION 'sid,serial#' 后,v$session 中对应记录的 status 变成 KILLED,但 DROP USER 还报 ORA-01940 —— 这说明 PMON 尚未回收资源,底层 OS 进程还活着。
- 加
IMMEDIATE参数强制中断:ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE,跳过等待事务回滚,加速清理 - 若仍卡在
KILLED状态,立刻查 OS 进程号:SELECT p.spid, s.sid, s.serial# FROM v$process p, v$session s WHERE p.addr = s.paddr AND s.username = 'XXX' - Linux 下执行:
kill -9 spid;Windows 下用:orakill <oracle_sid> spid</oracle_sid> - 再查
v$session,确认该用户所有记录彻底消失 —— 若还有残留,需重启监听器(lsnrctl stop/start),而非整个数据库
为什么先锁用户再杀会话更稳妥?
直接杀会话时,新连接可能瞬间重建,尤其在应用使用连接池、自动重连机制下,导致反复失败。
- 先执行:
ALTER USER XXX ACCOUNT LOCK,阻断一切新认证请求 - 再查会话、杀进程、删用户,整个流程原子性更强
- 注意:锁用户不影响已有会话,所以必须在锁之后立即清理现存会话,否则锁了也删不掉
- 不要依赖
DISCONNECT SESSION—— 它虽比KILL SESSION更激进,但在部分 Oracle 版本中行为不稳定,IMMEDIATE+kill -9组合更可控
最易被忽略的点是:v$session 里看不到会话 ≠ 没有会话。调度作业、空闲连接池连接、监听器转发连接都可能不显式出现在 username 字段里,得从 schemaname、program、后台进程三路交叉验证。一旦发现残留,OS 层 kill -9 是兜底动作,但必须配合 spid 精准定位,避免误杀其他 Oracle 进程。











