ORA-28002是密码到期前7天的只读提示,不影响登录但必须处理;需先查dba_users中expiry_date和dba_profiles中PASSWORD_LIFE_TIME,再执行ALTER USER IDENTIFIED BY重置密码以清除警告。
ora-28002 提示本身不发邮件,它只是数据库连接时的一行只读输出。要实现“自动邮件提醒”,必须自己搭一套从 dba_users.expiry_date 读取、计算剩余天数、再调用邮件函数的链路。关键前提是:你得先确认用户真正在用哪个 profile,以及该 profile 的 password_life_time 是多少——否则算出来的“还剩x天”可能是错的。
SELECT username, profile, account_status, expiry_date FROM dba_users WHERE username = 'SCOTT';
SELECT resource_name, limit FROM dba_profiles WHERE profile = 'DEFAULT' AND resource_type = 'PASSWORD' AND resource_name = 'PASSWORD_LIFE_TIME';
EXPIRY_DATE 为 NULL 表示从未设过期;若为过去时间,说明已触发 ORA-28001;若为未来时间,才可参与倒计时计算Oracle 原生不带“到期前N天发邮件”功能,但可以用 DBMS_SCHEDULER 定时跑 SQL,配合 UTL_MAIL.SEND 发信。注意:这不是开箱即用的功能,UTL_MAIL 需要提前配置 SMTP 参数(smtp_out_server),且数据库用户要有 EXECUTE 权限。
SELECT value FROM v$parameter WHERE name = 'smtp_out_server';,为空则需 ALTER SYSTEM SET smtp_out_server='smtp.company.com:25' SCOPE=BOTH;
SELECT username, email FROM dba_users u JOIN user_contact c ON u.username = c.username WHERE u.expiry_date BETWEEN SYSDATE AND SYSDATE + 7;(假设有扩展表存邮箱)UTL_MAIL.SEND,得包进 PL/SQL 匿名块或存储过程里,再由作业调用DBA_USERS 里没有邮箱列,硬加 email 字段到数据库是反模式。常见做法是建一张 user_contacts 映射表,或让应用在首次登录时上报邮箱,再通过视图关联查询。
mail)拉取,比维护一张 Oracle 表更可持续username 外键引用 DBA_USERS,并定期清理离职人员记录EXPIRY_DATE,只写“您的密码将在 N 天后过期”,避免泄露元数据很多人误以为监听 ORA-28002 错误就能发邮件,这是错的——它不是可捕获的异常,而是登录成功后的提示文本,不会进 DBA_AUDIT_TRAIL 或告警日志。真正可靠的判断依据只有 EXPIRY_DATE - SYSDATE 的数值。
TRUNC(u.expiry_date) - TRUNC(SYSDATE) 避免时分秒干扰EXPIRED(GRACE),说明已过期但还能登一次,此时应发紧急通知,而非常规提醒实际落地最易卡在 UTL_MAIL 配置和邮箱来源上,而不是 SQL 逻辑本身。没配好 SMTP,再准的倒计时也发不出去;没理清邮箱从哪来,发出去也是退信。