Erro ao preencher JTextField

Olá galera,
Estou com dificuldade de achar o erro ao preencher JTextField, poderem me ajudar agradeço.
O erro é o seguinte:
java.sql.SQLException: Illegal operation on empty result set.

a informação não esta fazia no banco de dados, mas mesmo assim da esse erro.

public void preencheCampos() {
int linha = lista.getSelectedIndex();
System.out.println(linha);
conn = Conexao.conector();
try {
if (linha >= 0) {
String sql = “Select * from tbproduto where produto_cod=’” + linha + “’”;
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
rs.first();
txtValorUnitario.setText(String.valueOf(rs.getString(“produto_valor”)));
}

    } catch (Exception erro) {
        JOptionPane.showMessageDialog(null, "Erro ao mostrar dados " + erro);
        System.out.println(erro);
    }
}

Uma observação o erro acontecer em alguns produtos não é com todos.
Mas todos foram cadastrados do mesmo jeito.

Sua consulta não trouxe resultados.

Implemente assim:

String sql = “Select * from tbproduto where produto_cod = ?”;
pst = conn.prepareStatement(sql);
pst.setInt(1, linha);
rs = pst.executeQuery();
String valor;
if (rs.next()) {
    valor = rs.getString(“produto_valor”);
} else {
    valor = "";
}
txtValorUnitario.setText(valor);

staroski boa tarde,
Então continua do mesmo a unica diferença agora é que não aparece a mensagem java.sql.SQLException: Illegal operation on empty result set.

Mas os produtos que retorna vazio esta cadastrado no banco de dados.
Tenho 5 produtos cadastrados no banco, desses 5 2 estão não traz resultado.

Outra que percebi fazendo uns teste é que quando clico no Jlist para preencher o txtValorUnitario ele esta trazendo o valor errado.
por exemplo: clico em um produto em traz o valor de outro.

E conferiu se o select está certo?

Posta seu código fonte completo.
Não dá pra adivinhar como você implementou. :wink:

Essa é minha lista responsável por fazer a pesquisa do nome do produto no banco.

public void listaDePesquisa() {
String sql = “Select * from tbproduto where produto_nome like '” + txtPesquisa_ProdutosServicos.getText() + “%'order by produto_nome”;
modeloList.removeAllElements();
try {
conn = Conexao.conector();
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
int v = 0;
while (rs.next() & v < 10) {
modeloList.addElement(rs.getString(“produto_cod”) + " " + rs.getString(“produto_nome”));
//modeloList.addElement(rs.getString(“produto_nome”));
v++;
}
if (v >= 1) {
lista.setVisible(true);
} else {
lista.setVisible(false);
}

    } catch (SQLException erro) {
        JOptionPane.showMessageDialog(null, "Erro ao listar dados " + erro);
    }

}

E esse é o método responsável por preencher txtValorUnitario

public void teste() {
int linha = lista.getSelectedIndex();
conn = Conexao.conector();
try {
String sql = “Select * from tbproduto where produto_cod = ?”;
pst = conn.prepareStatement(sql);
pst.setDouble(1, linha);
rs = pst.executeQuery();
String valor;
if (rs.next()) {
valor = rs.getString(“produto_valor”);
} else {
valor = “**”;
}
txtValorUnitario.setText(valor);
} catch (SQLException erro) {
JOptionPane.showMessageDialog(null, "Erro ao mostrar dados " + erro);
}
}

Observação: deletei todos os produtos e cadastrei outros, agora todos retornam vazios.

E já conferiu se o SELECT que seu programa faz, está certo, se os parâmetros que você passa para o PreparedStatement estão certos?
Já pegou o mesmo SELECT que você faz no Java e executou diretamente no banco pra ver se traz resultados?

Dicas:

  • Se você só vai ler 2 colunas, não faça SELECT *, faça SELECT COLUNA_1, COLUNA_2;
  • Se você usa PreparedStatement, não deve concatenar os parâmetros na String da query;
  • Procure separar o acesso ao banco da sua interface de usuário, crie uma camada própria pra isso, a interface de usuário deveria interagir somente com os objetos pertinentes ao modelo do seu problema.

Respondendo seus questionamentos
E já conferiu se o SELECT que seu programa faz, está certo? Sim esta, fiz o teste no banco e retorna certinho.
Se os parâmetros que você passa para o PreparedStatement estão certos? Sim estão

Aqui você concatena os parâmetros na String antes de criar o PreparedStatement.
Quando se usa PreparedStatement, não se concatena parâmetros na String, você põe o parâmetro como ? e seta com um método setTipoDeDado(coluna, conteúdo).
Você realmente precisa retornar todas as colunas nesse select?

O código do produto é realmente um double na tabela do banco?
E novamente, você precisa realmente retornar todas as colunas neste select?

Bom dia,
Eu fiz sem concatenar também aí só foi um teste o que preciso mesmo é só retorna o produto_valor
No meu banco o produto_valor está como decimal(10,2).

Legal, mas essa sua query aqui está errada:

String sql = “Select * from tbproduto where produto_cod = ?”;
pst = conn.prepareStatement(sql);
pst.setDouble(1, linha); // produto_cod é um decimal no banco???
rs = pst.executeQuery();

Oque é decimal no banco é só o produto_valor.

Então não faz sentido tu setar o parâmetro de consulta com setDouble :wink:

Entendi não tinha trabalhado com decimal ainda.
Devo setar como oque ?

Creio que ainda não entendeu como funciona o PreparedStatement.

Veja a string abaixo:

String sql = “Select * from tbproduto where produto_cod = ?”;
pst = conn.prepareStatement(sql);

Quando você usa o PreparedStatement, os parâmetros são identificados por ?

Então para setar o valor com o qual o produto_cod será comparado. você precisa usar o método set apropriado.

pst.setTipoDeDado(numeroDoParametro, valorDoParametro);

Como só tem um parâmetro, o número dele será 1;

`pst.setTipoDeDado(1, valorDoParametro);`

Se o produto_cod é um inteiro, você vai fazer:

`pst.setInt(1, umValorInt);`

Se o produto_cod é decimal, você vai fazer:

`pst.setDouble(1, umValorDouble);`

Se o produto_cod é String, você vai fazer:

`pst.setString(1, valorString);`

A minha variável é double
E no banco é decimal
Então o correto é
pst.setDouble(1, “produto_valor”);

Não amiguinho, você ainda não entendeu!

Preste atenção no seu select:

select * from tbproduto where produto_cod = ?

A cláusula where procura produto que tenha um produto_cod que atenda a seguinte condição:

produto_cod = ?

Quando você faz o PreparedStatement.setAlgumaCoisa, você tem que usar o método apropriado com o tipo de dado desse parâmetro e aí o driver JDBC vai tratar de substituir o ? adequadamente ao executar a query.

Meu já fiz CRUD várias vezes imaginei q sabia oque estava fazendo, pelo jeito tenho muito que aprender.
Fiquei confuso agora.
Se não é dessa forma que fiz não tô entendendo como fazer.
Desculpa amigo vc esta me ajudando muito.
Mas agora travei.
Poderia citar um exemplo de como eu faria essa linha de código.