必须分四类调用dbms_metadata.get_granted_ddl(system、role、default_role、object_grant),且用户名全大写、set long≥100000,再补tablespace_quota和profile配置,按建用户→profile→配额→权限顺序执行。

直接用 DBMS_METADATA.GET_GRANTED_DDL 四次调用就能拿到可执行的权限脚本,但漏一次、大小写错、SET LONG 不够,新用户大概率连不上库。
必须分四类调用 GET_GRANTED_DDL,缺一不可
一个能登录、建表、查数据的用户,权限不是“一堆 GRANT 合起来”那么简单。只取 OBJECT_GRANT,新用户会卡在登录环节;只取 ROLE_GRANT,默认角色不生效,连 SELECT * FROM DUAL 都报权限不足。
-
SYSTEM_GRANT:包含CREATE SESSION、CREATE TABLE等底层能力,没它用户根本进不了库 -
ROLE_GRANT:比如GRANT CONNECT TO "U1",但不展开角色内部权限(那是角色自己的事) -
DEFAULT_ROLE:决定连接后哪些角色自动启用,常见输出是ALTER USER U1 DEFAULT ROLE ALL或显式列表 -
OBJECT_GRANT:具体到对象的权限,如GRANT SELECT ON SCOTT.EMP TO U1,列级权限也会被自动合并
四条语句必须分别执行,顺序无关,但用户名参数必须全大写——小写或带双引号(如 "u1")会导致返回空 CLOB,且不报错,极易误判为“该用户没权限”。
SET LONG 必须设够大,否则脚本执行必报 ORA-00922
DBMS_METADATA.GET_GRANTED_DDL 返回的是 CLOB,SQL*Plus 默认 LONG 是 80 字符,而一条含多个对象的 GRANT 语句就可能超 2000 字符。截断后脚本里会出现半截 GRANT SELECT ON ...,执行时报 ORA-00922: missing or invalid option。
- 执行前务必先运行:
SET LONG 100000 - 顺手加上:
SET PAGESIZE 0(去页眉页脚)、SET FEEDBACK OFF(去 “1 row selected”)、SET TRIMSPOOL ON(去行尾空格) - 验证是否生效:看输出第一行是不是完整以
GRANT或ALTER USER开头,而不是GRANT SELECT ON ...后跟省略号
别忘了 TABLESPACE_QUOTA 和 PROFILE
GET_GRANTED_DDL 完全不处理配额和配置文件,这两项漏掉,用户建表时会直接报 ORA-01536: space quota exceeded 或使用错误密码策略被锁。
- 查配额:
SELECT username, tablespace_name, bytes/1024/1024 AS mb FROM dba_ts_quotas WHERE username = 'U1';→ 手动转成ALTER USER U1 QUOTA 100M ON USERS; - 查 PROFILE:
SELECT profile FROM dba_users WHERE username = 'U1';→ 若非DEFAULT,需加CREATE PROFILE(如果目标库没有)+ALTER USER U1 PROFILE xxx; - 建用户本身也要单独导:
SELECT DBMS_METADATA.GET_DDL('USER', 'U1') FROM DUAL;,注意同样要SET LONG和大写用户名
执行顺序不能乱:建用户 → 设 PROFILE → 配配额 → 授权限
权限脚本里混着 GRANT 和 ALTER USER,但实际执行必须按依赖顺序来,否则会报 ORA-01918: user does not exist 或 ORA-01917: user or role 'XXX' does not exist。
- 先跑
GET_DDL('USER', ...)创建用户骨架 - 再执行
PROFILE相关语句(含CREATE PROFILE和ALTER USER ... PROFILE) - 然后是
QUOTA语句 - 最后才是四类
GET_GRANTED_DDL输出的权限语句(它们之间无强依赖,可合并执行)
最容易被忽略的是:所有这些步骤里,用户名大小写、SET LONG 值、以及 DEFAULT_ROLE 是否显式设置,三者只要错一个,生成的脚本表面能跑通,但新用户行为就会异常——比如能登录却查不了任何表,或者建表成功但插入时报配额超限。











