Como rodar um executavel a partir do oracle

Estava precisando executar um script no linux pelo oracle, e para que isso fosse possível, veio horas e horas de pesquisa.

Mas a partir desta pesquisa descobri que é possível sim executar um script do linux “.sh” ou um script do windows “.bat”

Para efetuarmos isso vamos precisar criar uma classe Java no nosso banco para executar os comandos. Vou chama-la de “OSCOMMAND”
Lembrando, que você deve ter memória para o java no banco para executar este comando.

CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "OSCommand" AS
import java.io.*;
public class OSCommand{
public static String Run(String Command){
try{
Runtime.getRuntime().exec(Command);
return("0");
}
catch (Exception e){
System.out.println("Error running command: " + Command +
"\n" + e.getMessage());
return(e.getMessage());
}
}
}
/

Agora vamos criar uma função para identificar se o comando executou com sucesso ou com erro.

CREATE or REPLACE FUNCTION OSCommand_Run(Command IN STRING)
RETURN VARCHAR2 IS
LANGUAGE JAVA
NAME 'OSCommand.Run(java.lang.String) return int';
/

Esta função acima vai retornar “0” caso tenha executado com sucesso.
Logo quando formos efetuar o teste de execução podemos executar algo semelhante com “if <> 0 then”, mas isso veremos logo a seguir.

Temos de efetuar grants para o usuário utilizar os comandos, logicamente estes grants deverão ser executados como “SYS”

Execute dbms_java.grant_permission('USUÁRIO','SYS:java.io.FilePermission','<>','execute');
Execute dbms_java.grant_permission('USUÁRIO','SYS:java.io.FilePermission','<>','writeFileDescriptor');
Execute dbms_java.grant_permission('USUÁRIO','SYS:java.io.FilePermission','<>','readFileDescriptor');
commit;

Vamos agora para a melhor parte:
Executando um scipt.

No caso abaixo eu vou executar um script propriamente dito, mas dentro dele vou executar um programa do próprio linux o famoso “echo” que também existe para windows.

Set Serverout On
Declare
x1 Varchar2(2000);
Begin
x1 := OSCommand_Run('/home/oracle/echo.sh');
DBMS_OUTPUT.Put_Line(x1);
End;
/

Testes:

[oracle@dbserver ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.2.0 Production on Thu Jun 21 20:37:28 2012

Copyright (c) 1982, 2010, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Release 11.2.0.2.0 - Production

SQL> create user lana identified by lana;

User created.

SQL> grant dba to lana;

Grant succeeded.

SQL> conn lana/lana
Connected.
SQL> CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "OSCommand" AS
import java.io.*;
public class OSCommand{
public static String Run(String Command){
try{
Runtime.getRuntime().exec(Command);
return("0");
}
catch (Exception e){
System.out.println("Error running command: " + Command +
"\n" + e.getMessage());
return(e.getMessage());
}
}
}
/

Java created.

SQL> CREATE or REPLACE FUNCTION OSCommand_Run(Command IN STRING)
RETURN VARCHAR2 IS
LANGUAGE JAVA
NAME 'OSCommand.Run(java.lang.String) return int';
/

Function created.

SQL>
SQL> conn / as sysdba
Connected.

SQL> Execute dbms_java.grant_permission('LANA','SYS:java.io.FilePermission','<>','execute');
Execute dbms_java.grant_permission('LANA','SYS:java.io.FilePermission','<>','writeFileDescriptor');
Execute dbms_java.grant_permission('LANA','SYS:java.io.FilePermission','<>','readFileDescriptor');
commit;

PL/SQL procedure successfully completed.

SQL>
PL/SQL procedure successfully completed.

SQL>
PL/SQL procedure successfully completed.

SQL>
Commit complete.

SQL>
SQL> conn lana/lana
Connected.

Todos os nossos procedimentos foram efetuados agora vamos criar o script

Criei um script em /home/oracle chamado echo.sh, e nele contem:

<pre>SQL> !cat echo.sh
#!/bin/bash
/bin/echo teste > /home/oracle/teste/teste_de_escrita.txt

SQL>

Agora vamos executa-lo

SQL> !ls -lrt /home/oracle/teste
total 0

SQL> Set Serverout On
Declare
x1 Varchar2(2000);
Begin
x1 := OSCommand_Run('/home/oracle/echo.sh');
DBMS_OUTPUT.Put_Line(x1);
End;
/
  0

PL/SQL procedure successfully completed.

SQL>
SQL> !ls -lrt /home/oracle/teste
total 4
-rw-r--r-- 1 oracle oinstall 6 Jun 21 20:54 teste_de_escrita.txt

Observe que no final do comando saiu como output o numero 0 (zero).
Isso que dizer que você efetuou o processo com sucesso.

No meu script eu fiz o seguinte controle.

if x1 <> 0 then
   dbms_output.put_line('Erro');
else
   dbms_output.put_line('Sucesso');
end if;

Porem com saídas mais adequadas ao que eu pretendia efetuar.

Espero ter ajudado.

Fonte:
OTN

%name Como rodar um executavel a partir do oracle

Autor: Leandro Lana

Trabalho com banco de dados Oracle desde 2006, já trabalhei com as plataformas 9i, 10G, 11G, 12C, 18C, 19C e 21(ainda em testes).

Trabalhando atualmente como consultor Oracle na MigraTI Soluções em TI como administrador de banco de dados Oracle, SQL-Server, MySQL e Postgresql.

Contato: leandro.lana@migrati.com.br

Fone: (47) 9191-6052 / (47) 3328 0996

Certificações:

OCA 10G.

OCP 10G.

OCE Linux.

OCE RAC/Cluster.

MCP SQL-Server 2008.

MCITP SQL-Server 2008.

DB2 Fundamentals.