查dba_users.expiry_date可识别已过期或即将过期用户,但null值不表示永不过期,需结合dba_profiles中password_life_time设置判断;expiry_date仅是快照值,策略变更后须手动重置密码才能更新该字段。
直接查 dba_users 的 expiry_date 字段就能看到哪些用户密码已过期或即将过期,但要注意字段值为 null 并不等于“永不过期”,而是取决于 profile 中的 password_life_time 设置。
查 expiry_date 为什么有时显示 NULL 却仍报 ORA-28002?
Oracle 不在 dba_users.expiry_date 里存“永不过期”这个语义,它只记录显式计算出的到期时间。当 profile 中 PASSWORD_LIFE_TIME 是 UNLIMITED 时,该字段恒为 NULL;但若设为 180 天,且用户上次改密时间是 2025-11-01,则 expiry_date 就是 2026-04-29(180 天后),哪怕你还没收到警告。
-
expiry_date IS NOT NULL:说明该用户受密码有效期约束,且系统已算出具体到期日 -
expiry_date IS NULL:可能因为 profile 是UNLIMITED,也可能是用户刚创建、尚未触发计算逻辑(如未登录过) - 真正决定是否过期的,是
dba_profiles中该用户 profile 的PASSWORD_LIFE_TIME值 + 用户最后一次改密时间
执行 SQL 查看所有用户的到期状态
用 DBA 权限执行以下查询,能一次性看清账户状态、到期日和所属 profile:
SELECT username, account_status, expiry_date, profile FROM dba_users ORDER BY expiry_date;
重点关注这几类结果:
-
account_status = 'EXPIRED':密码已过期,无法登录(ORA-28001) -
account_status = 'EXPIRED(GRACE)':宽限期中,还能登录但必须改密(ORA-28002 提示“X 天后过期”) expiry_date :日期已过去,但状态仍是 <code>OPEN?说明 profile 刚被改成UNLIMITED,但用户没重置过密码,需手动ALTER USER ... IDENTIFIED BY才会清空expiry_date
为什么只查 expiry_date 不够,还得看 dba_profiles?
dba_users.expiry_date 是“快照值”,不是实时策略。比如你把 DEFAULT profile 的 PASSWORD_LIFE_TIME 从 180 改成 60,已有用户的 expiry_date 不会自动刷新——它仍按旧规则算出的日期保留,直到该用户下次改密或数据库触发重算(如登录时)。
- 查策略:
SELECT * FROM dba_profiles WHERE profile = 'DEFAULT' AND resource_name = 'PASSWORD_LIFE_TIME'; - 查用户实际生效的 profile:
SELECT username, profile FROM dba_users WHERE username = 'SCOTT'; - 两者结合才能判断:当前策略是否已覆盖历史设置?用户是否需要强制重置密码才能让新策略落地?
容易被忽略的关键点
很多人改完 PASSWORD_LIFE_TIME UNLIMITED 就以为万事大吉,结果发现老用户还是提示过期——因为 expiry_date 字段不会自动清空,account_status 也不会自动变回 OPEN。必须对每个已过期/宽限期用户单独执行 ALTER USER username IDENTIFIED BY <same_password></same_password>,Oracle 才会重置其 expiry_date 为 NULL 并恢复状态。这步漏掉,再改 profile 也没用。











