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
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.