Não é possível adicionar ou atualizar uma linha filho: uma restrição de chave estrangeira falha


174

tabela 1

+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| UserID   | int(11)     | NO   | PRI | NULL    | auto_increment |
| Password | varchar(20) | NO   |     |         |                |
| Username | varchar(25) | NO   |     |         |                |
| Email    | varchar(60) | NO   |     |         |                |
+----------+-------------+------+-----+---------+----------------+

mesa 2

+------------------+--------------+------+-----+---------+----------------+
| Field            | Type         | Null | Key | Default | Extra          |
+------------------+--------------+------+-----+---------+----------------+
| UserID           | int(11)      | NO   | MUL |         |                |
| PostID           | int(11)      | NO   | PRI | NULL    | auto_increment |
| Title            | varchar(50)  | NO   |     |         |                |
| Summary          | varchar(500) | NO   |     |         |                |
+------------------+--------------+------+-----+---------+----------------+

Erro:

com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: 
Cannot add or update a child row: a foreign key constraint fails 
(`myapp/table2`, CONSTRAINT `table2_ibfk_1` FOREIGN KEY (`UserID`) 
REFERENCES `table1` (`UserID`)) 

O que eu fiz errado? Li http://www.w3schools.com/Sql/sql_foreignkey.asp e não vejo o que há de errado.


4
Você pode postar a consulta que aciona o erro?
Damp

38
Em poucas palavras, você está tentando inserir / atualizar um valor em table2.UserIDque não existe table1.UserID.
Joe Stefanelli

Não sei por que, mas depois de mover meu banco de dados de um ambiente Windows para o Linux, tive que excluir e recriar uma relação (foi quando percebi o problema). O valor existia, mas remover e adicionar novamente a relação o corrigiu. Você pode ter muito cuidado ao fazê-lo, obviamente.
johnsnails

Respostas:


235

Você está recebendo este erro porque está tentando adicionar / atualizar uma linha table2que não possui um valor válido para o UserIDcampo com base nos valores atualmente armazenados table1. Se você postar mais algum código, eu posso ajudá-lo a diagnosticar a causa específica.


PreparedStatement st = connection.prepareStatement ("Inserir na tabela2 (ID do usuário, ID da postagem, título, resumo)" + "valores (ID do usuário,?,?,") ");
Tom

15
não sei para que serve o voto negativo; minha resposta é perfeitamente válida e correta.
Brian Driscoll

Hmm ... definitivamente não é uma boa ideia misturar parâmetros nomeados com parâmetros sem nome na sua declaração preparada. deve ser "valores (?,?,?,?)" com o valor apropriado para UserID especificado em sua instrução de execução.
Brian Driscoll

Então, eu preciso fazer para outra instrução SQL para obter o ID do usuário da tabela1?
Tom

5
Provavelmente um 0, substitua-o por Null, se for o caso
Jeffrey Nicholson Carré

123

Isso significa que você está tentando inserir table2um UserIDvalor que não existe table1.


104

Um hack simples pode ser desativar as verificações de chave estrangeira antes de executar qualquer operação na tabela. Basta consultar

SET FOREIGN_KEY_CHECKS=0

Isso desativará a correspondência de chave estrangeira em outras tabelas. Depois de terminar a tabela, ative-a novamente

SET FOREIGN_KEY_CHECKS=1

Isso funciona para mim muitas vezes.


Como eu uso isso ??
Sachin de Pune

2
@SachinfromPune basta adicionar SET FOREIGN_KEY_CHECKS = 0; no início do arquivo mysql e SET FOREIGN_KEY_CHECKS = 1; no final do arquivo mysql, reimporte dados
inrsaurabh 15/09

1
Isso não é problemático? Você perde a integridade referencial, certo?
roadrunner66

A integridade referencial é suportada pela presença das entradas de índice corretas. Contanto que você tenha as chaves e os índices corretos, poderá desativar a verificação de chaves durante uma entrada em massa.
Vernon Keenan

46

Eu descobri outro caso estranho: se você acidentalmente criar uma chave estrangeira de uma tabela InnoDB para uma tabela MyISAM, o MySQL lançará esse erro no momento da inserção, mesmo que os dados sejam válidos.

Veja http://nick.zoic.org/art/mysql-foreign-key-error/


1
Sim, tenho o mesmo problema. Duas tabelas devem ser o InnoDB!
Emeraldhieu

2
Eu tive o mesmo problema, obrigado pela dica. Aqui está um link para a documentação do MySQL sobre como converter tabelas do MyISAM para o InnoDB dev.mysql.com/doc/refman/5.7/en/… TLDR: ALTER TABLE table_name ENGINE = InnoDB;
Guilherme Vaz

De fato, esse foi o caso no meu banco de dados. Decidi mudar o mecanismo MyISAM para InnoDB. Finalmente, posso trabalhar com o banco de dados da maneira que eu queria.
11769 Mike

17

Você está recebendo esse erro porque há algum valor int table2.UserIDque não existe table1.UserID(acho que você definiu o table2.UserIDvalor manualmente antes de criar essa chave estrangeira).
Um exemplo para esta cena: table1.UserIDobter valores 1,2,3 e table2.UserIDobter valores 4 (adicionar pelo manual). Então, quando você faz uma chave estrangeira, eles não conseguem encontrar UserID = 4a partir table1e o erro será ocurse.
Para corrigir este erro, basta remover UserID = 4a partir de table2ou você pode esvaziar ambos e, em seguida, criar a chave estrangeira e.
Boa sorte!


11

Demorei um pouco para descobrir. Simplificando, a tabela que referencia a outra tabela já possui dados e um ou mais de seus valores não existe na tabela pai.

por exemplo, a Tabela2 possui os seguintes dados:

UserID    PostID    Title    Summary
5         1         Lorem    Ipsum dolor sit

Tabela 1

UserID    Password    Username    Email
9         ********    JohnDoe     john@example.com

Se você tentar ALTERAR a tabela2 e adicionar uma chave estrangeira, a consulta falhará porque o UserID = 5 não existe na Tabela1.


10

Se você inseriu uma linha na tabela 1 antes de criar a chave estrangeira na tabela 2, receberá um erro de restrição de chave estrangeira, porque o valor do incremento automático é 2 na tabela 1 e 1 na tabela 2. Para resolver isso, é necessário trunque a tabela 1 e defina o valor de incremento automático de volta para 1. Em seguida, você pode adicionar a tabela 2.


10

Verifique se você configurou o mecanismo de banco de dados como InnoDB, porque no MySQL a chave estrangeira e a transação não são suportadas


2
ALTER TABLE my_table ENGINE = InnoDB;
Bishwas Mishra 28/05/19

7

Apenas uma pequena correção: torne o JoinColumn 'nullable = true' na Tabela1 e o campo 'UserID' 'insertable = false' e 'nullable = true' na Tabela2.

Na Entidade Tabela1:

@OneToMany(targetEntity=Table2.class, cascade = CascadeType.ALL)
@JoinColumn(name = "UserID", referencedColumnName = "UserID", nullable = true)
private List<Table2> table2List;

Na Entidade Tabela2:

@Column(insertable = false, nullable = true)
private int UserID;

Esta resposta resolveu totalmente o meu problema, muito obrigado por compartilhar isso. A chave para mim foi adicionar o @Column (insertable = false, nullable = true) no arquivo que eu estou usando como a chave de saída no meu objeto / tabela filho.
Israelm

6

Acabei de ter o mesmo problema, a solução é fácil.

Você está tentando adicionar um ID na tabela filho que não existe na tabela pai.

verifique bem, porque o InnoDB possui o bug que às vezes aumenta a coluna auto_increment sem adicionar valores, por exemplo, INSERT ... ON DUPLICATE KEY


seriamente? não insira uma referência de id que não existe ... apenas verificar
Blaztix

5

Eu tive uma questão semelhante. Você está tentando aplicar chave estrangeira em uma tabela que possui conteúdo e a coluna não é anulável. Você tem duas opções.

  1. Torne a coluna na qual você deseja aplicar restrições de chave estrangeira seja anulável. Dessa forma, a chave estrangeira será aplicada sabendo que alguns campos podem ser anuláveis. ( Isto é o que eu fiz. )
  2. Crie a coluna na qual deseja aplicar a restrição de chave estrangeira, escreva uma consulta para inserir a chave estrangeira na coluna e aplique as restrições de chave estrangeira. ( Não tentei isso, mas deve funcionar )

4

Verifique se o valor que você está inserindo na chave estrangeira existe na tabela pai. Isso me ajudou. Por exemplo, se você inserir user_id = 2em table.2, mas table.1não tiver um user_id = 2, a restrição gerará um erro. O meu era o código de erro # 1452 para ser exato. Espero que isso ajude outras pessoas com o mesmo problema!


3

Eu tive o mesmo problema, e o motivo era que eu tinha uma linha na primeira tabela antes de adicionar a chave estrangeira.


1

Também enfrentei o mesmo problema e o problema era que o valor das entradas da tabela pai não coincide com o valor da tabela de chave estrangeira. Então, tente limpar todas as linhas.


A restrição requer que os usuários mencionados na Tabela2 já estejam definidos na Tabela1.
Sorak

1

Caso as soluções fornecidas por outros não funcionassem. Tente verificar os mecanismos de banco de dados das tabelas pai e filho. No meu caso, eu tinha o mecanismo das tabelas pai definido como "MyISAM", alterando-o para o InnoDB corrigido.

Espero que isso ajude outras pessoas que estão presas como eu.


1

Você não deve colocar um campo ondelete em uma cascata no banco de dados.

Portanto, defina o campo onDelete como RESTRICT

Boa sorte ♥


0

Outro caso estranho que me deu esse erro. Eu referenciei erroneamente minhas chaves estrangeiras à chave primária de identificação. Isso foi causado por comandos incorretos de alteração da tabela. Descobri isso consultando a tabela INFORMATION_SCHEMA (consulte esta resposta do stackoverflow)

A tabela estava tão confusa que não pôde ser corrigida por nenhum comando ALTER TABLE . Eu finalmente larguei a mesa e a reconstruí. Isso se livrou do erro de integridade.


0

Talvez enquanto você adicionou a userIDcoluna, existem dados para essa determinada tabela que ela está estabelecida e, portanto, terá um valor padrão 0, tente adicionar a coluna sem oNOT NULL


0

Também recebi este erro: "Não é possível adicionar ou atualizar uma linha filho: uma restrição de chave estrangeira falha". Recebi o erro ao adicionar uma nova linha à tabela pai

O problema era que a restrição de chave estrangeira havia sido definida na tabela pai em vez da tabela filho.


0

Se você usar o índice mysql ou a relação entre tabelas, primeiro exclua as colunas (por exemplo: city_id) e crie novas colunas com o mesmo nome (por exemplo: city_id). Em seguida, tente novamente ...


0

Existe algum dado existente que a tabela contenha? Nesse caso, tente limpar todos os dados da tabela que você deseja adicionar uma chave estrangeira. Em seguida, execute o código (adicione uma chave estrangeira) novamente.

Eu encontrei esse problema tantas vezes. Essa limpeza de todos os dados da tabela funciona quando você deseja adicionar uma chave estrangeira a uma tabela existente.

Espero que isso funcione :)


0

Exclua índices do campo UserID da tabela2. Seus ternos para mim


-1

a restrição de chave estrangeira da tabela filho está falhando

Esse problema pode ocorrer devido ao seguinte motivo:

Se você estiver fazendo isso no Spring mvc, precisará descrever explicitamente o tipo de id, porque às vezes o mysql falha em reconhecer o tipo de id. para que você defina explicitamente como nas duas tabelas da sua classe de entidade@GeneratedValue (strategy = GenerationType.IDENTITY)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.