SQLException a tratar no DELETE (MySQL)

Pessoal,

O delete abaixo está funcionando perfeitamente quando a linha a ser deletada existe na tabela. Porém, quando o delete é de uma linha inexistente, estranhamente, o try/catch não pega nada (parece que foi tudo ok quando, na verdade não foi). Existe alguma outra condição que devo tratar no catch? Vejam as linhas de código abaixo (eu só deixei a parte do try/delete/catch pra facilitar:

public static String mtdSqlDel(Connection wSqlCon, int wTabCha) {
	String wSqlDelSit = " ";
	
	try {
		String wSqlDel = "DELETE FROM TBTESTE WHERE CHAVE = ?";  
		PreparedStatement wStatement = wSqlCon.prepareStatement(wSqlDel); 
		wStatement.setInt(1, wTabCha);  
		wStatement.execute(); 
		wSqlDelSit = "DELETE OK";
		wStatement.close();  
	} catch (SQLException ex) {  
		System.out.println("Problemas no Delete ."+ex);
		wSqlDelSit = "ERRSQL1";
	}
	
	return wSqlDelSit;
}

Grato.

Quando exclui um registro pelo Workbench, mesmo não existido o registro ele não da erro, mas avisa que não foi excluído nenhum registro

É o mesmo que fazer um select e não retornar nada. Não é um erro na verdade.

O que geralmente faço é verificar, principalmente no INSERT se o registro existe. Na exclusão eu não verifico não.

Caramba! É q, talvez, um Delete com key inexistente pode, na verdade, caracterizar um erro lógico onde
a chave informada para o Delete está errada. O fato do SQL não retornar algo como Not Found pode vir a mascarar
este erro lógico.

Vonquelbe_Cruz , mesmo não sendo um erro pro SQL será que não temos um SQLState informando isso?

Grato.

O método executeUpdate (e não execute como tens) deve ser invocado no PreparedStatement para inserts, updates e deletes. Este método devolve o número de linhas afetadas (0 caso o delete ou update seja sobre registos que não existem)

1 curtida

pmlm, você pode me dizer a diferença entre o execute() e o executeUpdate()? Grato.

O método execute executa ( tu-dum-tss :sunglasses: ) um código SQL, seja ele um select para retornar registros do banco ou comandos para realizar alterações na base (delete, update). Esse método retorna true caso o retorno seja um ResultSet, ou seja, consulta de registros do banco, ou false caso seja o total de linha afetadas no caso de ser um update ou delete.

O método executeUpdate faz alterações na base e retorna o total de registros alterados e o método executeQuery retorna um ResultSet com os registros consultados.

Boa @pmlm … É isso mesmo @Lucio_Tepe_Jr … Olha o que fiz.

Inclui três registros numa tabela e alterei minha rotina de exclusão para exclui todos os registros com a mesma Descrição, “DELETE” … inclui na mensagem o retorno da quantidade de registros afetados. Olha o resultado:

Segue código do meu DAO:

public static List <AplicacaoMod> Lista () {
    List <AplicacaoMod> lista = new ArrayList();
    AplicacaoMod obj;
    try {
        Conn cnx = Conn.getInstance();
        ps = cnx.conn.prepareStatement("select * from adm_aplicacao order by tipo, descr");
        rs = ps.executeQuery();
        while(rs.next()){
            obj = new AplicacaoMod(rs.getString("codaplic"),
                                   rs.getString("descr"),
                                   rs.getString("tipo").charAt(0),
                                   rs.getBoolean("ativo"),null);
            lista.add(obj);
        }
    } catch (Exception e) {
        Util.mensagem("Error (Lista): "+e.getMessage());
    } finally {
        Conn.closeConnection(ps, rs);
    }        
    return lista;
}    
public static Msg Acao (AplicacaoMod obj){
 // Critica
    if (obj.getCodigo().equals("")) {return new Msg("1", "Campo obrigatório: Código");}
    if (obj.getDescr().equals(""))  {return new Msg("2", "Campo obrigatório: Descrição");}
 // Ação
    try {
        Conn cnx = Conn.getInstance();
        switch(obj.getAcao()) {
            case "INC":
                ps = cnx.conn.prepareStatement("insert into adm_aplicacao values ("
                                              +"'"+obj.getCodigo()+"',"
                                              +"'"+obj.getDescr ()+"',"
                                              +"'"+obj.getTipo  ()+"',"
                                                  +obj.isAtivo  ()+")");
                ps.executeUpdate();
                
                Util.mensagem("Inclusão realizada com sucesso ("+ps.getUpdateCount()+").");
                break;
            case "ALT":
                ps = cnx.conn.prepareStatement("update adm_aplicacao "
                                             + "   set descr     = ? "
                                             + "     , tipo      = ? "
                                             + "     , ativo     = ? "
                                             + " where codaplic  = ? ");
                ps.setString (1,obj.getDescr ());
                ps.setString (2,String.valueOf(obj.getTipo()));
                ps.setBoolean(3,obj.isAtivo  ());
                ps.setString (4,obj.getCodigo());
                ps.executeUpdate();
                Util.mensagem("Alteração realizada com sucesso ("+ps.getUpdateCount()+").");
                break;
            case "EXC":
                ps = cnx.conn.prepareStatement("delete from adm_aplicacao "
                                             //+ " where codaplic = ?");
                                             + " where descr = 'DELETE'");
                //ps.setString (1,obj.getCodigo());
                ps.executeUpdate();
                Util.mensagem("Exclusão realizada com sucesso ("+ps.getUpdateCount()+").");
                break;
        }        
    } catch (Exception e) {
        Util.mensagem("Erro Aplicação ("+obj.getAcao()+") : "+e.getMessage());
    } finally {
        Conn.closeConnection(ps);
    }
    return new Msg(null, null);
}

Repare que no meu método “Lista()” eu uso o rs = ps.executeQuery();. Já nos insert, update e delete do método “Acao()” eu uso ps.executeUpdate();. Inclui na mensagem o total de registros Util.mensagem("Alteração realizada com sucesso ("+ps.getUpdateCount()+").");

Depois de excluídos, se tendo excluir novamente ele retorna o que ? ZERO

Está tudo de acordo com o que já foi explicado pelos demais. Agora, se você quer melhorar a mensagem, pode sofisticar um pouco mais assim:

int linhasAfetadas = ps.executeUpdate();
Util.mensagem( linhasAfetadas == 0 ? "Nenhum registro excluído." : "Exclusão realizada com sucesso (" + linhasAfetadas = ").");
1 curtida

Vonquelbe_Cruz, pmlm, lucastody e Ademiltonjlc, obrigado pelo apoio e explicações. Vou usar o
executeUpdate() de agora em diante.

Obs: o q eu devo fazer pra colocar como resolvido este tópico? É isso q eu devo fazer quando minha
dúvida é resolvida, certo?

Logo abaixo da resposta que te ajudou, clique nas reticências (…) que irá abrir a opção de marcar como solução (o botão é o desenho de um check marcado)