[Resolvido] java.sql.SQLException: Illegal operation on empty result set

13 respostas
M

Boa Tarde gurizada! Seguinte, tou com um problema aqui, esse insert tá me retornando empty result set, já googlei de monte e não acho o que pode ser. eu quero que esse insert, além dos campos de texto, envie a data como um numero (pex: 01/06/2010 => 01062010 pro DB, pra depois eu retomar esse numero (01062010) e jogar na máscara. os inserts de texto tão funcionando tranquilo, começou a dar esse erro depois de eu inserir a data tbm =S

vai ali a criança:

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.sql.*;
import java.text.*;


import javax.lang.model.util.Types;
import javax.swing.*;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.text.MaskFormatter;
import javax.swing.text.AttributeSet.ColorAttribute;


/**
 * @author Mauricio
 * 
 */
public class CadFun extends JFrame {

	JLabel jlb_codigo, jlb_nome, jlb_nascimento, jlb_carteira, jbl_rg, jbl_cpf,
			jlb_endereco, jlb_bairro, jlb_municipio, jlb_estado, jlb_telefone,
			jlb_celular, jlb_email, jlb_funcao, jlb_obs, jlb_admissao, jlb_demissao,
			jlb_horarios;
	JTextField jtf_codigo, jtf_nome, jtf_nascimento, jtf_carteira, jtf_rg,
			jtf_cpf, jtf_endereco, jtf_bairro, jtf_telefone, jtf_celular,
			jtf_email, jtf_funcao, jtf_admissao;
	JFormattedTextField jft_nascimento, jft_admissao, jft_demissao;
	JTextArea jta_obs;
	JComboBox jcb_municipio, jcb_estado, jcb_horarios;
	JButton jbt_primeiro, jbt_anterior, jbt_proximo, jbt_ultimo, jbt_gravar,
			jbt_alterar, jbt_deletar, jbt_consultar, jbt_horarios, jbt_sair;
	MaskFormatter data;
	
	String codigo, nome, nascimento, carttrab, rg, cpf, endereco, bairro, telefone, celular, email, funcao, obs, admissão;
	String estado, municipio, horarios;
	String admi, demi, nasc;
	int id;
	public CadFun() {
//--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**
		//remover mascaras
		admi = jft_admissao.getText();
		demi = jft_demissao.getText();
		nasc = jft_nascimento.getText();
		if (admi.contains("/")) 
		{
		if (admi.contains("/")) 
		admi = admi.replace("/", ""); 
		}
		if (demi.contains("/")) 
		{if (demi.contains("/")) 
		demi = demi.replace("/", ""); 
		}
		
		if (demi.contains("/")) 
		{if (nasc.contains("/")) 
		nasc = nasc.replace("/", ""); 
		}
//--------------------------------------------------------------------------------------------------------------
		jbt_gravar.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent evento)
			{
				inserir();
			}
		});
	}// Final Construtor
	private void inserir/*termiado*/() 
	{
		try {
			int id;
			ResultSet rs; 
			Connection con;
			con 			= gConexao.getConexao();
			Statement st 	= con.createStatement();
			
			rs = st.executeQuery("Select max(IDFUNCIONARIO) as id from funcionarios");
			rs.next();
			
			id = rs.getInt("id")+1;
			rs = st.executeQuery
			("SELECT idmunicipio from `municipios` where descricao = '"+jcb_municipio.getSelectedItem()+"' " +
					"and idestado = "+jcb_estado.getSelectedIndex());
			rs.next();
			
			int municipio = rs.getInt("idmunicipio");
			String end = jtf_endereco.getText();
			end.toString();
			String obs = jta_obs.getText(); obs.toString();
			
			st.executeUpdate("INSERT INTO `funcionarios`" +
					"(idfuncionario, nome, nascimento," +
					" cart_trabalho, rg, cpf,endereco," +
					" fone, cell, email," +
					" funcao, admissao, demissao, obs," +
					" id_estado, id_municipio, horario) " +
					"VALUES" +
					"("+id+", '"+jtf_nome.getText()+"', '"+nasc+"', '"
					+jtf_carteira.getText()+"', '"+jtf_rg.getText()+"', '"+jtf_cpf.getText()+"', '"+end+"', '"
					+jtf_telefone.getText()+"', '"+jtf_celular.getText()+"', '"+jtf_email.getText()+"', '"
					+jtf_funcao.getText()+"', '"+admi+"', '"+demi+"', '"+obs+"', "+
					jcb_estado.getSelectedIndex()+", "+municipio+", "+jcb_horarios.getSelectedIndex()+")");
			
			jtf_codigo.setText(Integer.toString(id));
			JOptionPane.showMessageDialog(null,"Registro Inserido Com Sucesso!!!","Gerenciamento de estados."
					,JOptionPane.INFORMATION_MESSAGE);
		} 
		catch (Exception e) {
			System.out.println(e);
			JOptionPane.showMessageDialog(null,"Erro: "+e,"Gerenciamento de estados."
					,JOptionPane.INFORMATION_MESSAGE);
		}
	   
	}

}// Final CadFun

13 Respostas

E

Em vez de

rs.next();

você tem de usar

if (rs.next()) {
    // Processar, do jeito que você já fez
    ...
} else {
    // neste caso não há registros, talvez mostrar uma mensagem dizendo que não achou.
    ...
}
M

hmmm…

não entendi direito.eu uso um if pra cada rs.next()?

e então, se cada if for verdadeiro, eu passo pra próxima query, isso?

pq ali eu to chamando um método de inserção, então eu espero q não tenha nenhum registro. e que pegue os dados da aplicação e crie um… :pensativo:

E

Quem espera sempre “cança” - você não ouviu falar nisso?

De qualquer maneira, cheque se seu select não está errado. O valor de rs.next() deve sempre ser checado, porque pode ser que a consulta não retorne nenhum registro.

ViniGodoy

Outra coisa, recomendo fortemente que você substitua esse monte de concatenação aí pelo uso do PreparedStatement. Não é mais difícil de fazer, ele já trata automaticamente campos String digitados com caracteres como apóstrofe (’), deixa a aplicação independente do formato de data do banco e também deixa o código muito mais limpo.

Sem falar que elimina completamente a chance de alguém fazer um ataque de SQL Injection.

M

Ok, vou fazer isso. tou reescrevendo do zero essa parte de código. se duvida vai se mais rápido que descobri como faze aquela coisa funciona.

xD

M

Cara, é pra fica mais ou menos assim o código do preparedstatment? pq tá dando uns errinhos na setagem dos campos...

é que eu nunca fiz prepared, achei um fonte de exemplo no google e me larguei modifica.... é isso mesmo??
PreparedStatement stmt;
	        rs = st.executeQuery("SELECT max(idfuncionario) as id FROM funcionarios");
	        if(rs.next())
	        idfun = rs.getInt("id");
		
	        String query = "insert into funcionarios " +
	        "(IDFuncionario,nome,nascimento,cart_trabalho,rg,cpf,endereco,bairro,id_estado,id_municipio,fone,cell,email,funcao,horario,admissao,demissao,obs) VALUE"+
	        "(idfu = ?, pnome = ?, pnasc = ?, pcart = ?, prg = ?, pcpf = ?, pendereco = ?)";
	        stmt = con.prepareStatement(query);  
	        stmt.setLong(idfun, idfu);  
	        stmt.setString(2, pnome);  
	        stmt.setString(3, pnasc);
dá pra ve q eu ñ terminei ele ainda, é que deu esses erros e eu mandei pra cá, pra depois ñ ter de reescreve tudo caso eu teja fazendo errado..... :?
M

Bom, o código tá dando pau (novidade...)

onde eu errei? ele inseriu o registro numero 0 no banco, mas não insere depois disso... retorna chave duplicada...

aqui o erro>
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '0' for key 1
aqui o código>
private void inserir() 
	{	
		
		try {
			ResultSet rs;
			Connection con;
			con = gConexao.getConexao();
	        Statement st = con.createStatement();
	        
	        rs = st.executeQuery("SELECT max(idfuncionario) as id FROM funcionarios");
	        if(rs.next()) {
	        idfun = rs.getInt("id")+1;
	        
	        	rs = st.executeQuery("SELECT idmunicipio from `municipios` where descricao = '"+jcb_municipio.getSelectedItem()+"' and Idestado = "+jcb_estado.getSelectedIndex());
	        	if(rs.next())
	        		idmun = rs.getInt("idmunicipio");
	        String query = "insert into funcionarios "+
	        "(IDFuncionario,nome,nascimento,cart_trabalho,rg,cpf,endereco,bairro,id_estado,id_municipio,fone,cell,email,funcao,horario,admissao,demissao,obs) VALUE"+
	        "(IDFuncionario =?,nome =?,nascimento =?,cart_trabalho =?,rg =?,cpf =?,endereco =?,bairro =?,id_estado =?,id_municipio =?,fone =?,cell =?,email =?,funcao =?,horario =?,admissao =?,demissao =?,obs =?)";
	        PreparedStatement stmt = con.prepareStatement(query);
	        stmt.setLong(1, idfun);
	        stmt.setString(2, jtf_nome.getText());
	        stmt.setString(3, nasc);
	        stmt.setString(4, jtf_carteira.getText());
	        stmt.setString(5, jtf_rg.getText());
	        stmt.setString(6, jtf_cpf.getText());
	        stmt.setString(7, jtf_endereco.getText());
	        stmt.setString(8, jtf_bairro.getText());
	        stmt.setLong(9, jcb_estado.getSelectedIndex());
	        stmt.setLong(10, idmun);
	        stmt.setString(11, jtf_telefone.getText());
	        stmt.setString(12, jtf_celular.getText());
	        stmt.setString(13, jtf_email.getText());
	        stmt.setString(14, jtf_funcao.getText());
	        stmt.setLong(15, jcb_horarios.getSelectedIndex());
	        stmt.setString(16, admi);
	        stmt.setString(17, demi);
	        stmt.setString(18, jta_obs.getText());
	        stmt.execute();
	        }
			/*
			 *  (1IDFuncionario,2nome,3nascimento,4cart_trabalho,5rg,6cpf,7endereco,8bairro,
			 *  9id_estado,10id_municipio,11fone,12cell,13email,14funcao,15horario,16admissao,17demissao,18obs)
			 */
			con.close();
		
			st.close();
		}catch (Exception e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog
			(null,"Erro: \n"+e,"",JOptionPane.INFORMATION_MESSAGE);;
			//System.out.println("erro: \n"+e);
		}
	}
ViniGodoy

Ele está dizendo que você está tentando inserir um ID duplicado.

Dica, não cadastre ids no braço. No lugar, crie o campo como auto-numerado no banco de dados e use o ID que ele mesmo gerar automaticamente para você. Aí vc nem sequer precisa informar o ID nos seus SQLs, nem mesmo rodar aquela consulta com max ali.
A consulta com o MAX tem um problema. Existe a chance de um registro ser inserido entre a consulta do MAX e o seu INSERT, o que faria seu insert falhar ao tentar inserir um ID duplicado (não é esse seu problema agora, já que vc tá rodando em uma máquina só).

Com a auto-numeração esse problema não ocorre.

M

Vini

Valeu cara, entendi essa parte do ID autonumerado.

amanha vo configura o tal pra isso, por hora vo deixa esse tópico como resolvido, eu já consegui fazer inserts (rodando o MAX, mas tá inserindo de boa)

só tá dando um problema nos campos de data, mas to quase resolvendo eles, to tirando a mascara deles com o
if(strnascimento.contains("/")) 
			bdnasc = strnascimento.replace("/", "");
mas ainda dá erro quando o campo é vazio, nada que eu não resolva, é só acrescenta mais um replace pra tira o place holder xD (ou existe método melhor?)
private void inserir() 
	{	
		String strnome = jtf_nome.getText();
		String strcart = jtf_carteira.getText();
		String strrg = jtf_rg.getText();
		String strcpf = jtf_cpf.getText();
		String strendereco = jtf_endereco.getText();
		String strbairro = jtf_bairro.getText();
		String strtelefone = jtf_telefone.getText();
		String strcell = jtf_celular.getText();
		String stremail = jtf_email.getText();
		String strfuncao = jtf_funcao.getText();
		int idestado = jcb_estado.getSelectedIndex();
		String strmunicipio = (String) jcb_municipio.getSelectedItem();
		int idhorario = jcb_horarios.getSelectedIndex();
		String strobs = jta_obs.getText();
		String strnascimento = jft_nascimento.getText();
		String stradmissao = jft_admissao.getText();
		String strdemissao = jft_demissao.getText();
		String bdnasc = null, bdadmi = null, bddemi = null;
		if(strnascimento.contains("/")) 
			bdnasc = strnascimento.replace("/", "");
		if(stradmissao.contains("/")) 
			bdadmi = strnascimento.replace("/", "");
		if(strdemissao.contains("/"))
			bddemi = strdemissao.replace("/", "");

		System.out.println(bdnasc);
		try {
			ResultSet rs; 
			Connection con;
			con = gConexao.getConexao();
			
			PreparedStatement st = con.prepareStatement("SELECT idmunicipio FROM municipios WHERE Descrição = ? and IDEstado = ?");
			st.setString(1, strmunicipio);
			st.setLong(2, idestado);
			rs = st.executeQuery();
			rs.next();
			idmun = rs.getInt("idmunicipio");
			System.out.println("idmun: "+idmun);
			
			st = con.prepareStatement("SELECT max(idfuncionario) as id FROM funcionarios");
			rs = st.executeQuery();
			rs.next();
			id = rs.getInt("id")+1;
						
			st = con.prepareStatement("INSERT INTO funcionarios(IDFuncionario, nome, nascimento, cart_trabalho, rg, cpf, endereco, bairro, id_estado, id_municipio, fone, cell, email, funcao, horario, admissao, demissao, obs) Value (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
			st.setInt(1, id);
			st.setString(2, strnome);
			st.setString(3, bdnasc);
			st.setString(4, strcart);
			st.setString(5, strrg);
			st.setString(6, strcpf);		
			st.setString(7, strendereco);
			st.setString(8, strbairro);
			st.setInt(9, idestado);
			st.setString(10, strmunicipio);
			st.setString(11, strtelefone);
			st.setString(12, strcell);
			st.setString(13, stremail);
			st.setString(14, strfuncao);
			st.setInt(15, idhorario);
			st.setString(16, bdadmi);
			st.setString(17, bddemi);
			st.setString(18, strobs);
			
			
			
			
			
			st.execute();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (ExcRepositorio e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		

	}

aqui o código funcionando, só dando erro quando a data é nula (coisa de vadio ñ tratar isso hj... mas vá lá...)

valeu vinão! já me salvo de algumas nesse fórum! hehehehe :lol: :lol: :lol: :lol:

ViniGodoy

Para inserir datas, use o setDate.

Primeiro você faz o parse da Data usando um SimpleDateFormatter. Mais ou menos assim:

SimpleDateFormatter df = new SimpleDateFormatter("dd/MM/yyyy"); Date dt = df.parse(strnascimento);

Depois, você transforma num java.sql.Date:

java.sql.Date sqlDate = new java.sql.Date(dt.getTime());

Finalmente, vc substitui o seu set do PreparedStatement:

st.setDate(3, sqlDate);

Menos linhas, mais fácil de fazer o parse e mais seguro. :slight_smile:

M

sim, eu já tentei esse método vini, mas eu nunca consegui recuperar as datas do banco pra aplicação com ele… =’(

ViniGodoy

Ué, no seu banco de dados o tipo da coluna é DateTime?
E você deve usar esse método também na hora de fazer o select, também através de um PreparedStatement.

Essa é a maneira correta de fazer. Via de regra, você sempre deve representar dados pelo seu tipo correto. Datas não são texto, são Date. O único lugar que data vira texto é na view. E textos já não deveriam ser mais datas a partir do momento que passaram pelo seu controller.

M

ok :wink:

Criado 24 de junho de 2010
Ultima resposta 25 de jun. de 2010
Respostas 13
Participantes 3