Recebo esta mensagem de erro:
ERROR 1217 (23000) na linha 40: Não é possível excluir ou atualizar uma linha pai: uma restrição de chave estrangeira falha
... quando tento derrubar uma mesa:
DROP TABLE IF EXISTS `area`;
... definido assim:
CREATE TABLE `area` (
`area_id` char(3) COLLATE utf8_spanish_ci NOT NULL,
`nombre_area` varchar(30) COLLATE utf8_spanish_ci NOT NULL,
`descripcion_area` varchar(100) COLLATE utf8_spanish_ci NOT NULL,
PRIMARY KEY (`area_id`),
UNIQUE KEY `nombre_area_UNIQUE` (`nombre_area`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci;
O engraçado é que eu já eliminei todas as outras tabelas do esquema que possuem chaves estrangeiras area
. Na verdade, o banco de dados está vazio, exceto pela area
tabela.
Como pode haver linhas filho se não houver nenhum outro objeto no banco de dados? Pelo que eu sei, o InnoDB não permite chaves estrangeiras em outros esquemas, permite?
(Posso até executar um RENAME TABLE area TO something_else
comando: -?)
CONSTRAINT fk_servicio_area1 FOREIGN KEY (area_id) REFERENCES area (area_id)
, ou seja, nenhum nome de esquema na referência de tabela: -?Respostas:
Duas possibilidades:
Você pode ver qual tabela era (uma delas, pelo menos) fazendo um "MOSTRAR STATUS DO ENGINE INNODB" depois que o drop falhar.
Se for o último caso, descartarei e restaurarei todo o servidor, se possível.
O MySQL 5.1 e superior fornecerão o nome da tabela com o FK na mensagem de erro.
fonte
SHOW ENGINE INNODB STATUS
relatórios.Sob demanda, agora como uma resposta ...
Ao usar o MySQL Query Browser ou phpMyAdmin, parece que uma nova conexão é aberta para cada consulta ( bugs.mysql.com/bug.php?id=8280 ), tornando necessário escrever todas as instruções drop em uma consulta, por exemplo.
Onde o
SET FOREIGN_KEY_CHECKS=1
serve como medida de segurança extra ...fonte
SET FOREIGN_KEY_CHECKS=0;
ao início do dump.Desativar verificação de chave estrangeira
fonte
SET FOREIGN_KEY_CHECKS=0
e corrige a mensagem de erro. Você tem alguma ideia de por que isso é necessário? As chaves estrangeiras são armazenadas em cache mesmo depois que as tabelas desaparecem?SET FOREIGN_KEY_CHECKS=1;
depois de terminar!SET FOREIGN_KEY_CHECKS=0; DROP TABLE my_first_table_to_drop; DROP TABLE my_second_table_to_drop; SET FOREIGN_KEY_CHECKS=1;
Onde SET FOREIGN_KEY_CHECKS = 1 serve como uma medida de segurança extra ...a partir deste blog :
Você pode desativar temporariamente as verificações de chave estrangeira:
Apenas certifique-se de restaurá-los quando terminar de mexer:
fonte
espero que seja o trabalho
SET Foreign_key_checks = 0; DROP TABLE
table name
; SET Foreign_key_checks = 1;fonte
No Rails, pode-se fazer o seguinte usando
rails console
:fonte
Talvez você tenha recebido um erro ao trabalhar com esta tabela antes. Você pode renomear a tabela e tentar removê-la novamente.
fonte
Eu encontrei uma solução fácil, exporte o banco de dados, edite o que você deseja editar em um editor de texto, depois importe. Feito
fonte
CREATE TABLE
código e carregar o dump novamente ... não fará com que o MySQL remova a tabela. E se você quer dizer restaurar o dump em um novo banco de dados ... Se você quiser apagar todas as tabelas como eu, um banco de dados recém-criado já estará vazio. Se você quiser manter algumas tabelas, aSET FOREIGN_KEY_CHECKS=0
solução alternativa mencionada em todos os lugares aqui funciona bem e é mais simples; e você provavelmente não precisa editar o dump, pois a nova cópia de seus dados possivelmente não terá um dicionário de dados fora de sincronia.Não é possível excluir ou atualizar uma linha pai: uma restrição de chave estrangeira falha (
table1
.user_role
, CONSTRAINTFK143BF46A8dsfsfds@#5A6BD60
FOREIGN KEY (user_id
) REFERENCESuser
(id
))O que fiz em duas etapas simples. primeiro eu deleto a linha filha na tabela filha, como
mysql> delete from table2 onde role_id = 2 && user_id = 20;
Consulta OK, 1 linha afetada (0,10 seg)
e a segunda etapa como excluir o pai
excluir da tabela1 onde id = 20;
Consulta OK, 1 linha afetada (0,12 s)
Com isso eu resolvo o problema, o que significa excluir filho e depois excluir pai
Espero que você tenha entendido. :)
fonte