Oracle e suas peripécias

22/outubro/2010 - Oracle

Olá

Hoje o Oracle me deu um baile, como faço todos os dias, estava eu tranquilo fazendo minha procedure PL/SQL quando de repente começo a obter esse erro:

LINE/COL ERROR
-------- ------------------------------------------
167/17   PL/SQL: ORA-00984: column not allowed here
160/7    PL/SQL: SQL Statement ignored

Olho aqui, olho lá, leio e releio as linha indicadas mas nada de ter uma luz para resolver esse problema. Resolvo criar o teste no PLSQL Developer (ver abaixo) com o trecho em torno da linha 167 mas o erro continua:

declare
  -- Local variables here
  i integer;
  --num_iden number;
  --num_cli number;
begin
  -- Test statements here
  insert into cad_endereco
    (num_cli_ende,
     cod_ende_ende,
     num_iden_ende,
     cod_ende_ende,
     cod_situ_ende,
     data_ende,
     usu_ende)
  values
    (num_cli,
     '0001',
     num_iden,
     '0001',
     'EN',
     '01',
     sysdate,
     user);
end;

Como o quantidade de código diminui e o scroolbar sumiu percebi que as variáveis num_cli e num_iden não estavam declaradas, lógico que não iria funcionar.
Visto isso, criei as benditas variáveis (no código acima estão comentadas). E não é que funcionou!!!

Poxa vida!! Não dava para me mostrar uma mensagem mais intuitiva do tipo a variável num_cli não está criada seu idiota??!! Mas com um column not allowed here é pra acabar com o meu dia. Já vi erro cuja mensagens não era assim uma beleza, mas essa ganhou disparado.

[desabafo mode="off"]

Até mais,
Roberto

IsNumber em Oracle PL/SQL

05/fevereiro/2010 - Oracle

Olá

Existem duas formas de verificar se uma string contém um número válido. A primeira forma é usando as funções translate, trim e length. Quando usadas em conjunto você obtém null se a string for número ou o comprimento da string sem espaços em branco. Veja abaixo:

 select

length(trim(translate('minha_variavel', ' +-0123456789.', ' '))) n1,

length(trim(translate('123456789.9999', ' +-0123456789.', ' '))) n2

from dual;

O resultado dessa query é:

N1    N2
14    null

Outra forma é usando a função to_number().  Caso a string passada contiver caracteres não numéricos é lançada uma exceção.


declare
n number;
s varchar2(10);
begin
s :=  '1236';
n :=  to_number(s);
dbms_output.put_line('É número');
exception when others then
dbms_output.put_line('Não é número');
end;

Olá!

Para quem quer saber um pouco mais sobre BPEL e a ferramenta Oracle SOA Suite escrevi um artigo sobre eles.

Introdução ao BPEL utilizando o Oracle SOA Suíte 10g

Disponibilizei o web service utilizado no artigo nesse endereço http://www.furutani.com.br/CalculadoraServices/services/Calculadora?wsdl

Os fontes podem ser baixados clicando em CalculadoraServices.war e aqui.

Espero que ajude.

Até mais,
Roberto

Olá

Sabia que há a possibilidade de passar um objeto Java para dentro de uma procedure ou function do Oracle ?

Dica do blog do André LS.

Até mais,
Roberto

Olá!
No banco de dados Oracle, além de guardar dados é possivel criar rotinas para manipulá-los. A linguagem default é o PL/SQL mas é possivel criar rotinas em Java.
Teoricamente é possível usar todos os recursos da linguagem e de mais algumas tecnologias como Java Mail, JMS, fazer chamadas a EJBs. Acredito que só não seja possível usar classes de interface gráfica (JFrame, JPanel e etc.).
No caso do JavaMail é preciso que o objeto tenha um grant especial senão ele conseguirá enviar os emails.
Abaixo um exemplo de classe que executa um update em uma tabela de paramêtros.

create or replace and compile java source named
Parametro as

import java.sql.*;
import oracle.jdbc.driver.*;

public class Parametro {
  public static java.lang.String
                            atualizarParam(java.lang.String codigo,
                                                java.lang.String valor)
                                                throws SQLException { 

    // Obtem um conexão com o banco de dados
    Connection conn = new OracleDriver().defaultConnection();

    String sql = "UPDATE tab_param SET " +
                    "vlr_par = ? WHERE cod_param = ?";

    // Todos os parametros devem estar preenchidos
    if (codigo == null || valor == null){
       return "Parametros nulo";
    }

    try {

      PreparedStatement pstmt = conn.prepareStatement(sql);
      pstmt.setString(1, valor);
      pstmt.setString(2, codigo);
      pstmt.executeUpdate();
      pstmt.close();
      conn.commit();

    } catch (SQLException e) {
        return e.getMessage();
    }

    return "OK";
  }
}

Como não é possível chamar a classe Java diretamente, preciamos criar uma função PL/SQL encarregada de invocar o método da classe Java.

create or replace function fun_atualizar(codigo varchar2, valor varchar2)
  return varchar2 is
  LANGUAGE JAVA NAME 'Parametro.atualizarParam(java.lang.String, java.lang.String) return java.lang.String';

Código para testar a função.

declare
     retorno varchar2(500);
begin
     retorno := fun_atualizar('parametro','valor');

     dbms_output.put_line(retorno);

exception
     when others then
        dbms_output.put_line('Erro -> ' || sqlerrm);
end;

Caso ocorrer esse erro:

ORA-29531: no method atualizarParam in class Parametro

Verifique se os tipo dos paramêtros na function atualizar estão corretos, por exemplo:
- Se o nome das classes estão completos. Ao invés de String deve estar java.lang.String;
- Se os tipos primitivos estão todas em minúsculas. No lugar de Int deve ser int ou FLOAT deve ser float.

Até mais