Stored procedure selecionavel com Firebird

5 respostas
H

Alguem sabe usar stored procedures “selecionaveis” com firebird?

ou seja, procedures que retornam um ResultSet…

grato

Hübner

5 Respostas

T

Não sei, mas achei um exemplo:
http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_using_sps

H

Olá thingol,

Desculpe-me, acho que formulei a pergunta de forma erra.

Usar Storeds procedure com firebird é tranquilo. A pergunta seria como acessá-las via java?

algo tipo assim:

public List procuraTitulo(String titulo) throws Exception {
        CallableStatement cs = null;
        ResultSet rset = null;
        try {
            
            String sb = null;
          
            sb = "{CALL SP_LIVROS (1,'Literario','T','Início',?,'','','','','','','')}";                           
            
            cs = conn.prepareCall(sb);
            ((FirebirdCallableStatement)cs).setSelectableProcedure(true);  
            cs.setString(1,titulo);
            cs.execute();
            rset = cs.getResultSet();
            return RetornaLista(rset);  
                       
                 
        } finally {
            if (rset != null) try { rset.close(); } catch(Exception e) { }
            if (cs != null) try { cs.close(); } catch(Exception e) { }
        }
    
   }

o erro acontece nessa linha …

((FirebirdCallableStatement)stmt).setSelectableProcedure(true);

javax.servlet.ServletException: Exception while invoking action busca: com.mchange.v2.c3p0.impl.NewProxyCallableStatement / java.lang.ClassCastException / com.mchange.v2.c3p0.impl.NewProxyCallableStatement / java.lang.ClassCastException
	org.mentawai.core.Controller.service(Controller.java:533)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
	org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:368)


root cause 

java.lang.ClassCastException: com.mchange.v2.c3p0.impl.NewProxyCallableStatement
	bookshop.dao.BuscaDao.procuraTitulo(BuscaDao.java:94)
	bookshop.action.Busca.execute(Busca.java:47)
	org.mentawai.core.InvocationChain.invoke(InvocationChain.java:175)
	org.mentawai.filter.InjectionFilter.filter(InjectionFilter.java:128)
	org.mentawai.core.InvocationChain.invoke(InvocationChain.java:92)
	org.mentawai.filter.DIFilter.filter(DIFilter.java:171)
	org.mentawai.core.InvocationChain.invoke(InvocationChain.java:92)
	org.mentawai.filter.ConnectionFilter.filter(ConnectionFilter.java:80)
	org.mentawai.core.InvocationChain.invoke(InvocationChain.java:92)
	org.mentawai.filter.IoCFilter.filter(IoCFilter.java:82)
	org.mentawai.core.InvocationChain.invoke(InvocationChain.java:92)
	org.mentawai.filter.ValidatorFilter.filter(ValidatorFilter.java:183)
	org.mentawai.core.InvocationChain.invoke(InvocationChain.java:92)
	org.mentawai.core.Controller.invokeAction(Controller.java:631)
	org.mentawai.core.Controller.service(Controller.java:496)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
	org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:368)

Eu uso o c3p0 como gerenciador de pool de conexão…

hübner

R

Vc não pode realizar um Cast de CallableStatement para FirebirdCallableStatement dessa maneira:

((FirebirdCallableStatement)cs).setSelectableProcedure(true);

O metodo retorna cs = conn.prepareCall(sb); retorna um objeto CallableStatement e do tipo CallableStatement

Para resolver seu problema:

public List procuraTitulo(String titulo) throws Exception {
         CallableStatement cs = null;
         FirebirdCallableStatement fcs = null;
         ResultSet rset = null;
         try {
             
             String sb = null;
           
             sb = "{CALL SP_LIVROS (1,'Literario','T','Início',?,'','','','','','','')}";                           
             fcs = (FirebirdCallableStatement) cs = conn.prepareCall(sb);
             //cs = conn.prepareCall(sb);
             fcs.setSelectableProcedure(true);  
             cs.setString(1,titulo);
             cs.execute();
             rset = cs.getResultSet();
             return RetornaLista(rset);  
                        
                  
         } finally {
             if (rset != null) try { rset.close(); } catch(Exception e) { }
             if (cs != null) try { cs.close(); } catch(Exception e) { }
         }
     
    }

Dessa maneira o compilador aceitará prq FirebirdCallableStatement herda CallableStatement então qualquer metodo CallableStatement é legivel ao FirebirdCallableStatement

H

Olá ramilani12,

continua dando o mesmo erro na operação de CAST

as classes importadas são essas:
import bookshop.bean.*;
import java.sql.*;
import java.util.*;
import javax.sql.rowset.CachedRowSet;
import com.sun.rowset.CachedRowSetImpl;
import org.firebirdsql.jdbc.*;
. . .
public List procuraTitulo(String titulo) throws Exception {
          CallableStatement cs = null;
          FirebirdCallableStatement fcs = null;
          ResultSet rset = null;
          try {
              
              String sb = null;
            
              sb = "{CALL SP_LIVROS (1,'Literario','T','Início',?,'','','','','','','')}";                           
              cs = conn.prepareCall(sb);
              fcs = (FirebirdCallableStatement) cs;
              fcs.setSelectableProcedure(true);  
              fcs.setString(1,titulo);
              fcs.execute();
              rset = fcs.getResultSet();
              return RetornaLista(rset);  
                         
                   
          } finally {
              if (rset != null) try { rset.close(); } catch(Exception e) { }
              if (cs != null) try { cs.close(); } catch(Exception e) { }
              if (fcs != null) try { fcs.close(); } catch(Exception e) { }
          }
      
     }
e o erro acontece na linha 195:
fcs = (FirebirdCallableStatement) cs;

o erro:

java.lang.ClassCastException: com.mchange.v2.c3p0.impl.NewProxyCallableStatement
	bookshop.dao.BuscaDao.procuraTitulo(BuscaDao.java:195)
	bookshop.action.Busca.execute(Busca.java:47)
	org.mentawai.core.InvocationChain.invoke(InvocationChain.java:175)
.
.
.

pela mensagem de erro ele parece ser do c3p0. (Gerenciador de pool de conexão).

Hübner

H

Olá pessoal,

pesquisando... pesquisando... achei a solução para o problema acima. segue o código que funciona corretamente:

public List procuraTitulo(String titulo) throws Exception {
        PreparedStatement stmt = null;
        ResultSet rset = null;
        try {
            
            String sb = null;
          
            
              sb = "SELECT * FROM SP_LIVROS (1,'Literario','T','Início',?,'','','','','','','')"; 
            
            stmt = conn.prepareStatement(sb);
            
            stmt.setString(1,titulo);
            rset = stmt.executeQuery();
            return RetornaListaProcedure(rset);
                       
                 
        } finally {
            if (rset != null) try { rset.close(); } catch(Exception e) { }
            if (stmt != null) try { stmt.close(); } catch(Exception e) { }
        }
    
   }

resumindo:
para se executar procedures "selecionáveis" no firebird com o driver jaybird (ultima versão) não é necessário nada de especial.

...preparedStatement()...
...executeQuery()..

tudo normal. O comando SQL da sua chamada à procedure também não tem nada de especial. Da mesma forma que vc a executa nativamente vc a chama em Java.

o driver tb suporta parâmetros de entrada e saída normalmente, sem a necessidade daquela frescura de se ficar especificando tipos., etc. afinal o driver Jaybird suporta a especificação JCA-JDBC Class 4

Criado 21 de maio de 2007
Ultima resposta 25 de mai. de 2007
Respostas 5
Participantes 3