AJUDA: Buscar dados no Oracle

8 respostas
A

Gostaria de saber porque não consigo retornar os dados do Oracle, o programa chega a imprimir até a mensagem "teste 1", depois imprime o seguinte erro: ORA-00903: nome de tabela inválido. Digitei a select (SELECT "descricao" FROM "Produto") no Oracle, e retornou os dados certinhos, e quando retirei as aspas duplas foi verificado que aparece o mesmo erro do que quando executado no programa.

Já trabalhei muito no MySQL, e agora estou fazendo uns teste no Oracle, mais acabei garrando nessa etapa. Se alguém souber me explicar o motivo, desde já agradeço.

import java.sql.*;
import oracle.jdbc.pool.OracleDataSource;

public class Oracle {
    public static void main(String args[]) {
        try {
            Connection con;
            Statement stm;
            ResultSet rs;
            OracleDataSource ds = new OracleDataSource();
            ds.setURL("jdbc:oracle:thin:@127.0.0.1");
            con = ds.getConnection("arthur", "123");
            stm = con.createStatement();
            System.out.println("teste 1");
            rs = stm.executeQuery("SELECT 'descricao' FROM 'Produto'");
            System.out.println("teste 2");
            while (rs.next()) {
                System.out.println(rs.getObject(1).toString());
            }
        } catch (Exception e) {
            System.out.println("erro: "+e.getMessage());
        }
    }
}

8 Respostas

G

Olá!

Me diz uma coisa pra que aquelas aspas na coluna e na tabela? Retire-as e teste novamente.

Abraços

A

deixei dessa seguinte forma

e apareceu o mesmo erro.

G

Olá!

Você é o owner dessa tabela? Se não for tente colocar nome_do_owner.produto ou crie um synonym para ter acesso sem ter que digitar o owner create public synonym produto for nome_do_owner.produto e se esse for o caso terá que dar permissão grant select on produto to seu_nome_usuario.

A

sim, sou o owner.

tentei refazer o código utilizando a procedure criada no oracle:
create or replace procedure SELECIONAR
(descr OUT VARCHAR2)
is
begin
SELECT "descricao"
INTO descr
FROM "Produto";
end;
e o seguinte código em java:
import java.sql.*;
import oracle.jdbc.pool.OracleDataSource;

public class Oracle {
    public static void main(String args[]) {
        try {
            Connection con;
            CallableStatement cs;
             OracleDataSource ds = new OracleDataSource();
            ds.setURL("jdbc:oracle:thin:@127.0.0.1");
            con = ds.getConnection("arthur", "123");
            cs = con.prepareCall("{CALL selecionar(?)}");
            cs.registerOutParameter(1, Types.VARCHAR);
            cs.execute();
        } catch (Exception e) {
            System.out.println("erro: "+e.getMessage());
        }
    }
}
mais apresenta o seguinte erro: ORA-01422: a extração exata retorna mais do que o número solicitado de linhas

se acrescentar na procedure WHERE "codigo"=123456, ai dá certo, mais desta forma só conseguo retornar um resultado. Gostaria de saber como faço pra retornar várias linhas da tabela com procedure?

C

Pra uma procedure retornar mais de um resultado de um select, só se ela retornar um cursor.
Mas, voltando ao select: vc já colocou o nome do seu usuário na frente da tabela?
tipo:

Coloca em capslock, pq o Oracle é chato com isso…

A

Consegui aqui. Eu refiz as tabelas a mão, da outra vez tinha feito pela interface do Oracle, mais quando faz utilizando a interface gráfica, ela cria as tabelas e os campos da tabela entre aspas, ai quando executa no programa da o erro, já criando na mão não necessita das aspas.

Muito obrigado pela as ajudas.

Mais como ficaria essa minha procedure com cursor?? É bom que eu aprendo de duas formas!

G

Olá!

Bom ai complica um pouco mas nem tanto :D
Em vez de retornar o select como você estava fazendo tem que retornar um cursor pode ser com um procedure ou uma function...

Procedure que retornará um RecordSet, Pode usar tanto o SYS_REFCURSOR (a partir do 9i) quanto o REF CURSOR a diferença é que o você não precida declarar o REF CURSOR a uma variavel caso for criar um procedure/function sem estar em uma package por exemplo
CREATE OR REPLACE PROCEDURE GETPRODUTOSBYID (P_PROID IN PRODUTOS.PROID%TYPE, P_CURSOR OUT SYS_REFCURSOR) AS 
BEGIN 
  OPEN P_CURSOR FOR
    SELECT PROID, PRODES
    FROM PRODUTOS
    WHERE PROID = PPROID;
END GETPRODUTOSBYID;
/
Agora com java é so usar CallableStatement e um ResultSet normalmente
Connection con = ... // pega a conexão de alguma forma;
  CallableStatement cstmt = null;
  ResultSet rs = null;
  int proid = 1;
  Object obj;

  try{
      cstmt = conn.prepareCall("BEGIN  GETPRODUTOSBYID(?,?); END;");
      cstmt.setInt(1, proid);
      // Registra o tipo do segundo parametro como um CURSOR parecido como o do java.sql.Types
      cstmt.registerOutParameter(2, OracleTypes.CURSOR);
      cstmt.execute();

      rs = (ResultSet) cstmt.getObject(2);

      while (rs.next()){
            ... rs.getInt(1);
            ... rs.getString(2);
      }

  } catch (SQLException e) {
      ... 
  } finally {
      ... 
  }
Outra forma é utilizar-se das classes da Oracle para poder trabalhar o retorno com cursores reais mesmo.
Connection con = ... // pega a conexão de alguma forma;
  OracleCallableStatement oracstmt = null; // Oracle class
  OracleResultSet orars = null; // Oracle class
  int proid = 1;

  try{
      // o que muda é exatamente neste cast
      oracstmt = (OracleCallableStatement) conn.prepareCall("BEGIN  GETPRODUTOSBYID(?,?); END;");
      oracstmt.setInt(1, proid);
      // Registra o tipo do segundo parametro como um CURSOR parecido como o do java.sql.Types
      oracstmt.registerOutParameter(2, OracleTypes.CURSOR);
      oracstmt.execute();
      // outro cast e repare que a chamda é getCursor e não Object
      orars = (OracleResultSet) oracstmt.getCursor(2);

      while (orars.next()){
            ... orars.getInt(1);
            ... orars.getString(2);
      }
  } catch (SQLException e) {
      ... 
  } finally {
      ... 
  }
Onde trabalho utilizamos muitos cursores (dinamicos ou não) mas com muita cautela pois a abertura de muitos cursores interfere diretamente no desempenho.

Testa ai e poste o resultado.

Abraços

A

Conseguir fazer com procedute com cursor.

Segue para quem quiser aprender.

Procedure com cursor:
create or replace procedure SELECIONAR
(descr OUT SYS_REFCURSOR)
is
begin
OPEN descr FOR
SELECT descricao
FROM produto;
end;
Código java:
import java.sql.*;
import oracle.jdbc.pool.OracleDataSource;
import oracle.jdbc.OracleTypes;

public class Oracle {
    public static void main(String args[]) {
        try {
            Connection con;
            CallableStatement cs;
            ResultSet rs;
            OracleDataSource ds = new OracleDataSource();
            ds.setURL("jdbc:oracle:thin:@127.0.0.1");
            con = ds.getConnection("arthur", "123");
            cs = con.prepareCall("call selecionar(?)");
            cs.registerOutParameter(1, OracleTypes.CURSOR);
            cs.execute();
            rs = (ResultSet) cs.getObject(1);
            while (rs.next()) {
                System.out.println(rs.getString(1));
            }
        } catch (Exception e) {
            System.out.println("erro: "+e.getMessage());
        }
    }
}

Muito obrigado Granella!!

Criado 6 de setembro de 2009
Ultima resposta 11 de set. de 2009
Respostas 8
Participantes 3