oracle不提供密码过期自动邮件提醒的开箱功能,需通过dbms_scheduler调用pl/sql块查询dba_users.expiry_date、关联邮箱表、调用utl_mail.send实现,且必须验证profile绑定、password_life_time值、smtp配置及邮箱数据准确性。
oracle 本身不提供「密码过期前n天自动发邮件给用户」的开箱功能。ora-28002 提示只在登录时输出一行只读文本,不触发任何外部动作。要实现真正的提醒通知,必须自己搭链路:从 dba_users.expiry_date 读取、计算剩余天数、关联邮箱、调用 utl_mail.send —— 缺一不可。
查清楚 expiry_date 和 PASSWORD_LIFE_TIME 才能定提醒逻辑
很多人写的提醒脚本跑出来“还剩5天”,结果用户根本没过期,原因就是没确认 profile 绑定和策略生效值。
-
SELECT username, profile, account_status, expiry_date FROM dba_users WHERE username = 'SCOTT'—— 看expiry_date是未来时间才参与倒计时;若为NULL,说明该用户从未设过期;若已是过去时间,已触发ORA-28001,提醒已失效 -
SELECT resource_name, limit FROM dba_profiles WHERE profile = 'DEFAULT' AND resource_type = 'PASSWORD' AND resource_name = 'PASSWORD_LIFE_TIME'—— 若返回UNLIMITED,那ORA-28002就不该出现,得查用户是否绑了其他 profile(比如APP_PROFILE) - 一个用户可能被显式
ALTER USER ... PROFILE xxx指定了非 DEFAULT 的 profile,不能只查 DEFAULT
用 DBMS_SCHEDULER + UTL_MAIL 写定时提醒作业
Oracle 原生没有“到期前7天发邮件”这种调度能力,但可以用 DBMS_SCHEDULER 调用 PL/SQL 匿名块来组合实现。
- 先确认 SMTP 已配置:
SELECT value FROM v$parameter WHERE name = 'smtp_out_server';为空就得执行ALTER SYSTEM SET smtp_out_server='smtp.company.com:25' SCOPE=BOTH -
UTL_MAIL.SEND需要EXECUTE权限,且数据库用户必须被显式授权,不是 DBA 就默认有 - 作业主体不能是纯 SQL 查询,必须包进 PL/SQL 块里,例如:
BEGIN FOR r IN ( SELECT u.username, c.email FROM dba_users u JOIN user_contacts c ON u.username = c.username WHERE u.expiry_date BETWEEN SYSDATE AND SYSDATE + 7 AND u.account_status = 'OPEN' ) LOOP UTL_MAIL.SEND( sender => 'db-alert@company.com', recipients => r.email, subject => 'Oracle 密码将在 ' || TRUNC(r.expiry_date - SYSDATE) || ' 天后过期', message => '请尽快登录数据库执行 ALTER USER ' || r.username || ' IDENTIFIED BY ;' ); END LOOP; END; - 作业频率建议设为每天一次(
repeat_interval => 'FREQ=DAILY; BYHOUR=9; BYMINUTE=0'),避免窗口边缘漏掉
别硬编码邮箱字段:用外部表或应用层补全更可靠
DBA_USERS 表里根本没有 email 列。直接往系统表加字段是反模式,维护成本高、易出错。
- 推荐建一张
user_contacts映射表,username作为外键引用DBA_USERS,并加定期清理离职人员的机制 - 如果公司用 AD/LDAP 同步账号,优先从 AD 的
mail属性拉取,比 Oracle 表更可持续 - 应用首次登录时由前端收集邮箱并写入映射表,比 DBA 手动维护更轻量
- 邮件内容里不要暴露
expiry_date具体日期(如 2026-07-01),只写“还剩 X 天”,避免用户误判时区或缓存问题
真正难的不是写那几行 UTL_MAIL.SEND,而是确保 expiry_date 计算路径上每一步都可验证:profile 绑定对不对、limit 值是不是真生效、邮箱数据有没有滞后、SMTP 连接会不会被防火墙拦截——任何一个环节断掉,提醒就成摆设。











