Fórum Classe Generica trabalhando com stored procedure #401911

28/05/2011

0

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]
 
Nilo Souza

Nilo Souza

Responder

Posts

28/05/2011

Anthony Accioly

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ódigoregisterOutParameter(<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,
Responder

Gostei + 0

28/05/2011

Nilo Souza

Achei que fosse mais simples, precisarei estudar mais.
Responder

Gostei + 0

28/05/2011

Anthony Accioly

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:
//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.
Responder

Gostei + 0

28/05/2011

Nilo Souza

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

MINHA CLASSE DE PROCEDURE GENERICA


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;     } }



MINHA CLASSE DAO PARA INSERIR, ALTERAR E EXCLUIR


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;     } }


Responder

Gostei + 0

28/05/2011

Nilo Souza

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

classe de teste

 @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);
        
    }



METODO DA CLASSE DAO

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');
          
      }




MENSAGEM DE ERRO DO TESTE

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)



Responder

Gostei + 0

28/05/2011

Davi Costa

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



Responder

Gostei + 0

29/05/2011

Nilo Souza


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

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());                }


Classe teste alterada
 @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);            }


Erro ao testar a classe
Testsuite: treinamento.dao.Usuario_Proc_DaoTestaddUsuarioProcTests run: 1, Failures: 0, Errors: 1, Time elapsed: 1,775 sec
------------- Standard Output ---------------addUsuarioProc------------- ---------------- ---------------Testcase: testAddUsuarioProc(treinamento.dao.Usuario_Proc_DaoTest):	Caused an ERRORORA-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 FAILEDtest:Deleting: /tmp/TEST-treinamento.dao.Usuario_Proc_DaoTest.xmlBUILD SUCCESSFUL (total time: 3 seconds)



Responder

Gostei + 0

29/05/2011

Anthony Accioly

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.

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.
String query = "{ call sp_restricoes(?,?,?) }


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

Abraços
Responder

Gostei + 0

29/05/2011

Nilo Souza

Era isso mesmo, funcionou. Muito obrigado mais uma vez!!Um grande abraço a todos!!
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar