Erros na criação de Foreign Key’s no MySql

MySqlOlha eu aqui de novo…. continuando o meu projeto de remodelagem do banco de dados do sistema que irei desenvolver daqui pra frente me deparei com vários erros ao tentar criar minhas foreign keys… então vou listá-los aqui para explicar tudo que descobri e quem sabe ajudar você colega desenvolvedor que está batendo cabeça num erro não muito claro que o MySql te oferece… tem horas que chega a cansar a beleza…

Erro 1:


alter table [tabela1] add constraint fk_tabela1_x_tabela2 foreign key (idTabela1) references tabela2 (idTabela2) on delete restrict on update cascade;
[Err] 1005 - Can't create table 'basedados.#sql-11e0_4f' (errno: 150)

Solução 1:

ERRNO 150… o que é!?

No meu caso o problema foi o seguinte… não sei porque cargas d’água que em algumas tabelas os campos que seriam a minha foreign key estava com o UNSIGNED ligado. E o campo referenciado (primary key da outra tabela) logicamente não era UNSIGNED.

Para quem não sabe, o UNSIGNED define que um campo inteiro ou numérico não pode receber valores negativos (somente valores sem sinal).

Ou seja, ao criar integridade referencial, os campos envolvidos devem ser UNSIGNED ou SIGNED. Se forem divergentes o MySql retornará o ERRNO 150.

Para acertar, eu tive que fazer um modify na coluna que seria minha FK em cada tabela para retirar o UNSIGNED:

#se a definição do seu campo é algo mais ou menos assim
campo1 int(6) UNSIGNED NOT NULL AUTO_INCREMENT;

#repita-o somente tirando o UNSIGNED
alter table tabela1 modify campo1 int(6) NOT NULL AUTO_INCREMENT;

Erro 2:


[SQL] alter table [tabela1] add constraint fk_tabela1_x_tabela2 foreign key (idTabela1) references tabela2 (idTabela2) on delete restrict on update cascade;
[Err] 1452 - Cannot add or update a child row: a foreign key constraint fails (`basedados`.`#sql-11e0_4f`, CONSTRAINT `fk_tabela1_x_tabela2` FOREIGN KEY (`idTabela1`) REFERENCES `tabela2` (`idTabela2`) ON UPDATE CASCADE)

Solução 2:

Que que ocorre nesse ERR 1452?!?!?!

Esse erro ocorre não só na criação da foreign key, mas pode acontecer também quando a foreign key já existir na tabela e você estiver atualizando ou inserindo dados nesta tabela. No caso, esse erro está indicando que constraint foreign key falhou…. Mas como falhou!?!?

Muito simples… a informação do campo da foreign key não é encontrada na tabela2 (a tabela que possui a primary key referenciada). No meu caso, como estou criando as relações em uma base que já existe e já possui informações cadastradas, significa dizer que na tabela1 que eu estou tentando criar a foreign key eu tenho uma ou mais linhas que estão referenciando uma chave primária que não existe na minha ‘tabela2’ (a tabela referenciada).

Se a foreign key já existir e você receber esse erro, significará que você está editando ou inserindo um registro e passando um valor para o campo da foreign key que não possui um registro na tabela2 referenciada (tabela da primary key).

Na minha situação, como minhas tabelas já possuem registros e eu não posso simplesmente limpar a tabela toda, tive que fazer sql’s que deletassem os registros que estão referenciando informações inválidas. Ficou assim mais ou menos:


delete a from tabela1 a left join tabela2 b on b.idTabela2 = a.idTabela2 where b.idTabela2 is null;

Ou seja, faço um select com left join nas minhas duas tabelas e deleto as linhas que vierem com as informações da tabela2 nulas.

Erro 3:

[SQL]
alter table orcamento add constraint fk_orcamento_x_seguradora foreign key (codSeguradora) references seguradora (codSeguradora) on delete restrict on update cascade;
[Err] 1005 - Can't create table 'tiseg.#sql-11e0_4f' (errno: 121)

Solução 3:

E o ERRNO 121??

Mais simples ainda… a sua foreign key já existe!!! Pule para seu próximo comando…. =)