Boa tarde.
Fazendo meu trabalho da faculdade, me deparei com mais uma dúvida!!
Como fazer vários inserts no banco de dados Postgres (acredito que não apenas para o Postgres, mas enfim…) passando o ID do insert anterior como parâmetro para o próximo insert na FK, mas que, possa garantir a integridade o insert como se tivesse passando um insert de uma vez só.
Na verdade, os inserts eu consigui fazer, o problema foi que não consegui manter a integridade!
Meu professor de banco de dados, disse que em banco “ou tudo é feito ou nada é feito”, ou seja, se eu passar um script no banco para criar tabelas, inserts, etc… Se em algum ponto tiver algum problema, nada é “comitado”.
Realmente, fiz testes no PgAdmin e isso acontece mesmo. Até antes de criar o sql para minha classe em java, eu fazia o teste no PgAdmin.
E problema que estou tendo é:
Ao fazer um insert em uma tabela, preciso pegar o id desse insert para passar para o próximo insert. Isso eu fiz com o getGeneratedKeys() de ResultSet.
No entanto, o problema é: se o segundo insert tiver um problema o primeiro também não deveria ser comitado, mas no meu caso esta sendo!!
Eu fiz duas tabelas, uma para nome de usário e nível de acesso e outra para login e senha. Meu professor disse para fazer login e senha separado, que era o ideal por questões de segurança, não fiz encriptação de senha, apenas separei as tabelas.
Mas aconteceu que, comecei a fazer os inserts pela tabela de nome e quando ia fazer o segundo insert e encontrava um login já existente (login = unique), dava erro. Até aí tudo bem, era para dar mesmo, mas não era para comitar nada, mas a primeira tabela foi inserida e a segunda não.
Resolvi isso invertendo a ordem dos inserts.
Mas, esse problema posso encontro também quando se tenta fazer um insert de um dado nulo em um not null, se for um segundo insert, o primeiro já foi inserido também.
Abaixo o método que fiz para fazer os inserts dos nomes e logins:
package model.dao;
import java.sql.*;
import java.util.*;
import java.util.logging.*;
import model.Connection_BD;
import model.bean.Usuario;
import view._util.Tools_SQL;
public class UsuarioDAO {
private static Usuario userReturn = null;
//==========================================================================
// cria (cadastra) um novo registro
public static int create(Usuario user) {
Connection con = Connection_BD.getConnection();
PreparedStatement stmt = null;
ResultSet rs = null;
String sql = null;
int returnId = -1;
try {
//------------------------------------------------------------------
// Primeiro INSERT - Tabela acessos (tabela de login e senha)
sql = "INSERT INTO acessos(login, senha) VALUES (?, ?)";
stmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
stmt.setString(1, user.getLogin());
stmt.setString(2, user.getSenha());
stmt.executeUpdate();
rs = stmt.getGeneratedKeys(); // recupera a key gerada no insert
// pega o "ID" do cadastro atual
if (rs.next()) {
returnId = rs.getInt("id_acesso");
}
//------------------------------------------------------------------
// Segundo INSERT - Tabela usuario
sql = "INSERT INTO usuarios(id_usuario, nome, nivel_acesso) VALUES (?, ?, ?)";
stmt = con.prepareStatement(sql);
stmt.setInt(1, returnId);
stmt.setString(2, user.getNome());
stmt.setString(3, user.getNivelAcesso());
stmt.executeUpdate();
return returnId; // retorna o id para a aplicação
} catch (SQLException ex) {
Tools_SQL.mensagemErro(ex); // exibe mensagem de erro, caso ocorra
} finally {
Connection_BD.closeConnection(con, stmt, rs); // encerra conexão
}
return 0;
}
/*
.....
*/
}
Como posso garantir a integridade e não comitar ao fazer vários inserts?
Att.