我在Oracle中创建了一些新用户。但是,当运行sqlplus时,它们都需要完全限定查询中的表名。为这些新用户设置默认架构的最佳方法是什么?
我在Oracle中创建了一些新用户。但是,当运行sqlplus时,它们都需要完全限定查询中的表名。为这些新用户设置默认架构的最佳方法是什么?
Answers:
set search_path
在Oracle中,没有什么比PostgreSQL更好的了。
我能想到的最接近的东西是运行 ALTER SESSION SET CURRENT_SCHEMA ...
CREATE OR REPLACE TRIGGER LOGON_TRG
AFTER LOGON ON SCHEMA
BEGIN
EXECUTE IMMEDIATE 'ALTER SESSION SET CURRENT_SCHEMA = foobar';
EXCEPTION
when others
then null; -- prevent a login failure due to an exception
END;
/
如果用户列表不太长,则可以创建数据库登录触发器,因此不必为每个用户创建该触发器:
CREATE OR REPLACE TRIGGER LOGON_TRG
AFTER LOGON ON DATABASE
BEGIN
if (user in ('TOM', 'DICK', 'HARRY')) then
EXECUTE IMMEDIATE 'ALTER SESSION SET CURRENT_SCHEMA = foobar';
end if;
exception
when others
then null; -- prevent a login failure due to an exception
END logon_trg;
/
当然,您也可以从表中获取要更改默认架构的用户列表。在那种情况下,您只需要从那里插入或删除行即可“激活”此功能(而不是每次都重新创建触发器)。
另一种选择是在每次创建用户时创建指向实际表的同义词。您可以使用存储过程自动执行该过程,该存储过程循环遍历一个模式中的所有表,并在另一模式中为其创建同义词。
除非您所有的Oracle用户都在同一个表上工作,否则我强烈建议您不要使用只能创建一次的公共同义词-如果安装中存在不同的应用程序用户,它们会引起很多麻烦。
编辑:
按照Alex的建议,这是一个登录触发器,它检查角色而不是用户名:
CREATE OR REPLACE TRIGGER LOGON_TRG
AFTER LOGON ON DATABASE
declare
has_role boolean;
BEGIN
has_role := dbms_session.is_role_enabled('FOOBAR_ROLE');
if (has_role) then
EXECUTE IMMEDIATE 'ALTER SESSION SET CURRENT_SCHEMA = foobar';
end if;
exception
when others
then null; -- prevent a login failure due to an exception
END logon_trg;
/
when others then null;
是一个包罗万象的东西,它将使故障排除变得很复杂,因为它使任何错误都变得不可见。也许完全删除异常处理或将错误记录在自治事务中的服务器上,然后重新引发它?