Banco de Dados

24 out, 2018

Criando procedures e funções em Oracle PL/SQL baseadas em classes Java

Publicidade

A linguagem de programação Oracle PL/SQL, além de seus recursos nativos, possibilita a criação de procedures e funções utilizando programas externos escritos nas linguagens Java e C, permitindo estender a própria linguagem PL/SQL e promover a reutilização de código que, normalmente, já foi testado e está aderente ao negócio.

Os passos para escrever uma procedure ou função em PL/SQL baseada em uma classe Java são os seguintes:

  • 1. Preparar o arquivo Java, que pode estar em um dos seguintes formatos: .java, .class ou .jar;
  • 2. Carregar o arquivo Java no Oracle Database;
  • 3. Publicar a classe Java carregada no Oracle Database por meio de uma procedure ou função em PL/SQL;
  • 4. Testar a procedure ou função PL/SQL criada com base na classe Java.

Há duas formas de carregar um arquivo Java no Oracle Database:

  • Utilizar a procedure interna DBMS_JAVA.LoadJava;
  • Ou utilizar o utilitário de linha de comando loadjava ($ORACLE_HOME/bin/loadjava).

Para ilustrar este artigo, criarei duas funções em PL/SQL, cada uma baseada em uma classe Java. Uma para validação e outra para formatação de CPF.

Os softwares que utilizei para redigir este artigo, são:

Vamos lá!

1. Privilégios requeridos

Os privilégios de sistema requeridos, são:

  • Create Procedure
  • Create Table

Atenção! O privilégio Create Table somente será requerido se o carregamento de arquivos Java no Oracle Database for feito utilizando o utilitário de linha de comando loadjava ($ORACLE_HOME/bin/loadjava).

2. Regras para classes Java que serão utilizadas em PL/SQL

As regras para classes Java que serão utilizadas na criação de procedures e funções em PL/SQL, são:

  • Métodos da classe Java que serão invocadas via PL/SQL devem ser estáticos;
  • Métodos da classe Java que serão invocados via PL/SQL não devem propagar exceções;
  • Versão do código Java da classe deve ser compatível com a versão da JVM do Oracle Database.

Dica! Para verificar a versão da JVM instalada no Oracle Database, execute a seguinte consulta:

Select DBMS_JAVA.Get_OJVM_Property(PROPSTRING=>'java.version') From dual;

3. Carregando classes Java no Oracle Database

Como já disse acima, há duas formas para carregar um arquivo Java no Oracle Database – utilizar a procedure interna DBMS_JAVA.LoadJava ou o utilitário de linha de comando loadjava. Porém, para utilizar o utilitário de linha de comando loadjava, você precisará ter o software de banco de dados Oracle Database instalado em sua máquina ou executá-lo diretamente no servidor.

Já a procedure interna DBMS_JAVA.LoadJava pode ser invocada utilizando um IDE, como o Oracle SQL Developer, a partir de qualquer estação de trabalho, sem a necessidade de ter o software de banco de dados Oracle Database instalado localmente.

Para ilustrar, carregarei um arquivo .jar (Utils.jar) contendo duas classes Java – Validacao e Formatacao – no Oracle Database, demonstrando a utilização dos dois métodos.

3.1. Carregando classes Java utilizando a procedure interna DBMS_JAVA.LoadJava

Para carregar arquivos Java no Oracle Database utilizando DBMS_JAVA.LoadJava, será necessário:

  • Que o arquivo Java a ser carregado esteja localizado no servidor;
  • Que o DBA conceda ao seu esquema/usuário de banco de dados, além do privilégio Create Procedure, também a permissão de leitura do arquivo Java a ser carregado; esta concessão é feita utilizando a procedure DBMS_JAVA.Grant_Permission, logado como SYS;

Para carregar o arquivo Java Utils.jar, localizado no servidor em /home/oracle/Utils.jar, no esquema de banco de dados SoftLog, o DBA deverá, logado como SYS, invocar a procedure interna DBMS_JAVA.Grant_Permission passando os seguintes argumentos:

Call DBMS_JAVA.Grant_Permission(
	Grantee => ‘SOFTLOG’
	,Permission_Name => ’/home/oracle/Utils.jar’
	,Permission_Type => ’SYS:java.io.FilePermission’
	,’read’
);
/

Agora, basta logar no banco de dados como usuário SoftLog, e fazer o carregamento do arquivo Java no Oracle Database invocando a procedure interna DBMS_JAVA.LoadJava passando os seguintes argumentos:

Call DBMS_JAVA.LoadJava(‘-v -r /home/oracle/Utils.jar’);
/

Pronto!

3.2. Carregando classes Java utilizando o utiltário de linha de comando loadjava

Para carregar arquivos Java no Oracle Database utilizando o utilitário de linha de comando loadjava ($ORACLE_HOME/bin/loadjava), será necessário:

  • Ter o software de banco de dados Oracle Database instalado em sua estação de trabalho ou, então, executá-lo diretamente no servidor;
  • Ter o arquivo Java a ser carregado localizado nesta mesma máquina;
  • O usuário do banco de dados que fará o carregamento do arquivo Java deverá ter os privilégios Create Procedure e Create Table;

A sintaxe do utilitário loadjava é a seguinte:

$ORACLE_HOME/bin/loadjava -u <Usuario_BD>/<Senha>@<IP_ou_Nome_Servidor>:<Porta_Listener>/<SID> -v -r <Nome_Arquivo_Java>

Portanto, para carregar no esquema de banco de dados SoftLog, o arquivo Java Utils.jar localizado localmente, utilizando o utilitário loadjava, basta executar na linha de comando de seu sistema operacional:

$ORACLE_HOME/bin/loadjava -u SoftLog/Pwd123@192.168.1.100:1521/orcl.adsdomain -v -r Utils.jar

Pronto!

3.3. Verificando se as classes Java foram carregadas com sucesso no Oracle Database

Após fazer o carregamento de arquivos Java no Oracle Database, verifique se as classes foram carregadas e resolvidas com sucesso. Esta verificação é feita consultando a tabela User_Objects. As classes carregadas devem ser listadas no resultado desta consulta e seus status devem ser VALID.

Select * From User_Objects;

Pronto! Se as classes Java foram carregadas e resolvidas com sucesso no Oracle Database, o próximo passo será publicar seus métodos por meio de procedures ou funções em PL/SQL.

4. Publicando classes Java com PL/SQL

Publicar uma classe Java em PL/SQL nada mais é do que mapear os seus métodos utilizando procedures ou funções em PL/SQL. A seguir, mapearei em PL/SQL as duas classes Java, Validacao e Formatacao, carregadas no item anterior.

  • Publicando o método validarCPF da classe Validacao utilizando uma função em PL/SQL:

Classe Java:

public class Validacao {
	public static boolean validarCPF(String cpf) {
		boolean resultado = false;
		
		// Esta parte do código foi omitida para simplificar...
		
		return resultado;
	}
}

Função em PL/SQL:

Create Or Replace Function Validar_CPF(P_CPF VarChar2)
Return Number
As Language Java
Name ‘Validacao.validarCPF(java.lang.String) return java.lang.boolean’;
/
  • Publicando o método formatarCPF da classe Formatacao utilizando uma função em PL/SQL:

Classe Java:

public class Formatacao {
	public static String formatarCPF(String cpf) {
		String resultado = cpf;
		
		// Esta parte do código foi omitida para simplificar...
		
		return resultado;
	}
}

Função em PL/SQL:

Create Or Replace Function Formatar_CPF(P_CPF VarChar2)
Return VarChar2
As Language Java
Name ‘Formatacao.formatarCPF(java.lang.String) return java.lang.String’;
/

Agora, basta testar as funções em PL/SQL baseadas nas classes Java:

Select Formatar_CPF('12345678900') CPF, Validar_CPF('12345678900') Valido From dual;

Pronto!

5. Recomendações

Para encerrar este artigo, recomendo as seguintes boas práticas em desenvolvimento em Oracle PL/SQL:

  • Sempre organize suas procedures e funções PL/SQL em pacotes;
  • Defina o nível de segurança adequado de seus pacotes, procedures e functions em PL/SQL utilizando a clásula AuthID;
  • Em ambientes de produção, melhore a performance de subprogramas em PL/SQL utilizando Native Compilation (NCOMP).

Para mais informações sobre o tema deste artigo, consulte a documentação oficial da Oracle.

Bom trabalho!