Job no Oracle

Fala PessoALL,

Atendendo a pedidos, hoje falaremos sobre Job’s no Oracle.
Do que se trata? Job’s são tarefas que são “scheduladas” (agendadas) no Oracle para rodar numa determinada hora que você estipula.

Como assim? Bom, vamos aos exemplos:

Suponha que você tem um sistema na sua empresa de controle de acesso, ele é quem gera os crachás para os funcionários entrarem na empresa. No sistema de RH, é onde são cadastrados os meus funcionários… e agora? Tenho que fazer os dois sistemas conversarem. Geralmente essa “conversa” é feita através de arquivos, chamados EDI (eletronic Data Interchange) e seu sistema de RH teria que gerar esses arquivos diariamente durante a noite com todas as pessoas Admitidas e Demitidas para que o sistema de crachá leia este arquivo e habilite ou desabilite o acesso do funcionário. Como fazer?

Criamos um JOB para gerar este arquivo “na calada da noite”.

Num JOB você diz as rotinas que vão ser executadas, que podem ser códigos direto com blocos de PL/SQL, ou podem ser chamadas Procedures ou Packages que executam as rotinas que você precisa.

Suponhamos mais uma vez, que neste nosso exemplo, precisamos de um JOB que chame a procedure: Pr_Gera_Arq_Mov_Funcionarios, e este JOB precisa gerar este arquivo às 22:00, porque às 23:00 o sistema de controle de acesso vai ler o arquivo gerado. Pronto… cenário montado, vamos criar o JOB.

Como criamos um JOB? Temos no banco de dados Oracle uma Package que faz todo controle e manipulação dos JOB’s no banco, o nome dela é DBMS_JOB, e é ela que vamos utilizar para criar nosso JOB. Como fazemos isso? Com blocos de PL/SQL, simples e rápido, assim:


declare
--Declare variável que recebe número do JOB.
job_num binary_integer;
begin
--Cria o JOB no banco e retorna o número dele job_num
dbms_job.submit(job_num,
'begin Pr_Gera_Arq_Mov_Funcionarios; end;',
to_date('10/06/2009, 22:00', 'dd/mm/yyyy hh24:mi'),
'sysdate + 1');
end;

Vamos explicar….

A rotina dbms_job.submit(...) exige 2 parâmetros como obrigatórios, são eles:
job, que é um parâmetro OUT, ou seja, a rotina vai retornar um valor para a variável que estiver neste local, no nosso caso é o número do JOB.
what que é uma string que diz para o banco que rotinas o JOB vai executar, note que este parâmetro é uma string e tem que conter um bloco PL/SQL, ou seja, tem que ter begin...end; e tudo mais.

Os outros dois parâmetros passados neste caso, para a rotina dbms_job.submit(...) não são obrigatórios, eles são responsáveis por dizer que data o JOB vai rodar a próxima vez (next_date) e com que intervalo vai rodar novamente (interval), não são obrigatórios porque na package dbms_job existe diversas outras procedures que manipulam os JOB’s e entre elas está dbms_job.next_date(...) e dbms_job.interval(...) (entre outras), nestas rotinas é necessário informar o número do JOB e o valor que você deseja atribuir para estes atributos.

Observe que o tempo todo falamos de “número do JOB”, é isso mesmo. No Oracle, os JOB’s são identificados por números, não tem como atribuirmos nomes aos JOB’s (nem tudo é perfeito), por isso, na rotina que cria o JOB ele exige uma variável para receber o número que foi atribuído ao JOB.

Depois do seu JOB criado, você pode fazer alterações no bloco que o JOB executa, na próxima vez que ele vai rodar, no intervalo e etc, tudo usando as procedures da package dbms_job.

Para listar os JOB’s criados no seu banco de dados, bem como ver os seus Status, ultimas execuções, Status de execução, Próxima vez que vai rodar e etc, podemos dar um select na view user_jobs. E se ainda, quisermos saber que JOB’s estão sendo executados neste exato momento, podemos dar um select na tabela dba_jobs_running, mas para esta segunda você precisa ter privilégios de DBA.

Espero ter sido claro e tomara que este post seja útil.
Qualquer dúvida não deixe de enviar um comentário ou até mesmo e-mail que descobrimos juntos as respostas.

Abraços à todos.

Atc.
Gerson Júnior
gerson.vasconcelos@gmail.com

6 ideias sobre “Job no Oracle

  1. Gerson Júnior

    Pessoal, estou publicando aqui uma duvida tirada por e-mail do nosso amigo Marinho!

    Segue:

    DUVIDA – MARINHO

    Olá,

    Eu preciso programar no banco a execução de um job para que dispare uma determinada procedure todo dia 20 de outubro de cada ano às 5h00min am. Ou seja, uma determinada procedure deve ser executada somente uma vez por ano nessa data e hora específicas.

    Há como fazer essa programação através da DBMS_JOB?

    Att.


    Marinho

    MINHA RESPOSTA – GERSON
    Olá Marinho,

    Tem jeito sim.
    A forma de criar o JOB é do mesmo jeito, o que vai diferenciar neste caso é a data que o JOB vai iniciar (NEXT_DATE) e o intervalo que ele vai rodar novamente (INTERVAL) definindo de uma forma que retorne pra você o mesmo dia que ele rodou (20/10) às 05:00 só que no próximo ano.

    Testa isso aqui:

    declare
    n_job binary_integer;
    begin
    dbms_job.submit(n_job,
    'declare n number; begin select 1 into n from dual; end;',
    to_date('20/10/2009 05:00', 'DD/MM/YYYY HH24:MI'),
    'add_months(to_date(to_char(sysdate, ''DD/MM/YYYY'')||'' 05:00'', ''DD/MM/YYYY HH24:MI''), 12)'
    );

    end;

    Só que no segundo parâmetro entra a tua procedure e sai esse bloco anônimo que coloquei aí pra testar.

    Espero que te ajude.

    Depois dá um retorno se ficou beleza.

    RESPOSTA – MARINHO
    Camarada, funcionou como uma luva.

    Muito obrigado mesmo!

    []
    ———————————

    Atc.
    Gerson Júnior
    (gerson.vasconcelos@gmail.com)

    Responder
  2. Varela

    Garotão,
    sobre Jobs uma das maiores dúvidas recaem sobre o código para as regras de periodicidade.
    Você poderia dar exemplos para todas o tipos de regras, tipo: Rodar todos os dias as 08:00h e 20:00, rodar todas as Terças e Quitas a 01:00, Rodar todo dia tal, hora, e aí vai.

    Abraço.
    Alessandro Varela.

    Responder
  3. oracle Autor do post

    Pessoal,

    Mais uma dúvida tirada por e-mail… segue para que caso alguém tenha a mesma dúvida.


    Boa Tarde,

    Estava pesquisando na internet e verifiquei um documento seu com explicação sobre jobs.

    Estou precisando criar um job, porém o mesmo só poderá rodar uma vez, ou seja, não posso programar a próxima data de execução.

    Você sabe se existe algum parâmetro para isso?

    Pensei em criar e depois que rodado eu excluir, porém também não posso fazer isso por normas do cliente. Só posso criar e depois não poderei mais mexer até o ano que vem.

    Aguardo retorno.

    Att,
    Rodolfo Mielitz

    Minha resposta:


    Você pode tornar o job broken… ou seja, você diz pro banco que ele não vai mais executar.

    Por exemplo:

    begin
    dbms_job.broken(999, true);
    end;

    Onde 999 é o numero do teu Job. Isso diz pro banco que o Job está “quebrado” e assim ele fica inativo. Caso queira ativá-lo novamente, você altera o broken pra False!

    Espero que te ajude.

    Abraço.

    Vou postar tua dúvida e a resposta como comentário no blog ok? Caso mais alguém tenha essa dúvida, já tá lá!

    Depois diz se funcionou.

    Atc.
    Gerson S. de Vasconcelos Júnior
    DBA Oracle / Oracle Certified (IZ0-007)
    Fone: (81) 9103-4984 / (82) 9119-0640
    Msn: gerson.vasconcelos@gmail.com
    Skype: gersonvjunior
    http://www.diaadiaoracle.com.br/

    Abraços a todos!

    Responder
  4. oracle Autor do post

    ———MINHA RESPOSTA————
    Opa Rodrigo,

    Obrigado pela visita.

    Bom, quanto a seu problema, creio que a chamada da procedure no caso 1 está correto!
    O que está errado é que a procedure DBMS_JOB.SUBMIT tem um parâmetro OUT e voce está passando valor, portanto deve estar dando erro na criação do JOB. Voce tem que criar uma variável, e quem atribui o nome (na verdade o número) do Job é o banco, e não voce. Portanto voce não tem como estabelecer esse 3000 aí como sendo o numero do seu Job.

    O correto ficaria assim:

    declare
    v_num_job binary_integer;
    begin
    dbms_job.isubmit(v_num_job,

    ‘DECLARE x NUMBER; BEGIN INSERIR_CONTATO_MAILING(7942,X); END;’,
    sysdate,
    ‘sysdate + 1’,
    false);
    end;

    Faz o teste e diz se funcionou.

    Grande abraço!

    Atc.
    Gerson S. de Vasconcelos Júnior
    OCA DBA – Oracle Certified Associate
    Fone: (81) 9103-4984
    Msn: gerson.vasconcelos@gmail.com
    Skype: gersonvjunior
    http://www.diaadiaoracle.com.br/

    ————-EMAIL RECEBIDO————-
    Em 28 de junho de 2010 10:56, Rodrigo Dias escreveu:

    Ola pesquisando sobre job achei um artigo seu e gostaria de saber se pode me dar uma ajuda

    Estou criando um job aqui no meu banco, a stored procedure que eu disparo tem 2 parametros 1 de entrada e 1 de saida

    crio o job assim

    begin
    dbms_job.isubmit(3000,’DECLARE x NUMBER; BEGIN INSERIR_CONTATO_MAILING(7942,X); END;’,sysdate, ‘sysdate + 1′,false);
    end;

    mas da erro, e qndo coloco assim

    begin
    dbms_job.isubmit(3000,’DECLARE x NUMBER; BEGIN INSERIR_CONTATO_MAILING(:7942,X); END;’,sysdate, ‘sysdate + 1’,false);
    end;

    adicionando os “:” antes do meu parametro da procedure ele compila mas nao executa a minha procedure

    Vc sabe me dizer como faço pra passar parametro pra minha procedure…???

    obs. a procedure inserir_contato-mailing qndo executada na mao funciona, ja testei ela, soh qndo eh startada pelo job que nao funciona

    Obrigado ….

    Responder
  5. Eduardo

    Blz cara?
    eu dei uma lida no artigo, mas nao estou entendo muito bem. Eu acho que o essa função serve para o meu caso, mas nao eu conseguindo aplicar.

    Eu preciso montar um script que rode todo dia, as 7:00 am e o resultado será salvo em uma pasta em Excel.

    Sou novo no mundo Oracle, to apanhando um pouco, agradeço se puder me ajudar!

    Responder

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *