none
Remover item de base de dados RRS feed

  • Pergunta

  • Olá a todos. Estou aqui com um problema a remover um registo da base de dados. 

    Para a remoção que preciso de fazer, 1º tenho de remover o registo de uma tabela de associação (visto ser relação N para N) e depois da tabela do registo. O que acontece é que, aparentemente tudo é feito correctamente. No entanto, depois de fechar o programa e voltar a executar (ou fechar e consultar a bd), o registo permanece na base de dados, em ambas as tabelas.

    A base de dados está no sqlserverce (incorporado com o visual studio)

    Tenho o seguinte código:

    //Pega o valor do IDEnrenagem do datagridviewstring num = dg_engrenagens.CurrentRow.Cells[2].Value.ToString(); DialogResult res = MessageBox.Show("Tem a certeza que pretende eliminar a engrenagem selecionda?", "Confirmação", MessageBoxButtons.YesNo, MessageBoxIcon.Question);  if(res == DialogResult.Yes)  { try    {

    con.Open();

    }catch{

    MessageBox.Show("Erro com a base de dados!", "ERRO", MessageBoxButtons.OK, MessageBoxIcon.Error);

    }      //Dados eliminar tabela de associação string eliminaDer = "DELETE FROM ClienteEngrenagem WHERE IDEngrenagem = @IDEngA"; SqlCeCommand queryeliminaDer = new SqlCeCommand(eliminaDer, con); queryeliminaDer.Parameters.AddWithValue(@"IDEngA", num);      //Dados eliminar tabela engrenagens      string elimina = "DELETE FROM Engrenagem WHERE IDEngrenagem = @IDEngB"; SqlCeCommand queryelimina = new SqlCeCommand(elimina, con);      queryelimina.Parameters.AddWithValue(@"IDEngB", num);   

    try { queryeliminaDer.ExecuteNonQuery(); queryelimina.ExecuteNonQuery(); }catch(SqlCeException exp)  {  con.Close(); MessageBox.Show(exp.ToString()); } con.Close();  MessageBox.Show("Engrenagem eliminada com sucesso", "Sucesso", MessageBoxButtons.OK,MessageBoxIcon.Information);this.Close();  }




    • Editado CrAsilva segunda-feira, 7 de abril de 2014 13:26
    segunda-feira, 7 de abril de 2014 13:24

Respostas

  • Olá, agora eu entendi o erro era no ID que vc buscava, alterei para usar parametros e criei um método para atualizar a grid, agora esá ok :

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Data.SqlServerCe;
    
    namespace TestesBaseDados_0104
    {
        public partial class frm_engrenagens : Form
        {
            public SqlCeConnection con = new SqlCeConnection(Properties.Settings.Default.DB_AsafilConnectionString);
    
            public frm_engrenagens()
            {
                InitializeComponent();
            }
    
            private void frm_engrenagens_Load(object sender, EventArgs e)
            {
                AtualizaDataGrid();
            }
    
            private void bt_adicionarengrenagem_Click(object sender, EventArgs e)
            {
                frm_adicionarengrenagem AdicionarEngrenagem = new frm_adicionarengrenagem();
                AdicionarEngrenagem.ShowDialog();
            }
    
            private void bt_removerengrenagem_Click(object sender, EventArgs e)
            {
                //Pega o valor do IDEnrenagem do datagridview
                string num = (string)dg_engrenagens.CurrentRow.Cells[2].Value; //ok
                DialogResult res = MessageBox.Show("Tem a certeza que pretende eliminar a engrenagem selecionda?", "Confirmação", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if(res == DialogResult.Yes)
                {
                    try
                    {
                        con.Open();
                    }
                    catch
                    {
                        MessageBox.Show("Erro com a base de dados!", "ERRO", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    string eliminaDer = "DELETE FROM ClienteEngrenagem WHERE IDEngrenagem = @IDEngrenagem";
                    SqlCeCommand queryeliminaDer = new SqlCeCommand(eliminaDer, con);                
                    queryeliminaDer.Parameters.AddWithValue("@IDEngrenagem", num);
    
                    try
                    {
                        queryeliminaDer.ExecuteNonQuery();
                        //Dados eliminar tabela engrenagens      
                        string elimina = "DELETE FROM Engrenagem WHERE IDEngrenagem = @IDEngrenagem";
                        SqlCeCommand queryelimina = new SqlCeCommand(elimina, con);
                        queryelimina.Parameters.AddWithValue("@IDEngrenagem", num);
                        queryelimina.ExecuteNonQuery();
                        con.Close();
                    }
                    catch (SqlCeException exp)
                    {
                        con.Close();
                        MessageBox.Show(exp.ToString());
                    }                
                    MessageBox.Show("Engrenagem eliminada com sucesso", "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    AtualizaDataGrid();
                }
               
            }
    
            //CRIEI ESSE METODO PARA ATUALIZAR O DATAGRID
            void AtualizaDataGrid()
            {
                con.Open();
                SqlCeDataAdapter adapt = new SqlCeDataAdapter(" SELECT  Cliente.IDCliente, Cliente.NomeCliente, Engrenagem.IDEngrenagem, Engrenagem.Modulo, Engrenagem.AnguloBeta, Engrenagem.Correcao, Engrenagem.NumeroDentes FROM Cliente INNER JOIN ClienteEngrenagem ON Cliente.IDCliente = ClienteEngrenagem.IDCliente INNER JOIN Engrenagem ON ClienteEngrenagem.IDEngrenagem = Engrenagem.IDEngrenagem", con);
                SqlCeCommandBuilder build = new SqlCeCommandBuilder(adapt);
                con.Close();
                DataTable table = new DataTable();
                adapt.Fill(table);
                dg_engrenagens.DataSource = table;
            }
        }
    }
    

    • Sugerido como Resposta Giovani Cr segunda-feira, 7 de abril de 2014 19:05
    • Marcado como Resposta CrAsilva terça-feira, 8 de abril de 2014 16:09
    segunda-feira, 7 de abril de 2014 18:20

Todas as Respostas

  • Aparentemente está correto o codigo, o que pode estar acontecendo é no seu build vc reconstruir esses dados, como está a propriedade de sua tabela chamada 'Copy to Output Directory' que fica em solution explorer no seu arquivo .mdf, deveria estar 'Copy if never'.

    Uma outra coisa é se vc testou ao executar o metodo excluir sem fechar o programa os dados continuam lá nas tabelas ?

    segunda-feira, 7 de abril de 2014 13:40
  • Não consegui encontrar essa propriedade, pode tentar explicar melhor como chegar lá? A base de dados aparece-me .sdf e não .mdf... 

    Eu tenho um form com um datagrid carregado com os dados. Quando faço eliminar, para atualizar esse datagrid tenho de ir para o form inicial e abrir o form do datagrid novamente pois não sei como fazer para atualizar diretamente. No entanto, ao fazer isso, os dados "eliminados" não aparecem...

    Se fechar totalmente o programa e executar novamente, os dados "eliminados" aparecem novamente. às vezes acontece não aparecerem, mas se consultar as tabelas diretamente eles estão lá, e depois dessa consulta, ao executar o programa, os dados reaparecem no datagrid. 

    Edit: Já encontrei a tal propriedade, está "Copy if newer"

    • Editado CrAsilva segunda-feira, 7 de abril de 2014 13:49
    segunda-feira, 7 de abril de 2014 13:48
  • Mas esqueça o form ! Apaga ou não apaga da tabela quando vc executa o delete ?
    segunda-feira, 7 de abril de 2014 14:11
  • Não... Quando vou consultar diretamente a tabela os dados continuam lá
    segunda-feira, 7 de abril de 2014 14:15
  • Altere seu codigo e tente assim :

    //Dados eliminar tabela de associação
    string eliminaDer = "DELETE FROM ClienteEngrenagem WHERE IDEngrenagem = @IDEngA";
    SqlCeCommand queryeliminaDer = new SqlCeCommand(eliminaDer, con);
    queryeliminaDer.Parameters.AddWithValue(@"IDEngA", num);      
    
    try {
    queryeliminaDer.ExecuteNonQuery();
    
    
    //Dados eliminar tabela engrenagens      
    string elimina = "DELETE FROM Engrenagem WHERE IDEngrenagem = @IDEngB";
    SqlCeCommand queryelimina = new SqlCeCommand(elimina, con);      
    queryelimina.Parameters.AddWithValue(@"IDEngB", num);    
    
    queryelimina.ExecuteNonQuery();
    
    //neste momento olhe na database e veja se os dados persistem
    //se persistir pode ser o id que pode estar errado
    
    Caso persista sem deletar teste sua query diretamente em sua tabela sem C#... Como se fosse fazer um DELETE usando o Management do Sql Server.

    segunda-feira, 7 de abril de 2014 14:32
  • Agora acontece algo ainda mais estranho. Ao executar tudo corre bem, ao consultar as tabelas os dados continuam lá, no entanto mesmo fechando o visual studio e abrindo de novo esses dados não aparecem no datagrid... 

    Tentei eliminar um registo dos supostamente apagados no Management, apagou corretamente. Depois disto os outros registos apagados já aparecem no datagrid do form... 

    • Editado CrAsilva segunda-feira, 7 de abril de 2014 14:43
    segunda-feira, 7 de abril de 2014 14:40
  • Está muito estranho isso, bom se puder disponibilize o projeto no One Drive ou poste todo o codigo, desse form onde atualiza a grid onde carrega tudo, pq assim fica dificil isso deveria funcionar...
    segunda-feira, 7 de abril de 2014 14:53
  • Eu ponho na drive, mas preciso de um email para fazer a partilha, não queria colocar na pasta pública 
    segunda-feira, 7 de abril de 2014 15:00
  • daniel......@hotmail.com ,

    Quando por posta aqui p mim apagar o emai daqui.


    segunda-feira, 7 de abril de 2014 15:03
  • Já partilhei a pasta,pode apagar o mail daqui :)
    segunda-feira, 7 de abril de 2014 15:07
  • Olá CrAsilva, se possivel va no diretorio de sua aplicação a faça o zip de sua pasta e compartilhe fica mais simples de abrir toda a solution.
    segunda-feira, 7 de abril de 2014 16:15
  • Coloquei um .zip com todo o projeto 
    segunda-feira, 7 de abril de 2014 16:47
  • Olá CrAsilva, nesse projeto estava faltando a query de deletar o ClienteEngrenagem, veja como ficou tudo :

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Data.SqlServerCe;
    
    namespace TestesBaseDados_0104
    {
        public partial class frm_clientes : Form
        {
            
            public frm_clientes()
            {
                InitializeComponent();
            }
    
            private void frm_clientes_Load(object sender, EventArgs e)
            {
                SqlCeConnection con = new SqlCeConnection(@"Data Source=C:\Users\cris__000.LUISFILIPE\Desktop\DB_Test\TestesBaseDados_0104\TestesBaseDados_0104\DB_Asafil.sdf");
                            con.Open();
                SqlCeDataAdapter adapt = new SqlCeDataAdapter(" SELECT * FROM Cliente", con);
                SqlCeCommandBuilder build = new SqlCeCommandBuilder(adapt);
                con.Close();
                DataTable table = new DataTable();
                adapt.Fill(table);
                dg_clientes.DataSource = table;
            }
    
            private void bt_removercliente_Click(object sender, EventArgs e)
            {
                SqlCeConnection con = new SqlCeConnection(@"Data Source=C:\Users\cris__000.LUISFILIPE\Desktop\DB_Test\TestesBaseDados_0104\TestesBaseDados_0104\DB_Asafil.sdf");
                
                //obtem o id do cliente para a variável num
                int num = Convert.ToInt32(dg_clientes.CurrentRow.Cells[0].Value);
    
                DialogResult res = MessageBox.Show("Tem a certeza que pretende remover a linha seleccionada?", "Confirmação", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (res == DialogResult.Yes)
                {
                    try
                    {
                        con.Open();
                    }
                    catch
                    {
                        MessageBox.Show("Erro de ligação!");
                    }
                    
                    //Query de procura na base de dados
                    string queryPesquisa = "SELECT IDCliente FROM CLIENTE WHERE IDCliente = @IdCliente";
                    //execução do comando
                    SqlCeCommand numero = new SqlCeCommand(queryPesquisa, con);
                    numero.Parameters.AddWithValue("@IdCliente", num);
    
                    //ler recebe o resultado do comando
                    SqlCeDataReader ler = numero.ExecuteResultSet(ResultSetOptions.Scrollable);
                    //se o ler tiver valor - se o comando tiver resultado nalgum registo
                    if (ler.HasRows == true)
                    {
                        try
                        {
                            //PARA REMOVER O CLIENTE ANTES REMOVER O CLIENTEENGRENAGEM
                            string delClienteEngrenagem = "DELETE FROM ClienteEngrenagem WHERE IDCliente = @IDCliente";
    
    
                            SqlCeCommand cmd = new SqlCeCommand(delClienteEngrenagem, con);
                            cmd.Parameters.AddWithValue("@IdCliente", num);
                            int n = cmd.ExecuteNonQuery();
    
                            string queryDelete = "DELETE FROM Cliente WHERE IDCliente = @IdCliente";
                            SqlCeCommand Apagar = new SqlCeCommand(queryDelete, con);
                            Apagar.Parameters.AddWithValue("@IdCliente", num);
                            Apagar.ExecuteNonQuery();
                            con.Close();
                            //Apaga o registo da tabela - como actualizar de novo?! 
                            int selectedIndex = dg_clientes.CurrentCell.RowIndex;
                            if (selectedIndex > -1)
                            {
                                dg_clientes.Rows.RemoveAt(selectedIndex);
                                dg_clientes.Refresh(); 
    
                            }
                            MessageBox.Show("Cliente removido com sucesso", "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                        catch(Exception ex)
                        {
                            con.Close();
                            MessageBox.Show(ex.Message + "Erro ao apagar registo, cliente com engrenagens associadas!", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    else
                    {
                        MessageBox.Show("Erro crítico!", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
    
    
                }
            }
    
            private void bt_adicionarcliente_Click(object sender, EventArgs e)
            {
                frm_adicionarcliente AdicionarCliente = new frm_adicionarcliente();
                AdicionarCliente.ShowDialog();
            }
    
            private void bt_editarcliente_Click(object sender, EventArgs e)
            {
                string idc = dg_clientes.CurrentRow.Cells[0].Value.ToString();
                string nomec = dg_clientes.CurrentRow.Cells[1].Value.ToString();
                string moradac = dg_clientes.CurrentRow.Cells[2].Value.ToString();
                string nifc = dg_clientes.CurrentRow.Cells[3].Value.ToString();
                string telc = dg_clientes.CurrentRow.Cells[4].Value.ToString();
    
                frm_editarcliente EditarCliente = new frm_editarcliente(idc, nomec, moradac, nifc, telc);
                EditarCliente.ShowDialog();
            }
        }
    }
    

    segunda-feira, 7 de abril de 2014 17:08
  • Estive a ver, mas a correção não é por aí, penso eu, porque eu não quero remover o cliente caso este tenha engrenagens. Se as tiver tem de ser impossível remover.

    O problema não está na parte do cliente mas sim das engrenagens... Quando eu quero remover a engrenagem tenho de remover primeiro da tabela ClienteEngrenagem para a desassociar e  só depois remover da tabela Engrenagem. A correção que me fez é no form do cliente, e aí eu penso ter tudo como preciso 

    segunda-feira, 7 de abril de 2014 17:20
  • Entendi, então mas e se a engrenagem estiver cliente você vai remover mesmo assim ?
    segunda-feira, 7 de abril de 2014 17:29
  • Sim, a engrenagem pode ser removida, mas nesse caso tem de se eliminar antes da tabela de associação...
    segunda-feira, 7 de abril de 2014 18:06
  • Olá, agora eu entendi o erro era no ID que vc buscava, alterei para usar parametros e criei um método para atualizar a grid, agora esá ok :

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Data.SqlServerCe;
    
    namespace TestesBaseDados_0104
    {
        public partial class frm_engrenagens : Form
        {
            public SqlCeConnection con = new SqlCeConnection(Properties.Settings.Default.DB_AsafilConnectionString);
    
            public frm_engrenagens()
            {
                InitializeComponent();
            }
    
            private void frm_engrenagens_Load(object sender, EventArgs e)
            {
                AtualizaDataGrid();
            }
    
            private void bt_adicionarengrenagem_Click(object sender, EventArgs e)
            {
                frm_adicionarengrenagem AdicionarEngrenagem = new frm_adicionarengrenagem();
                AdicionarEngrenagem.ShowDialog();
            }
    
            private void bt_removerengrenagem_Click(object sender, EventArgs e)
            {
                //Pega o valor do IDEnrenagem do datagridview
                string num = (string)dg_engrenagens.CurrentRow.Cells[2].Value; //ok
                DialogResult res = MessageBox.Show("Tem a certeza que pretende eliminar a engrenagem selecionda?", "Confirmação", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if(res == DialogResult.Yes)
                {
                    try
                    {
                        con.Open();
                    }
                    catch
                    {
                        MessageBox.Show("Erro com a base de dados!", "ERRO", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    string eliminaDer = "DELETE FROM ClienteEngrenagem WHERE IDEngrenagem = @IDEngrenagem";
                    SqlCeCommand queryeliminaDer = new SqlCeCommand(eliminaDer, con);                
                    queryeliminaDer.Parameters.AddWithValue("@IDEngrenagem", num);
    
                    try
                    {
                        queryeliminaDer.ExecuteNonQuery();
                        //Dados eliminar tabela engrenagens      
                        string elimina = "DELETE FROM Engrenagem WHERE IDEngrenagem = @IDEngrenagem";
                        SqlCeCommand queryelimina = new SqlCeCommand(elimina, con);
                        queryelimina.Parameters.AddWithValue("@IDEngrenagem", num);
                        queryelimina.ExecuteNonQuery();
                        con.Close();
                    }
                    catch (SqlCeException exp)
                    {
                        con.Close();
                        MessageBox.Show(exp.ToString());
                    }                
                    MessageBox.Show("Engrenagem eliminada com sucesso", "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    AtualizaDataGrid();
                }
               
            }
    
            //CRIEI ESSE METODO PARA ATUALIZAR O DATAGRID
            void AtualizaDataGrid()
            {
                con.Open();
                SqlCeDataAdapter adapt = new SqlCeDataAdapter(" SELECT  Cliente.IDCliente, Cliente.NomeCliente, Engrenagem.IDEngrenagem, Engrenagem.Modulo, Engrenagem.AnguloBeta, Engrenagem.Correcao, Engrenagem.NumeroDentes FROM Cliente INNER JOIN ClienteEngrenagem ON Cliente.IDCliente = ClienteEngrenagem.IDCliente INNER JOIN Engrenagem ON ClienteEngrenagem.IDEngrenagem = Engrenagem.IDEngrenagem", con);
                SqlCeCommandBuilder build = new SqlCeCommandBuilder(adapt);
                con.Close();
                DataTable table = new DataTable();
                adapt.Fill(table);
                dg_engrenagens.DataSource = table;
            }
        }
    }
    

    • Sugerido como Resposta Giovani Cr segunda-feira, 7 de abril de 2014 19:05
    • Marcado como Resposta CrAsilva terça-feira, 8 de abril de 2014 16:09
    segunda-feira, 7 de abril de 2014 18:20
  • Olá, estive a ver e a testar o código, no entanto persiste o problema. Quando elimino aparentemente está tudo OK mas o registo permanece na base de dados... Deve haver algum problema com a base de dados, isto é muito estranho...
    terça-feira, 8 de abril de 2014 09:39
  • Olá CrAsilva, está funcionando sim, o que deve estar acontecendo é que você tem um arquivo de base de dados em seu Visual Studio e quando você roda o programa você gera outro arquivo .sdf, então quando faz o DELETE esse é feito no seu arquivo em runtime ou seja no caminho que está seu exe geralmente seucaminho/bin/Release/veja aqui seu arquivo .sdf faça os delete e abra esse arquivo no seu visual studio e veja que são apagados sim seus dados.

    Você pode obter mais informações nesse link. 

    terça-feira, 8 de abril de 2014 11:10
  • Olá, penso que não entendi muito bem. Na pasta /bin/release não existe nenhum ficheiro... O ficheiro de base de dados aparece na pasta do projeto e também na pasta debug... Devo apagar algum deles? 

    Desculpa estar a chatear com isto...

    Edit:

    Já consegui resolver, tinha a ver com a connection string..

    Eu tinha isto:

    public SqlCeConnection con = new SqlCeConnection(Properties.Settings.Default.DB_AsafilConnectionString);

    substitui por:

    public SqlCeConnection con = new SqlCeConnection(@"Data Source=C:\Users\***\***\***\TestesBaseDados_0104\TestesBaseDados_0104\DB_Asafil.sdf");

    E ficou Ok.... 

    Já agora, e desculpa estar já  abusar das perguntas, sabes como posso fazer para atualizar um form a partir de outro?

    Por exemplo, eu para adicionar um cliente não uso o datagrid, uso um form novo. Quando adiciono um cliente esse form de adicionar é fechado e fica o da listagem dos clientes, no entanto o novo cliente fica em falta porque esse form não foi "recarregado", ficou em background enquanto o form para adicionar o cliente aparece "por cima"... 

    • Editado CrAsilva terça-feira, 8 de abril de 2014 11:51
    terça-feira, 8 de abril de 2014 11:40
  • Entendi que bom que resolveu seu problema ! 

    Só uma coisa quando houver duvidas diferentes é recomendável abrir outro post para quando alguém tiver a mesma dúvida procurar esse post e ver a resposta correta do problema.

    Vou tentar lhe explicar se não conseguir sugiro abir outro post ok :

    Então você pode criar um método publico nesse form de cliente e chamá-lo após inserir o registro de clientes, e esse método vai fazer novamente a select no banco de dados e atualizar seu datagrid.

    terça-feira, 8 de abril de 2014 14:50
  • Ok obrigado pela ajuda... Vou tentar e caso não dê abr outro tópico.

    Muito obrigado mais uma vez ;) 

    terça-feira, 8 de abril de 2014 16:15