Como definir o esquema padrão de um usuário Oracle?

12

Criei alguns novos usuários no Oracle. No entanto, ao executar o sqlplus, todos precisam qualificar totalmente os nomes das tabelas na consulta. Qual é a melhor maneira de definir um esquema padrão para esses novos usuários?

um cavalo sem nome
fonte

Respostas:

19

Não há nada como o PostgreSQL set search_pathno Oracle.

A coisa mais próxima que consigo pensar seria um gatilho de logon para o usuário que executa uma 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;
/  

Se a lista de usuários não for muito longa, você poderá criar um gatilho de logon no banco de dados para não precisar criar esse gatilho para cada usuário:

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;
/  

Obviamente, a lista de usuários em que você deseja alterar o esquema padrão também pode ser obtida de uma tabela. Nesse caso, você só precisa inserir ou excluir linhas de lá para "ativar" esse recurso (em vez de recriar o gatilho toda vez).

Outra opção seria criar sinônimos sempre que você criar um usuário que aponte para as tabelas reais. Você pode automatizar isso usando um procedimento armazenado que percorre todas as tabelas em um esquema e cria os sinônimos para eles no outro esquema.

A menos que todos os usuários do Oracle trabalhem nas mesmas tabelas, eu não recomendaria o uso de sinônimos públicos que você precisaria criar apenas uma vez - eles podem causar muitos problemas se existirem diferentes usuários de aplicativos em sua instalação.

Editar :

Seguindo a sugestão de Alex, aqui está um gatilho de logon que verifica a função em vez de um nome de usuário:

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;
/
um cavalo sem nome
fonte
Ótima idéia, mas como when others then null;é um exemplo, complicará a solução de problemas, pois torna qualquer erro invisível. Talvez remova completamente a manipulação de exceções ou registre o erro no servidor em uma transação AUTÔNOMO e depois a RAISE novamente .
George3
@ George3: mas se a exceção for realmente lançada, o usuário não poderá fazer login - eu só queria impedir que alguém não pudesse fazer login apenas por causa de um estúpido erro no gatilho. Mas qualquer um é livre para adaptar isso ao que quiser.
a_horse_with_no_name
0

Eu não acho que existe uma maneira de definir um. O usuário é o esquema. AFAIK, você pode definir apenas o espaço de tabela padrão.

cljk
fonte