A história é recorrente: o desenvolvedor mandou para você  um mega script (ou um pacote com dezenas deles) para rodar no banco de dados Oracle. Em 99% dos casos o desenvolvedor vai dizer que o script precisa ser executado com você conectado no banco de dados utilizando o usuário XYZ, que é o dono dos objetos que vão ser criados/alterados/apagados.

Aí o que o DBA faz? Pega a senha do usuário numa listinha “cuidadosamente” guardada e roda o script em questão. Então, pare e pense: qual é o problema nisso?

Ok, você é um DBA esperto… muitos anos de praia, já sabe que existem outras alternativas:

Então qual é o procedimento que 10 entre 10 DBAs experientes utilizam? Simples:

ALTER SESSION SET current_schema=foo;

Simples assim. O esquema padrão passa a ser foo. Todos os objetos criados, alterados e apagados serão neste esquema.

Mas calma, existem alguns problemas sim: alguns comandos não trabalham bem com outro CURRENT_SCHEMA. Um deles é a criação de DB Links. Não é possível criar um DB Link para outro esquema, você tem de estar realmente conectado com o usuário em questão para criar este DB Link. Claro que você não cria DB Links no ambiente de produção com frequência (pela sua sanidade mental, eu espero que não). DB Links públicos não tem esse problema, é claro. Outro problema é a criação de JOBs com o DBMS_JOB. Você pode utilizar o DBMS_IJOB, para contornar este problema ou pelo bem da humanidade migrar para o Scheduler.

Bom, de qualquer forma é sempre obrigação do DBA revisar os scripts, verificar os parâmetros de Storage, etc.

OBS: Este post é dedicado a um DBA velho de guerra que ainda guarda velhos hábitos dos tempos que era desenvolvedor e insiste em me trazer mais problemas do que soluções.

OBS2: No PostgreSQL existe uma não conformidade com o padrão SQL (você pode trabalhar no padrão se quiser, mas não vejo vantagem) que permite que os usuários e os esquemas não sejam diretamente relacionados.  Então esta cultura ruim do Oracle não é tão comum entre os desenvolvedores/DBAs do PostgreSQL. Além disso o PostgreSQL tem o SEARCH_PATH que é mais refinado que o CURRENT_SCHEMA, e os comandos DDL permitem a troca do dono de qualquer objeto (que não seja um objeto de sistema, claro).

Para aqueles que ainda precisam utilizar o DBMS_JOB e precisam criar JOBs para outro usuário, segue uma dica de como fazer, utilizando o DBMS_IJOB.SUBMIT. O DBMS_IJOB.REMOVE é fácil de utilizar, mas para criar um novo JOB, você vai precisar passar todos os parâmetros, como em:

DECLARE
    job_num number;
    nlsvar varchar2(4000);
    envvar raw(32);
BEGIN
    SELECT nls_env,misc_env
        INTO nlsvar,envvar
        FROM dba_jobs
        WHERE
            rownum<2 and
            nls_env is not null and
            misc_env is not null;
    SELECT max(job)+1
        INTO job_num
        FROM dba_jobs;
    sys.dbms_ijob.submit(         job=>job_num,
        luser=>'MEU_USUARIO',
        puser=>'MEU_USUARIO',
        cuser=>'MEU_USUARIO',
        what=>'meu_usuario.roda_procedure_xyz;',
        next_date=>TRUNC(SYSDATE),
        interval=>'TRUNC(SYSDATE) + 1',
        broken=>FALSE,
        nlsenv=>nlsvar,
        env=>envvar);
    dbms_output.put_line(job_num);
END;
/
COMMIT;

Já aqueles que desejam criar um DB LINK privado, a única alternativa é recorrer ao DBMS_SYS_SQL, que assim como o DBMS_IJOB não está na documentação oficial:

DECLARE
    uid number;
    sqltext varchar2(1000) := 'CREATE DATABASE LINK test_dblink
CONNECT TO dblink_user IDENTIFIED BY dblink_user_password
USING ''nome_da_base_no_tnsnames''';
    myint integer;
BEGIN
    SELECT user_id INTO uid FROM all_users WHERE username LIKE 'SCOTT';
    myint:=sys.dbms_sys_sql.open_cursor();
    sys.dbms_sys_sql.parse_as_user(myint,sqltext,dbms_sql.native,UID);
    sys.dbms_sys_sql.close_cursor(myint);
END;
/

Note que você pode utilizar o DBMS_SYS_SQL para rodar qualquer comando SQL como outro usuário. No exemplo, estamos utilizando o usuário SCOTT.

Uma resposta

Deixe uma resposta