DevMedia - asp.net, Java, Delphi, SQL e web Design, tudo em um só lugar!
Bem vindo a DevMedia!
LOGIN:     SENHA:
 
 

Fórum DevMedia


Autor
Mensagem
NILO SOUZA
 


País: Brasil
Estado: MG
Cidade: MINAS GERAIS
Mensagens: 200
 Postado em: 28/5/2011 12:26:00 PM

Colega, tenho a classe abaixo que funciona perfeitamente como select. A mesma é do curso do Dyego sobre Desvendando o swing. Com o select tudo bem, como disse, mas eu gostaria de trabalha com procedure. 
Tem como adaptar? Minha conexao é com Oracle


[COD]
package treinamento.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;


public abstract class GenericaDao {

     private static final long serialVersionUID = 1L;

    public Connection getConnection() {
        try {
                  
           
           Class.forName("oracle.jdbc.OracleDriver");
           Connection cx = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","teste","teste");
          
           return cx;
        } catch (Exception ex) {
            Logger.getLogger(GenericaDao.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public Statement getStatement() throws SQLException {
        return getConnection().createStatement();
    }

    public PreparedStatement getStatement(String st) throws SQLException {
        return getConnection().prepareStatement(st);
    }

    public ResultSet executeQuery(String query,Object... params) throws SQLException {
        PreparedStatement ps = getStatement(query);
        for (int i = 0; i < params.length; i++) {
            ps.setObject(i+1, params[i]);
        }
        return ps.executeQuery();
    }

    public int executeCommand(String query,Object... params) throws SQLException {
        PreparedStatement ps = getStatement(query);
        for (int i = 0; i < params.length; i++) {
            try {
            ps.setObject(i+1, params[i]);
            } catch (Exception e) {
                System.out.println("Error to try "+i+" with value "+params[i]);
            }
        }
        int result = ps.executeUpdate();
        ps.close();
        return result;
    }
 

}
[/CODE]

 
Anthony Accioly
 

 


País: Brasil
Estado: SP
Cidade: São Paulo
Mensagens: 157
 Postado em: 28/5/2011 06:21:06 PM

Nilo.

Tem sim.
A API JDBC Possui CallableStatements (http://download.oracle.com/javase/6/docs/api/java/sql/CallableStatement.html) para fazer exatamente isso:

A sintaxe funciona assim:
#Código
{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}


Eis um exemplo de código fonte: http://www.java2s.com/Code/Java/Database-SQL-JDBC/CallStoredProcedureInOracleAndPassInOutParameters.htm

Para recuperar um cursor do Stored Procedure você vai ter que registrá-lo com a sequinte sintaxe antes de recuperar o ResultSet:
#Código
registerOutParameter(<nome-do-cursor>, OracleTypes.CURSOR);


Eis um exemplo: http://www.andrels.com/wp-en_US/index.php/2010/01/retieving-an-oracle-cursor-in-java/

Espero ter ajudado.

Abraços,
NILO SOUZA
 


País: Brasil
Estado: MG
Cidade: MINAS GERAIS
Mensagens: 200
 Postado em: 28/5/2011 06:56:09 PM

Achei que fosse mais simples, precisarei estudar mais.

Anthony Accioly
 

 


País: Brasil
Estado: SP
Cidade: São Paulo
Mensagens: 157
 Postado em: 28/5/2011 07:47:29 PM

Nilo,

Ok. Tendo uma dúvida mais específica pode perguntar.
No geral o CallableStatement é muito parecido com o PreparedStatement que você está usando nesse código.
Se você chegou a dar uma olhada no último exemplo, seu uso é bastante direto:
#Código

//Calling Oracle procedure
CallableStatement cs = conn.prepareCall("{call PAC_CURSOR.PRO_RETURN_CARS(?,?)}");

//Defining type of return
cs.registerOutParameter("o_cursor", OracleTypes.CURSOR);
cs.setLong("i_id", id);

cs.execute();//Running the call

//Retrieving the cursor as ResultSet
ResultSet rs = (ResultSet)cs.getObject("o_cursor");

//Iterating the returned rows
while(rs.next()){
    //Getting column values
    System.out.println("ID: " + rs.getLong("car_id"));
    System.out.println("Manufacturer: " + rs.getString("company"));
    System.out.println("Model: " + rs.getString("model"));
    System.out.println("Color: " + rs.getString("color"));
    System.out.println("HP: " + rs.getString("hp"));
    System.out.println("Price: " + rs.getFloat("price"));
}


Eu não gosto muito desse padrão de sair percorrendo var-args de Objects e chamando setObject por índice (apesar de muitos frameworks fazerem isso...). Porém, é possível fazer uma adaptação trivial do seu método executeQuery para fazer o que você quer. Apenas troque a versão para obter uma CallableStatement da conexão, sete o parâmetro de saída para o cursor, faça uma chamada para execute e obtenha o  ResultSet a partir do cursor. Tudo como no exemplo acima.
NILO SOUZA
 


País: Brasil
Estado: MG
Cidade: MINAS GERAIS
Mensagens: 200
 Postado em: 28/5/2011 10:10:36 PM

Caro,
se comecei a entender comecei a trilhar desse jeito.

MINHA CLASSE DE PROCEDURE GENERICA

[CODE]

package treinamento.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;


public abstract class GenericaDao_Proc {

     private static final long serialVersionUID = 1L;

    public Connection getConnection() {
        try {
                     
          
           Class.forName("oracle.jdbc.OracleDriver");
           Connection cx = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","TESTE","TESTE");

          
           return cx;
        } catch (Exception ex) {
            Logger.getLogger(GenericaDao_Proc.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public Statement getStatement() throws SQLException {
        return getConnection().createStatement();
    }

    public PreparedStatement getPrepared(String st) throws SQLException {
        return getConnection().prepareStatement(st);
    }
   
   
    public CallableStatement getCallableStatement(String st) throws SQLException{
               
        return getConnection().prepareCall(st);
    }
   
  
    public ResultSet executeQuery(String query,Object... params) throws SQLException {
        PreparedStatement ps = getPrepared(query);
        for (int i = 0; i < params.length; i++) {
            ps.setObject(i+1, params[i]);
        }
        return ps.executeQuery();
    }
   
   
    public int executePrepered(String query,Object... params) throws SQLException {
        PreparedStatement ps = getCallableStatement(query);
        for (int i = 0; i < params.length; i++) {
            try {
            ps.setObject(i+1, params[i]);
            } catch (Exception e) {
                System.out.println("Error to try "+i+" with value "+params[i]);
            }
        }
        int result = ps.executeUpdate();
        ps.close();
        return result;
    }   

    public int executeCommand(String query,Object... params) throws SQLException {
        PreparedStatement ps = getPrepared(query);
        for (int i = 0; i < params.length; i++) {
            try {
            ps.setObject(i+1, params[i]);
            } catch (Exception e) {
                System.out.println("Error to try "+i+" with value "+params[i]);
            }
        }
        int result = ps.executeUpdate();
        ps.close();
        return result;
    }

}


[/CODE]


MINHA CLASSE DAO PARA INSERIR, ALTERAR E EXCLUIR

[CODE]

package treinamento.dao;


import  treinamento.entidade.Usuario;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
/**
 *
 * @author Nilo
 */
public class Usuario_Proc_Dao extends GenericaDao_Proc{

      private static final long serialVersionUID = 1L;

      public Usuario_Proc_Dao(){

      }    
          
     
      public void addUsuarioProc(Usuario usr) throws SQLException {       
         
          String query = "{ call sp_restricoes(?,?,?,?,?,?,?) }";
          executePrepered(query, usr.getNome(), usr.getLogin(), usr.getSenha(),usr.getId_grupo(),usr.getUsuario_incluir(),usr.getUsuario_altera());
         
      }
      

   public Usuario getUsuario(int idUsuario) throws SQLException {
        ResultSet rs = executeQuery("SELECT * FROM USUARIO WHERE IDUSUARIO = ?", idUsuario);
        Usuario usr = null;
        if (rs.next()) {
            usr = populateUsuarioInfo(rs);
        }
        rs.close();
        return usr;
    }

    public List<Usuario> getAllUsuarios() throws SQLException {
        ResultSet rs = executeQuery("SELECT * FROM USUARIO");
        List<Usuario> toReturn = new LinkedList<Usuario>();
        while (rs.next()) {
            toReturn.add(populateUsuarioInfo(rs));
        }
        rs.close();
        return toReturn;
    }

    public static Usuario populateUsuarioInfo(ResultSet rs) throws SQLException {
        Usuario toReturn = new Usuario();
        toReturn.setIdUsuario(rs.getInt("IDUSUARIO"));
        toReturn.setLogin(rs.getString("LOGIN"));
        toReturn.setNome(rs.getString("NOME"));
        toReturn.setSenha(rs.getString("SENHA"));
        toReturn.setId_grupo(rs.getInt("ID_GRUPO"));
        toReturn.setUsuario_incluir(rs.getInt("USUARIO_INCLUI"));
        toReturn.setUsuario_altera(rs.getInt("USUARIO_ALTERA"));
        return toReturn;
    }

}
[/CODE]

NILO SOUZA
 


País: Brasil
Estado: MG
Cidade: MINAS GERAIS
Mensagens: 200
 Postado em: 28/5/2011 10:27:09 PM

Fiz um teste e me retorno o problema abaixo, se puderem me ajudar. Desde já grato!

classe de teste
[CODE]

 @Test
    public void testAddUsuarioProc() throws Exception {
        System.out.println("addUsuarioProc");
        Usuario usr = new Usuario();
        usr.setNome("Nilo Souza");
        usr.setLogin("nsouza9");
        usr.setSenha("123");
        usr.setId_grupo(1);
        usr.setUsuario_incluir(5);
        Usuario_Proc_Dao instance = new Usuario_Proc_Dao();
        instance.addUsuarioProc(usr);
       
    }

[/CODE]

METODO DA CLASSE DAO
[CODE]

public void addUsuarioProc(Usuario usr) throws SQLException {       
         
          String query = "{ call sp_restricoes(?,?,?,?,?,?,?) }";
          executePrepered(query,0, usr.getNome(), usr.getLogin(), usr.getSenha(),usr.getId_grupo(),usr.getUsuario_incluir(),'I');
         
      }

[/CODE]


MENSAGEM DE ERRO DO TESTE
[CODE]

Testsuite: treinamento.dao.Usuario_Proc_DaoTest
addUsuarioProc
Error to try 6 with value I
Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 1,43 sec

------------- Standard Output ---------------
addUsuarioProc
Error to try 6 with value I
------------- ---------------- ---------------
Testcase: testAddUsuarioProc(treinamento.dao.Usuario_Proc_DaoTest):    Caused an ERROR
Parâmetro IN ou OUT ausente do índice:: 7
java.sql.SQLException: Parâmetro IN ou OUT ausente do índice:: 7
    at oracle.jdbc.driver.OraclePreparedStatement.processCompletedBindRow(OraclePreparedStatement.java:1821)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3571)
    at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3657)
    at oracle.jdbc.driver.OracleCallableStatement.executeUpdate(OracleCallableStatement.java:4739)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1350)
    at treinamento.dao.GenericaDao_Proc.executePrepered(GenericaDao_Proc.java:70)
    at treinamento.dao.Usuario_Proc_Dao.addUsuarioProc(Usuario_Proc_Dao.java:30)
    at treinamento.dao.Usuario_Proc_DaoTest.testAddUsuarioProc(Usuario_Proc_DaoTest.java:55)


Test treinamento.dao.Usuario_Proc_DaoTest FAILED
test:
Deleting: /tmp/TEST-treinamento.dao.Usuario_Proc_DaoTest.xml
BUILD SUCCESSFUL (total time: 2 seconds)


[/CODE]
Davi Gomes da Costa
 

 


País: Brasil
Estado: CE
Cidade: Fortaleza
Mensagens: 1770
 Postado em: 28/5/2011 11:16:08 PM

Na sua chamada vc usou:

public void addUsuarioProc(Usuario usr) throws SQLException {       
         
          String query = "{ call sp_restricoes(?,?,?,?,?,?,?) }";
          executePrepered(query, usr.getNome(), usr.getLogin(), usr.getSenha(),usr.getId_grupo(),usr.getUsuario_incluir(),usr.getUsuario_altera());
         
      }



Mas aparentemente no seu teste vc não instancio todos esse atributos.


@Test
    public void testAddUsuarioProc() throws Exception {
        System.out.println("addUsuarioProc");
        Usuario usr = new Usuario();
        usr.setNome("Nilo Souza"); // confere
        usr.setLogin("nsouza9"); //confere
        usr.setSenha("123");//confere
        usr.setId_grupo(1);//confere
        usr.setUsuario_incluir(5);//confere
        // mas o usr.getUsuario_altera()?
        Usuario_Proc_Dao instance = new Usuario_Proc_Dao();
        instance.addUsuarioProc(usr);
       
    }



Att Davi



NILO SOUZA
 


País: Brasil
Estado: MG
Cidade: MINAS GERAIS
Mensagens: 200
 Postado em: 29/5/2011 08:30:40 AM


  Fiz conforme orientou e ficou desde jeito dando o erro abaixo: 

Metodo alterado

[CODE]
public void addUsuarioProc(Usuario usr) throws SQLException {        
          
          String query = "{ call sp_restricoes(?,?,?,?,?,?,?) }";
           executePrepered(query,usr.getIdUsuario(), usr.getNome(), usr.getLogin(), usr.getSenha(),usr.getId_grupo(),usr.getUsuario_incluir(),usr.getOpr());
          
      }
[/CODE]


Classe teste alterada
[CODE]
 @Test
    public void testAddUsuarioProc() throws Exception {
        System.out.println("addUsuarioProc");
        Usuario usr = new Usuario();
        usr.setIdUsuario(0);
        usr.setNome("Nilo Souza");
        usr.setLogin("nsouza9");
        usr.setSenha("123");
        usr.setId_grupo(1);
        usr.setUsuario_incluir(5);
        usr.setUsuario_altera(2);
        Usuario_Proc_Dao instance = new Usuario_Proc_Dao();
        instance.addUsuarioProc(usr);
        
    }
[/CODE]


Erro ao testar a classe

[CODE]
Testsuite: treinamento.dao.Usuario_Proc_DaoTest
addUsuarioProc
Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 1,775 sec

------------- Standard Output ---------------
addUsuarioProc
------------- ---------------- ---------------
Testcase: testAddUsuarioProc(treinamento.dao.Usuario_Proc_DaoTest): Caused an ERROR
ORA-06550: linha 1, coluna 7:
PLS-00306: número incorreto de tipos de argumentos na chamada para 'SP_RESTRICOES'
ORA-06550: linha 1, coluna 7:
PL/SQL: Statement ignored

java.sql.SQLException: ORA-06550: linha 1, coluna 7:
PLS-00306: número incorreto de tipos de argumentos na chamada para 'SP_RESTRICOES'
ORA-06550: linha 1, coluna 7:
PL/SQL: Statement ignored

at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:440)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:440)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:837)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:445)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:191)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:523)
at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:204)
at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:1007)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1315)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3576)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3657)
at oracle.jdbc.driver.OracleCallableStatement.executeUpdate(OracleCallableStatement.java:4739)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1350)
at treinamento.dao.GenericaDao_Proc.executePrepered(GenericaDao_Proc.java:70)
at treinamento.dao.Usuario_Proc_Dao.addUsuarioProc(Usuario_Proc_Dao.java:30)
at treinamento.dao.Usuario_Proc_DaoTest.testAddUsuarioProc(Usuario_Proc_DaoTest.java:57)


Test treinamento.dao.Usuario_Proc_DaoTest FAILED
test:
Deleting: /tmp/TEST-treinamento.dao.Usuario_Proc_DaoTest.xml
BUILD SUCCESSFUL (total time: 3 seconds)
[/CODE]



Anthony Accioly
 

 


País: Brasil
Estado: SP
Cidade: São Paulo
Mensagens: 157
 Postado em: 29/5/2011 11:24:17 AM

Nilo,

Se esse é aquele procedure que você postou no fórum de Oracle, veja que ele só tem três argumentos. Não se esqueça de anotar os parâmetros com IN.

#Código

PROCEDURE sp_restricoes(
ptabela    IN      NUMBER, 
popr         IN    VARCHAR2, 
pusuario  IN       VARCHAR2)


Nessa caso você teria que passar um número e duas Strings para a chamada do procedure.
#Código
String query = "{ call sp_restricoes(?,?,?) }


Você pode setar tanto por posição quanto nome conforme exemplos anteriores.

Abraços
NILO SOUZA
 


País: Brasil
Estado: MG
Cidade: MINAS GERAIS
Mensagens: 200
 Postado em: 29/5/2011 12:44:29 PM

Era isso mesmo, funcionou. 
Muito obrigado mais uma vez!!
Um grande abraço a todos!!
web-03
DevMedia  |  Anuncie  |  Fale conosco
Hospedagem web por Porta 80 Web Hosting
2013 - Todos os Direitos Reservados a web-03