ORA-00990表示权限名错误或对象不存在,非权限不足;常见原因包括使用非法权限名(如DROP TABLE)、对象名大小写/拼写错误、缺失ON子句、跨schema未加前缀、转授权无GRANT OPTION、误用GRANT ALL等。

GRANT语句报ORA-00990:权限名写错了
ORA-00990不是权限不足,而是SQL语法层面的“权限名不存在”——Oracle压根不认你写的那个权限。比如GRANT DROP TABLE TO user_name会直接报错,因为DROP TABLE根本不是合法的系统权限;真正可用的是DROP ANY TABLE。
常见错误写法与正确写法对照:
-
CREATE FUNCTION→ 错误,应改用CREATE PROCEDURE(该权限覆盖函数和过程) -
ALTER TABLE→ 错误,应改用ALTER ANY TABLE或对象级ALTER(需配合ON table_name) -
SELECT TABLE→ 错误,应改用SELECT ANY TABLE或对象级SELECT -
INSERT ON schema.table→ 缺少ON子句目标,必须写成GRANT INSERT ON schema.table TO user_name
授权目标对象不存在或拼写错误
ORA-00990也可能由ON子句后指定的对象引发,比如表名、视图名、序列名大小写不匹配,或未加双引号导致解析失败。
典型场景:
- 表名含小写字母但没用双引号:
GRANT SELECT ON "my_table" TO user_name✅,而GRANT SELECT ON my_table TO user_name❌(若建表时用了"my_table") - 跨schema访问时漏写schema前缀:
GRANT SELECT ON orders TO user_name报错,实际应为GRANT SELECT ON scott.orders TO user_name - 试图授权给一个不存在的表:
GRANT UPDATE ON nonexist_tab TO user_name→ 先确认SELECT table_name FROM all_tables WHERE table_name = 'NONEXIST_TAB'
用户没有执行GRANT所需的ADMIN OPTION或WITH GRANT OPTION
普通用户不能随意转授权限。如果你是用户A,想把B拥有的某张表的SELECT权再授给C,必须满足:B当初授给你时加了WITH GRANT OPTION;或者你是DBA/有GRANT ANY OBJECT PRIVILEGE系统权限。
否则会静默失败或报ORA-00990(尤其在某些Oracle版本中,错误提示不够精准)。
检查方式:
- 查自己是否被授予可转授的对象权限:
SELECT grantee, owner, table_name, privilege, grantable FROM dba_tab_privs WHERE grantee = 'YOUR_USER' AND grantable = 'YES' - 查是否有系统级授权能力:
SELECT privilege FROM user_sys_privs WHERE privilege LIKE '%GRANT%'
用ALL代替具体权限时要注意作用域
GRANT ALL ON table_name TO user_name看起来省事,但它只授予该对象上的所有**对象权限**(如SELECT/INSERT/UPDATE/DELETE/ALTER/INDEX/REFERENCES),不包括FLASHBACK或DEBUG等较新权限,更不会授予系统权限。
更重要的是:GRANT ALL ON table_name要求你对该表拥有ALL权限的**全部子集**——如果表上有列级授权(如只给了某几列的SELECT),ALL可能因权限不完整而失败。
稳妥做法:
- 明确列出需要的权限:
GRANT SELECT, INSERT, UPDATE ON t TO u - 避免对系统对象(如
SYS下的表)使用ALL,容易触发隐式限制 - 注意
GRANT ALL PRIVILEGES是系统权限语法,仅用于GRANT ALL PRIVILEGES TO user_name,不能带ON子句
ORA-00990本质是Oracle在解析阶段就拒绝执行,不涉及权限校验流程。最容易被忽略的是权限名大小写和空格——SELECTANYTABLE(无空格)和SELECT ANY TABLE(有空格)在部分客户端里会被自动截断或拼接,务必严格按官方文档的空格格式书写。


















