Oracle:对另一个用户的架构的只读访问权限?

我有一个架构和一个同名的用户: products 。 对于开发,我想在Java应用程序中以只读模式使用它。 因此,我为只读应用程序创建了一个新用户。

 CREATE USER PRODUCTS_READONLY IDENTIFIED BY PRODUCTS_READONLY; GRANT CREATE SESSION to PRODUCTS_READONLY; BEGIN FOR tab IN (SELECT table_name FROM all_tables WHERE owner = 'PRODUCTS') LOOP EXECUTE IMMEDIATE 'GRANT SELECT ON PRODUCTS.'||tab.table_name||' TO PRODUCTS_READONLY'; END LOOP; END; 

运行应用程序我得到表不存在的错误。 在互联网上搜索解决方案,我遇到了SYNONYM 。 所以我添加了架构的同义词:

 CREATE SYNONYM PRODUCTS_READONLY FOR PRODUCTS; 

现在,我在我的java应用程序中收到此错误:

ERROR org.hibernate.util.JDBCExceptionReporter - ORA-17074 invalid name pattern.: PRODUCTS_READONLY.PRODUCT_TYPE

我的方法出了什么问题?

–UPDATE–

似乎在10g中删除了为schema创建同义词( Oracle:是否可以为模式创建同义词? )。 如果我为目标模式中的每个对象创建模式,那么每次将表添加到目标模式或对目标模式中的任何其他对象进行任何其他更改时,我都必须执行相同的操作。 这听起来很麻烦……

– 更新2–

看起来像一个带有alter session的触发器是一个可能的解决方案,但它会使表只读,只要用户只有SELECT权限吗?

如果您可以控制应用程序的连接方式(例如连接池的初始化语句),那么您需要做的就是运行:

 ALTER SESSION SET CURRENT_SCHEMA = PRODUCTS; 

从那时起(在会话的生命周期内),将在PRODUCTS模式中搜索任何不合格的对象名称。

所有给予PRODUCTS_READONLY拨款都将生效。 会话将在用于登录的原始用户的凭据(和安全性限制)下运行。

如果您无法更改建立或初始化连接的方式,则登录触发器也应该完成此操作:

 create or replace trigger logon_trg after logon on database begin if (user = 'PRODUCTS_READONLY') then execute immediate 'alter session set current_schema = products'; end if; exception when others then null; -- prevent a login failure due to an exception end logon_trg; / 

请注意,捕获任何exception都至关重要,因为否则执行的SQL中的潜在错误将有效地将所有人从数据库中记录下来。 因此,在将其投入生产之前,要小心使用并进行测试。

我不确定您是否可以为架构创建同义词。

但您可以为远程模式中的每个对象创建一个同义词,例如

 begin for c in (select t.table_name from table_privileges t where grantee = 'PRODUCTS_READONLY') loop execute immediate 'create synonym '||c.table_name||' for PRODUCTS.'||c.table_name; end loop; end; 

不要与table_name混淆,它处理那里的所有类型的对象。