ORA-28003 报错后修改 utlpwdmg.sql 不生效,90% 是因未将新密码校验函数显式绑定到 profile;必须用 SYS AS SYSDBA 执行 @?/rdbms/admin/utlpwdmg.sql,再 ALTER PROFILE ... LIMIT PASSWORD_VERIFY_FUNCTION 指定函数名。
ORA-28003 报错后改了 utlpwdmg.sql 还不生效?先查 profile 绑定
密码校验函数改了但没起作用,90% 是因为没把新函数真正绑定到 profile 上。oracle 不会自动扫描数据库里所有叫 verify_function 的函数——它只认 profile 里 password_verify_function 字段指定的那个。
执行这两条 SQL 确认现状:
SELECT profile FROM dba_users WHERE username = 'YOUR_USER';
SELECT resource_name, limit FROM dba_profiles WHERE profile = 'DEFAULT' AND resource_name = 'PASSWORD_VERIFY_FUNCTION';
如果 limit 是 NULL 或 VERIFY_FUNCTION_11G,而你刚编译了 ora12c_strong_verify_function,那它根本不会被调用。
常见错误现象:反复修改 utlpwdmg.sql 再运行一遍,但 dba_profiles 里还是旧值;或者改完脚本后直接 ALTER USER ... IDENTIFIED BY xxx 测试,结果发现连最基础的长度检查都没触发。
必须以 SYS AS SYSDBA 运行 @?/rdbms/admin/utlpwdmg.sql
这个脚本不是普通 SQL 文件,它定义的是数据库级验证回调函数,权限要求硬性且明确:
- 必须用
SYS用户连接,且显式加上AS SYSDBA(仅AS SYSOPER或普通 DBA 角色不行) -
RESOURCE_LIMIT参数必须为TRUE:SHOW PARAMETER resource_limit查,若为FALSE,先执行ALTER SYSTEM SET resource_limit = TRUE; - 路径必须准确——Oracle 12c+ 自带的脚本在
$ORACLE_HOME/rdbms/admin/utlpwdmg.sql,别用网上下载的同名文件覆盖,版本不匹配会导致编译失败或逻辑缺失
运行命令是 @?/rdbms/admin/utlpwdmg.sql(注意是 @,不是 START 或直接粘贴内容),否则函数不会被创建或替换。
ora12c_strong_verify_function 和 verify_function 别混用
11g 及更早用 verify_function,12c+ 推荐用 ora12c_strong_verify_function,二者参数名、校验项、默认阈值都不同:
-
ora12c_strong_verify_function多校验键盘序列(如123456、qwerty)、重复字符(如aaabbb)、字典词(含用户名、实例名等),且默认要求至少 8 位、含大小写字母、数字、特殊字符(仅_ $ #被允许) -
verify_function仅做基础长度、大小写、数字检查,不防键盘序列或相似用户名 - 修改阈值时注意变量名差异:老版用
min_uppercase,新版用upper;老版min_special对应新版punct
如果你在 12c+ 环境下仍绑定了 verify_function,就等于主动放弃了更强的校验能力,也容易因特殊字符限制(比如拒绝 @ 或 !)导致用户报错 ORA-28003 却找不到原因。
自定义函数改完必须重新绑定 profile,不能只改脚本
改了 utlpwdmg.sql 里的阈值(比如把最小长度从 8 改成 12),只是让函数体变了;但 profile 还指着旧函数名,新逻辑就不会执行。
完整闭环操作只有三步:
1. 用 SYS AS SYSDBA 执行 @?/rdbms/admin/utlpwdmg.sql(这步会重建函数)
2. 查确认函数已存在:SELECT object_name FROM dba_objects WHERE object_type = 'FUNCTION' AND object_name LIKE '%VERIFY%';
3. 显式绑定:ALTER PROFILE DEFAULT LIMIT PASSWORD_VERIFY_FUNCTION ora12c_strong_verify_function;(或你自定义的函数名)
容易踩的坑:
- 函数里加
DBMS_OUTPUT.PUT_LINE—— 密码校验发生在登录/改密瞬间,此时输出不可见,还可能因权限不足抛ORA-06502 - 注释掉某个校验分支却忘了删
RETURN TRUE—— 函数提前返回,等于整个校验逻辑被绕过 - 对生产用户直接改
DEFAULTprofile —— 所有依赖它的用户立刻受新规则约束,建议先建新 profile(如SECURE_PROFILE),测试通过后再切换
最常被忽略的一点:函数改了、profile 也绑了,但用户 session 还在用旧密码缓存,得强制其改密才能触发新校验逻辑,用 ALTER USER username PASSWORD EXPIRE; 最稳妥。











