Estou programando com interface gráfica, mas acho que o pessoal dessa área conseguirá responder a minha dúvida.
Como eu faço para ter várias sentenças em uma única função? O problema é que se eu coloco mais de uma query, por exemplo, na mesma função, fala que o objeto que eu utilizei como resposta já está “closed”.
Eu preciso dessa função para coletar alguns dados do DB. Entre eles o total de produtos cadastrados no DB, total de clientes cadastrados, etc. Então, vou armazena-los todos em um Vector e enviar pra classe que chama ele. Só que ocorre esse erro que e falei quando chamo o método.
Cara pelo que eu entendi você tem várias consultas diferentes dentro de uma mesma string e quer executar tudo de uma vez.
Cara se for isso, não dá pra fazer, você precisa fazer cada uma separada, a não ser que você faça utilizando um union ou seja uma subquery, tirando isso, você vai precisar fazer uma por vez.
Teria como você postar o código pra ajudarmos melhor?
O que você indicou é simples e deve ser algum detalhe na sua implementação
que está atrapalhando.
[quote=Gerson da S. Lima]Cara pelo que eu entendi você tem várias consultas diferentes dentro de uma mesma string e quer executar tudo de uma vez.
Cara se for isso, não dá pra fazer, você precisa fazer cada uma separada, a não ser que você faça utilizando um union ou seja uma subquery, tirando isso, você vai precisar fazer uma por vez.[/quote]
Não é isso. São várias consultas diferentes com objetos distintos guardando a sentença SQL distintos.
Gerson
O que eu tento fazer é o seguinte:
[code] public static String[] pegaDadosIniciais() throws SQLException{
PreparedStatement objSQLTotProd = objCon.prepareStatement("SELECT COUNT(*) AS TOTPROD FROM TABPRODUTOS");
ResultSet objRespTotProd = objSQLTotProd.executeQuery();
PreparedStatement objSQLTotCli = objCon.prepareStatement("SELECT COUNT(*) AS TOTCLI FROM CLIENTES");
ResultSet objRespTotCli = objSQLTotCli.executeQuery();
String[] objResposta[];
//Faz Cast
objResposta[0] = "" + objRespTotProd.getInt("TOTPROD");
objResposta[1] = "" + objRespTotCli.getInt("TOTCLI");
//Obteu os dados com sucesso se não retorna erro
if(objRespTotProd.next()){
return objResposta;
} else {
throw new SQLException("Falha ao obter estatísticas iniciais.");
}
}[/code]
A idéia é mais ou menos essa. Só que a função retorna um SQLException falando do “Result set already Closed.”, ou algo assim.
é porque tu tá chamando os resultados antes de dá next no resultset.
Faz assim:
if (objSQLTotProd.next())
objResposta[0] = "" + objRespTotProd.getInt("TOTPROD");
if (objRespTotCli.next())
objResposta[1] = "" + objRespTotCli.getInt("TOTCLI");
if(objResposta.length() > 0) {
return objResposta;
} else {
throw new SQLException("Falha ao obter estatísticas iniciais.");
}
acho q isso resolve teu problema, mas cara, sinceramente essa implementação tá muito extranha. Dá uma pensada melhor, melhora um pouco essa implementação.
[quote=Gerson da S. Lima]é porque tu tá chamando os resultados antes de dá next no resultset.
Faz assim:
if (objSQLTotProd.next())
objResposta[0] = "" + objRespTotProd.getInt("TOTPROD");
if (objRespTotCli.next())
objResposta[1] = "" + objRespTotCli.getInt("TOTCLI");
if(objResposta.length() > 0) {
return objResposta;
} else {
throw new SQLException("Falha ao obter estatísticas iniciais.");
}
acho q isso resolve teu problema, mas cara, sinceramente essa implementação tá muito extranha. Dá uma pensada melhor, melhora um pouco essa implementação.
[quote=Gerson da S. Lima]é porque tu tá chamando os resultados antes de dá next no resultset.
Faz assim:
if (objSQLTotProd.next())
objResposta[0] = "" + objRespTotProd.getInt("TOTPROD");
if (objRespTotCli.next())
objResposta[1] = "" + objRespTotCli.getInt("TOTCLI");
if(objResposta.length() > 0) {
return objResposta;
} else {
throw new SQLException("Falha ao obter estatísticas iniciais.");
}
acho q isso resolve teu problema, mas cara, sinceramente essa implementação tá muito extranha. Dá uma pensada melhor, melhora um pouco essa implementação.
abraços
[/quote]
Ainda deu o mesmo erro. Eu acho que o problema tá na utilização dos métodos do SQL.
Procure utilizar o valor do resultset logo após rodar o comando no banco.
Nâo prepare vários resultsets para depois ler o valor 1 a 1.
Procure utilizar os tipos de dados corretamente.
Se retornará com valores inteiros, por que não colocar o tipo de retorno como int[] de uma vez?
Evite retornar um conjunto diferente de valores com um array.
Para ler isto em outro lugar você usará algo como:
int[] dadosIniciais = pegaDadosIniciais();
int quantidadeProdutos = dadosIniciais[0];
int quantidadeClientes = dadosIniciais[1];
Este tipo de código facilita o aparecimento de bugs.
Mudando a ordem dos valores em pegaDadosIniciais tudo pára de funcionar.
Crie uma classe com estas propriedades e retorne a classe no seu método.
Procure isolar o código de acesso ao banco do resto da sua aplicação.
A forma mais comum de se fazer isto é utilizando o padrão DAO.
Dê uma estudada a respeito.
Se seguir (quase) todas estas considerações e o problema continuar, me responda:
Que banco de dados está utilizando?
Você consegue trazer essas informações com um comando só, mas a sintaxe varia de banco pra banco.
Este código que postou é exatamente igual o que está rodando?
Copiando o código que colocou ele nem compila (mesmo com as alterações sugeridas)
Procure utilizar o valor do resultset logo após rodar o comando no banco.
Nâo prepare vários resultsets para depois ler o valor 1 a 1.
Procure utilizar os tipos de dados corretamente.
Se retornará com valores inteiros, por que não colocar o tipo de retorno como int[] de uma vez?
Evite retornar um conjunto diferente de valores com um array.
Para ler isto em outro lugar você usará algo como:
int[] dadosIniciais = pegaDadosIniciais();
int quantidadeProdutos = dadosIniciais[0];
int quantidadeClientes = dadosIniciais[1];
Este tipo de código facilita o aparecimento de bugs.
Mudando a ordem dos valores em pegaDadosIniciais tudo pára de funcionar.
Crie uma classe com estas propriedades e retorne a classe no seu método.
Procure isolar o código de acesso ao banco do resto da sua aplicação.
A forma mais comum de se fazer isto é utilizando o padrão DAO.
Dê uma estudada a respeito.
Se seguir (quase) todas estas considerações e o problema continuar, me responda:
Que banco de dados está utilizando?
Você consegue trazer essas informações com um comando só, mas a sintaxe varia de banco pra banco.
Este código que postou é exatamente igual o que está rodando?
Copiando o código que colocou ele nem compila (mesmo com as alterações sugeridas)
[/quote]
Sim, já utilizo tudo isso que você citou, inclusive o DAO e só retorno um vetor de String por que vou adicionar para um conjunto de Strings no final, daí daria na mesma, por que eu teria de fazer Cast do mesmo jeito. A idéia de criar uma classe com os dados que eu vou pegar eu tinha ela des de o início, mas como não consegui nem fazer ler os dados que eu quero do BD, não continuei.
Utilizo o Firebird.
O código que eu postei não é igual, por que o que eu tinha eu o retirei, esse daí criei na hora de criar o tópico, mas era assim que eu utilizava. O maior problema é o erro do ResultSet que fala que já está Closed, o resto dá pra arrumar.
Sim, utilizei. Assim que eu fazia a pesquisa eu atribuia o valor, mas mesmo assim dava o mesmo problema. Será que cada Statement tem que ficar em um try…catch?
Cuidado, abra sempre seu tópico no fórum mais específico. Abrir no fórum errado pode fazer com que ele demore muito mais a ser respondido, além de atrair usuários que são bem intencionados, mas não são muito especialistas no assunto.
No caso, você deve procurar o fórum que seja pertinente a sua dúvida. Esse tópico aqui, por exemplo, fala exclusivamente de acesso a dados, e pouco importa a interface final da solução. Por isso, o local mais adequado é mesmo o fórum de persistência.
[quote=ViniGodoy]Movido para o fórum de Persistência.
Cuidado, abra sempre seu tópico no fórum mais específico. Abrir no fórum errado pode fazer com que ele demore muito mais a ser respondido, além de atrair usuários que são bem intencionados, mas não são muito especialistas no assunto.
No caso, você deve procurar o fórum que seja pertinente a sua dúvida. Esse tópico aqui, por exemplo, fala exclusivamente de acesso a dados, e pouco importa a interface final da solução. Por isso, o local mais adequado é mesmo o fórum de persistência. ;)[/quote]
Hehe. Mas foi justalmente o que eu fiz. Por isso falei que o projeto é com interface gráfica, mas a parte que tenho dúvidas é a do acesso a banco de dados.