Tuesday, October 18, 2005
DBMS_SCHEDULER executando .BAT
Com a versão 10g é possível executar arquivos de lote no Windows (.BAT) através do Oracle. Especificamente através da nova package DBMS_SCHEDULER. É muito importante a leitura e entendimento desta package para seu uso.
No exemplo abaixo, precisei recorrer ao metalink para conseguir a execução. O que acontece é que o arquivo .bat nada mais é que um arquivo texto não executável (talvez a Oracle tenha negligenciado isso, porque .bat é realmente executável - pelo menos para o mundo Windows). Para contornar esse desvio, usaremos a ajuda do c:\windows\system32\cmd.exe. O número do "bug" no metalink é 3824718.
O Exemplo é simples. Basicamente dois arquivos .bat - O primeiro teste.bat tem o que queremos executar como tarefa e o test2.bat vai disparar o primeiro. No Unix não há essa bagunça. Por que? Ora, basta um chmod a+x ./nome_arquivo e pronto qualquer usuário pode executar o nome_arquivo, porque ele realmente tornou-se um executável, essa facilidade não existe no mundo Windows.
Os arquivos lote.
Vamos entender o que o teste.bat vai fazer. Copiar ele mesmo para outro arquivo chamado teste_funcionou no diretório e:\temp - isso vai mostrar que o .bat realmente funcionou. Note que estamos enviando a saída do comando copy ("1 file(s) copied.") para nul (NUL com um 'L' só porque isso aqui é Windows).
O test2.bat é usado como gatilho, apenas dispara o teste.bat e guarda a saída em command.output.
Agora, rodando o exemplo:
Nada do commando.output nem do teste_funcionou, lembre-se de que a criação desses arquivos mostra o sucesso da execução.
Como se pode notar acima, a execução do .bat aconteceu corretamente.
Adendo #1 - 26/Out/2005.
Estou desenvolvendo um pequeno sistema de administração de orçamentos domésticos e pretendo fazer o deploy tanto em Linux quanto Windows e tive que usar a dica acima, digamos, "em produção" quero dizer - minha produção. E o que eu melhorei da dica acima foi o .bat de disparo. Eu fiz um só bat que dispara qualquer outro através de parâmetro %1 e adicionei um argumento a mais na chamada da dbms_scheduler.
No exemplo abaixo, precisei recorrer ao metalink para conseguir a execução. O que acontece é que o arquivo .bat nada mais é que um arquivo texto não executável (talvez a Oracle tenha negligenciado isso, porque .bat é realmente executável - pelo menos para o mundo Windows). Para contornar esse desvio, usaremos a ajuda do c:\windows\system32\cmd.exe. O número do "bug" no metalink é 3824718.
O Exemplo é simples. Basicamente dois arquivos .bat - O primeiro teste.bat tem o que queremos executar como tarefa e o test2.bat vai disparar o primeiro. No Unix não há essa bagunça. Por que? Ora, basta um chmod a+x ./nome_arquivo e pronto qualquer usuário pode executar o nome_arquivo, porque ele realmente tornou-se um executável, essa facilidade não existe no mundo Windows.
Os arquivos lote.
ops$marcio@WIN10GR2> host type teste.bat
copy e:\temp\teste.bat e:\temp\teste_funcionou > nul
ops$marcio@WIN10GR2> host type test2.bat
c:\windows\system32\cmd.exe /c e:\temp\teste.bat > e:\temp\command.output
Vamos entender o que o teste.bat vai fazer. Copiar ele mesmo para outro arquivo chamado teste_funcionou no diretório e:\temp - isso vai mostrar que o .bat realmente funcionou. Note que estamos enviando a saída do comando copy ("1 file(s) copied.") para nul (NUL com um 'L' só porque isso aqui é Windows).
O test2.bat é usado como gatilho, apenas dispara o teste.bat e guarda a saída em command.output.
Agora, rodando o exemplo:
ops$marcio@WIN10GR2> host dir
Volume in drive E is New Volume
Volume Serial Number is 0C49-8771
Directory of E:\temp
10/19/2005 12:07 AM <DIR> .
10/19/2005 12:07 AM <DIR> ..
10/18/2005 11:39 PM 598 schedemo.sql
10/18/2005 10:36 PM 2,197 t.sql
10/18/2005 11:34 PM 76 test2.bat
10/18/2005 11:38 PM 54 teste.bat
4 File(s) 2,925 bytes
2 Dir(s) 56,558,862,336 bytes free
Nada do commando.output nem do teste_funcionou, lembre-se de que a criação desses arquivos mostra o sucesso da execução.
ops$marcio@WIN10GR2> begin
2 dbms_scheduler.create_job (
3 job_name => 'teste_scheduler',
4 job_action => 'C:\WINDOWS\SYSTEM32\CMD.EXE',
5 number_of_arguments => 3,
6 job_type => 'executable',
7 enabled => false
8 );
9
10 dbms_scheduler.set_job_argument_value('teste_scheduler',1,'/q');
11 dbms_scheduler.set_job_argument_value('teste_scheduler',2,'/c');
12 dbms_scheduler.set_job_argument_value('teste_scheduler',3,'e:\temp\test2.bat');
13
14 dbms_scheduler.enable('teste_scheduler');
15 end;
16 /
PL/SQL procedure successfully completed.
ops$marcio@WIN10GR2>
ops$marcio@WIN10GR2> set echo off
ops$marcio@WIN10GR2> host dir
Volume in drive E is New Volume
Volume Serial Number is 0C49-8771
Directory of E:\temp
10/19/2005 12:12 AM <DIR> .
10/19/2005 12:12 AM <DIR> ..
10/19/2005 12:12 AM 78 command.output
10/18/2005 11:39 PM 598 schedemo.sql
10/18/2005 10:36 PM 2,197 t.sql
10/18/2005 11:34 PM 76 test2.bat
10/18/2005 11:38 PM 54 teste.bat
10/18/2005 11:38 PM 54 teste_funcionou
6 File(s) 3,057 bytes
2 Dir(s) 56,558,862,336 bytes free
ops$marcio@WIN10GR2>
Como se pode notar acima, a execução do .bat aconteceu corretamente.
Adendo #1 - 26/Out/2005.
Estou desenvolvendo um pequeno sistema de administração de orçamentos domésticos e pretendo fazer o deploy tanto em Linux quanto Windows e tive que usar a dica acima, digamos, "em produção" quero dizer - minha produção. E o que eu melhorei da dica acima foi o .bat de disparo. Eu fiz um só bat que dispara qualquer outro através de parâmetro %1 e adicionei um argumento a mais na chamada da dbms_scheduler.