Oracle数据库中有列权限(Column Privileges)吗? 相信不少老司机都会对这个权限感到陌生. 无它,只是用得少而已,而且Oracle关于列权限的控制有点奇怪.甚至有点奇葩,没有诋毁的意思,而是就事论事. 下面请见浅析, 仅代表个人观点.
首先,这个权限并不像你想象的那样.可以控制列的查询(只对某些列授予查询权限给其它用户), 这个是不存在的.而像SQL Server数据库是有这项功能的.
SQL Server可以给用户授予相关列的查询权限(SELECT), 更多关于SQL Server列权限的介绍,可以查看我的这篇博客SQL Server 关于列的权限控制
GRANT SELECT(BusinessEntityID, NationalIDNumber, LoginID) ON [HumanResources].[Employee] TO [UserA]
但是Oracle数据库没有这个功能. 如下所示
SQL> SHOW USER;
USER is "TEST"
SQL> GRANT SELECT(OBJECT_ID, OBJECT_NAME) ON TEST.T2 TO TEST1;
GRANT SELECT(OBJECT_ID, OBJECT_NAME) ON TEST.T2 TO TEST1
*
ERROR at line 1:
ORA-00969: missing ON keyword
SQL>
其实并不是我的SQL语法有问题,而是实际上(到目前为止),Oracle就没有这个功能,官方文档关于列权限(Column Privileges)的阐述如下所示
column
Specify the table or view column on which privileges are to be granted. You can specify columns only when granting the INSERT, REFERENCES, or UPDATE privilege. If you do not list columns, then the grantee has the specified privilege on all columns in the table or view.
For information on existing column object grants, query the USER_, ALL_, or DBA_COL_PRIVS data dictionary view.
Oracle数据库的列权限(Column Privileges)只能对列授予INSERT,UPDATE,REFERENCES这三种权限.也就是说不能对表/视图的相关列进行SELECT授权. 下面简单演示一下
用户TEST授予用户TEST1对表T2的列(OBJECT_ID, OBJECT_NAME)更新的权限
SQL>
SQL> SHOW USER;
USER is "TEST"
SQL> GRANT UPDATE(OBJECT_ID, OBJECT_NAME) ON TEST.T2 TO TEST1;
Grant succeeded.
SQL>
用户TEST授予用户TEST1对表T2的列(OBJECT_ID, OBJECT_NAME)插入的的权限
SQL> SHOW USER;
USER is "TEST"
SQL> GRANT INSERT(OBJECT_ID, OBJECT_NAME) ON TEST.T2 TO TEST1;
Grant succeeded.
SQL>
那么要如何回收这些授予的权限呢?
SQL> SHOW USER;
USER is "TEST"
SQL> REVOKE UPDATE(OBJECT_ID, OBJECT_NAME) ON TEST.T2 FROM TEST1;
REVOKE UPDATE(OBJECT_ID, OBJECT_NAME) ON TEST.T2 FROM TEST1
*
ERROR at line 1:
ORA-01750: UPDATE/REFERENCES may only be REVOKEd from the whole table, not by
column
关于错误ORA-01750的解释如下所示:
$ oerr ora 01750
01750, 00000, "UPDATE/REFERENCES may only be REVOKEd from the whole table, not by column"
// *Cause: Although it was possible to GRANT update privileges on a
// column-by-column basis, it was only possible to REVOKE them for
// an entire table.
// *Action: Do not identify specific columns. To revoke update
// privileges for certain columns, use REVOKE for the entire
// table and GRANT the user privileges for specific columns.
上面解释得非常清楚了. 也就是说关于列权限(UPDATE),只能对整个表进行回收.
SQL> SHOW USER;
USER is "SYS"
SQL> REVOKE UPDATE ON TEST.T2 FROM TEST1;
Revoke succeeded.
SQL> REVOKE INSERT ON TEST.T2 FROM TEST1;
Revoke succeeded.
SQL>
总结
关于Oracle数据库中有列权限(Column Privileges),没有授予指定列的查询权限功能, 其实这个才是列权限最有价值的功能, 没有这个功能,那么只能通过视图来间接实现这个功能了. 另外, 列权限的权限回收也是透漏着别扭. 让人有点懵.