Stored procedure selecionavel com Firebird

Alguem sabe usar stored procedures “selecionaveis” com firebird?

ou seja, procedures que retornam um ResultSet…

grato

Hübner

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

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

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

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) { }
          }
      
     } [/code]


e o erro acontece na linha 195:
[code]             fcs = (FirebirdCallableStatement) cs;[/code]

o erro:

[code]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

Olá pessoal,

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

[code]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) { }
    }

} [/code]

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