(Resolvido) Dúvida Para Excluir - MySQL - Fórum Script Brasil
(Resolvido) Dúvida Para Excluir
Asked by Kogima,
Galera, eu sou iniciante e gostaria de saber se estou fazendo certo e como solucionar minha dúvida.
Eu tenho uma tabela categoria
categoria (codigo_id, categoria)
E uma tabela sub_categoria
sub-categoria(codigo_id,categoria,sub_categoria) onde a categoria indicada aqui recebe o codigo_id da tabela categoria
Caso eu venha excluir uma categoria, como fazer para todas as sub-categorias vinculadas a essa categoria excluida sejam excluidas também
Oi, Kogima!
Você tem três caminhos para solucionar este problema.
O primeiro independe de versão ou engine (tipo de tabela) do Mysql.
O Lado ruim é que se você estiver usando tabelas não transacionais tipo myisam e houver uma falha durante esta transação, então você ficará com tabelas inconsistentes.
A técnica consiste em você deletar os dados da tabela filha e depois deletar os dados da tabela mãe.
Exemplo: Sejam as tabelas Nota_Fiscal e Tabela Item_da_nota_fiscal. Para deletear os dados da nota fiscal de número 1 seria assim:
DETELE FROM Item_da_nota_fiscal WHERE Numero_Nota = 1;
DELETE FROM Nota_Fiscal WHERE Numero_Nota = 1;
A segunda técnica você deverá estar usando a versão 4.1x ou superior (de preferência a versão 5.x) do MySQL com tabelas tipo Tansacionais INNODB ou MAXDB. Consiste em alterar a estrutura da tabela Item_da_nota_fiscal para a inclusão de constraints deste tipo:
ALTER TABLE Item_da_nota_fiscal
ADD CONSTRAINT FK_Item_da_nota_fiscal FOREIGN KEY(Numero_Nota)  REFERENCES Nota_Fiscal (Numero_Nota) ON DELETE CASCADE ON UPDATE CASCADE;
Constraint permite que uma exclusão ou atualização na tabela pai se reflita na tabela filha. Assim o comando de delete só se aplicaria a tabela pai. Outra vantagem deste tipo de comando é que você não conseguirá incluir nenhum item na tabela filha sem que antes você inclua na tabela pai. Ou seja, Tem que haver um registro na tabela pai para que haja um registro na tabela filha. O comando de deleção seria:
A terceira forma novamente independe de tipo de tabela mas depende de você estar usando uma versão 5.x do MySQL. Consiste em utilizar triggers.
Triggers são gatilhos que são disparados quando um evento de inclusão, alteração ou exclusão ocorre em uma tabela do banco de dados.
Então, você criaria uma trigger conforme eu mencionei no tópico http://scriptbrasil.com.br/forum/index.php?showtopic=109864, adaptando as suas necessidades e, depois, você usaria somente o comando de deletar na tabela pai, conforme exemplo 2.
É só. Tente fazer e havendo dúvidas relate novamente.
Quanto a estruturação de suas tabelas, sugiro que você leia sobre normalização de banco de dados e havendo dúvidas abra novo tópico para discutirmos a respeito.
Caramba, você explicou legal pra caramba, valeu mesmo, vo tentar fazer e qualquer coisa posto aqui de novo...
Olha como ficou, utilizei o CONSTRAINT, é assim mesmo?
ALTER TABLE `menu_sub_categoria`
ADD CONSTRAINT `menu_sub_categoria_ibfk_1` FOREIGN KEY (`categoria`) REFERENCES `menu_categoria` (`codigo_id`) ON DELETE CASCADE ON UPDATE CASCADE;
Minhas tabelas---------------------------------------------------------------------------------------------------------
CREATE TABLE `menu_categoria` (
`codigo_id` int(11) NOT NULL auto_increment,
`categoria` varchar(35) NOT NULL,
`loja` int(5) NOT NULL,
PRIMARY KEY  (`codigo_id`),
UNIQUE KEY `categoria` (`categoria`,`loja`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4;
CREATE TABLE `menu_sub_categoria` (
`sub_categoria` varchar(150) NOT NULL,
`loja` int(8) NOT NULL,
`id_conteudo` int(2) NOT NULL,
UNIQUE KEY `categoria` (`categoria`,`sub_categoria`,`loja`,`id_conteudo`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=8;
Legal! é isso mesmo.
Só um detalhe que não parece muito mas em tabela muito populadas pode gastar um espaço considerável. Observe seu código quando você usou `codigo_id` int(11) NOT NULL auto_increment,
você poderia ter usado `codigo_id` int(10) unsigned NOT NULL auto_increment, já que seu autoincrement não vai trabalhar com números negativos. Usar tipo unsigned pata inteiros economiza o byte de sinal que os números não unsigned necessitam.