La instrucción ALTER TABLE está en conflicto con la restricción FOREIGN KEY

184

Tengo un problema al intentar agregar una clave externa a mi tblDomaretabla; ¿Qué estoy haciendo mal aquí?

CREATE TABLE tblDomare
(PersNR VARCHAR (15) NOT NULL,
fNamn VARCHAR (15) NOT NULL,
eNamn VARCHAR (20) NOT NULL,
Erfarenhet VARCHAR (5),
PRIMARY KEY (PersNR));

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (6811034679,'Bengt','Carlberg',10);

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (7606091347,'Josefin','Backman',4);

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (8508284163,'Johanna','Backman',1);

CREATE TABLE tblBana
(BanNR VARCHAR (15) NOT NULL,
PRIMARY KEY (BanNR));

INSERT INTO tblBana (BanNR)
Values (1);

INSERT INTO tblBana (BanNR)
Values (2);

INSERT INTO tblBana (BanNR)
Values (3);

ALTER TABLE tblDomare
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);

Mensaje de error:

La instrucción ALTER TABLE entró en conflicto con la restricción FOREIGN KEY "FK_ tblDomare _PersN__5F7E2DAC". El conflicto ocurrió en la base de datos "almu0004", tabla "dbo.tblBana", columna 'BanNR'.

usuario3162932
fuente

Respuestas:

333

Ocurrió porque trataste de crear una clave foránea desde tblDomare.PersNRa tblBana.BanNRpero / y los valores en tblDomare.PersNRno coincidían con ninguno de los valores en tblBana.BanNR. No puede crear una relación que viole la integridad referencial.

Smutje
fuente
87
Esta fue la respuesta para mí, pero aún me costaba darme cuenta de dónde estaba el problema, así que daré un ejemplo de laico. Si tiene una tabla llamada 'Pedidos' y una tabla llamada 'Clientes', y ha eliminado algunos clientes antiguos, pero no sus pedidos, recibirá este error si decide hacer una clave foránea de Pedidos. Id. De cliente a clientes .Carné de identidad. Algunos pedidos ya no tienen un cliente correspondiente, por lo que es imposible agregar la clave externa.
Chad Hedgcock
10
Aquí hay una consulta para verificar los valores incorrectos: seleccione una referencia de tabla distinta. ReferenceColumn de referrerTable.
jumxozizi
66
En caso de necesidad, también puede usar la opción "ALTER TABLE tablename WITH NOCHECK ..." para agregar el FK. Esto le permitirá agregar la relación, aunque los datos existentes rompan la restricción. Obviamente, es mejor limpiar sus datos primero, pero esto al menos le da otra opción.
DaveInMaine
2
@DaveInMaine Si uno desactiva las restricciones de la base de datos "cuando se desea", me preguntaría por qué preocuparse con ellas en primer lugar y no simplemente omitirlas si no le interesa la integridad de la base de datos.
Smutje
1
¡Qué pésimo mensaje de error! lo vi antes pero me pilló completamente desprevenido justo ahora que pensaba que algo estaba dañado
Simon_Weaver
43

Esta consulta fue muy útil para mí. Muestra todos los valores que no tienen coincidencias.

select FK_column from FK_table
WHERE FK_column NOT IN
(SELECT PK_column from PK_table)
dantey89
fuente
37

Prueba esta solución:

Hay un elemento de datos en su tabla cuyo valor asociado no existe en la tabla que desea usar como tabla de clave principal. Haga su tabla vacía o agregue el valor asociado a la segunda tabla.

PatsonLeaner
fuente
29

Es posible crear la clave externa utilizando ALTER TABLE tablename WITH NOCHECK ..., que permitirá datos que violen la clave externa.

Opción "ALTER TABLE tablename WITH NOCHECK ..." para agregar el FK: esta solución funcionó para mí.

Ankita Biswas
fuente
17
Tenga en cuenta que permitir tales violaciones anula el propósito de la restricción de clave externa.
reformado el
Peligroso...!!! Solo debe usarse si no desea perder los datos actualmente en la tabla. Pero incluso entonces, ¿por qué no hacer una copia de seguridad y luego eliminar los ID no válidos?
Andrei Bazanov el
Necesito implementar a través de java / spring / code para hacer eso, no directamente a través de una consulta SQL, cualquier idea de cómo hacer esto con el siguiente código: @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.DETACH) @JoinTable(name = "tbUsuariosTipoOcorrencia", joinColumns = { @JoinColumn(name = "idUsuario") }, inverseJoinColumns = { @JoinColumn(name = "idTipoOcorrencia") }) y lo resolví a través de una consulta en la base de datos:alter table tbUsuariosTipoOcorrencia WITH NOCHECK add constraint FKnbxg3ua7b8c5d53wps69q6jh foreign key (idUsuario) references tbUsuarios
Francisco Souza
11

Supongo que un valor de columna en una tabla de clave externa debe coincidir con el valor de columna de la tabla de clave primaria. Si estamos tratando de crear una restricción de clave externa entre dos tablas donde el valor dentro de una columna (que será la clave externa) es diferente del valor de la columna de la tabla de clave primaria, arrojará el mensaje.

Por lo tanto, siempre se recomienda insertar solo aquellos valores en la columna de clave externa que están presentes en la columna de la tabla de clave primaria.

Por ej. Si la columna de la tabla primaria tiene valores 1, 2, 3 y en la columna de clave externa los valores insertados son diferentes, entonces la consulta no se ejecutará ya que espera que los valores estén entre 1 y 3.

sam05
fuente
11

Antes de agregar una clave externa a la tabla, haga lo siguiente

  1. Asegúrese de que la tabla debe estar vacía o que los datos de la columna deben coincidir.
  2. Asegúrese de que no sea nulo.
  3. Si la tabla contiene no vaya a diseñar y cambiar, hágalo manualmente.

    alterar tabla Tabla 1 agregar clave externa (Nombre de columna) referencias Tabla 2 (Nombre de columna)

    alterar tabla Tabla 1 alterar columna Nombre de columna atributo no nulo

GirishBabuC
fuente
10

Limpie sus datos de sus tablas y luego haga una relación entre ellos.

max
fuente
Gracias max. funcionó para mí si tienen datos, incluso las relaciones son perfectas, el comando Actualizar-Base de datos no funcionará.
robert jebakumar2
No es necesario eliminar ningún dato mientras sea válido de acuerdo con la clave externa que se está creando.
jumxozizi
7

Pruebe DELETElos datos actuales de tblDomare.PersNR. Porque los valores en tblDomare.PersNRno coincidían con ninguno de los valores en tblBana.BanNR.

Campanita
fuente
@agenc ¿respondí tu pregunta?
Pensador Bell
3

También tuve este error ya que Smutje se refirió, asegúrese de que no tenga un valor en la columna de clave externa de su tabla de clave externa base que no esté en su tabla de referencia, es decir (cada valor en su tabla de clave externa base (valor de una columna que es clave externa) también debe estar en la columna de la tabla de referencia) es bueno vaciar primero la tabla de clave externa base y luego configurar las claves externas

ako
fuente
2

los datos que ha ingresado en una tabla (tbldomare) no coinciden con los datos que le ha asignado la tabla de clave primaria. escriba entre tbldomare y agregue esta palabra (con nocheck) luego ejecute su código.

por ejemplo, usted ingresó una tabla tbldomar estos datos

INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (6811034679,'Bengt','Carlberg',10);

y asignaste una foreign keytabla para aceptar solo1,2,3 .

tiene dos soluciones, una es eliminar los datos que ha ingresado en una tabla y luego ejecutar el código. otra es escribir esta palabra (con nocheck) ponla entre el nombre de tu tabla y agrega así

ALTER TABLE  tblDomare with nocheck
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);
Khadar
fuente
2

Esto me sucede, ya que estoy diseñando mi base de datos, me doy cuenta de que cambio mi semilla en mi tabla principal, ahora la tabla relacional no tiene una clave externa en la tabla principal.

Entonces necesito truncar ambas tablas, ¡y ahora funciona!

Willy David Jr
fuente
2

Debería ver si sus tablas tienen algún dato en las filas. Si "sí", entonces usted debe truncar la tabla (s) o de lo contrario puede hacer que tengan el mismo número de datos a tblDomare.PersNRa tblBana.BanNRy tornillo de banco-verso.

adrianex03
fuente
2

Smutje está en lo correcto y Chad HedgeCock ofreció un gran ejemplo de laico. Me gustaría construir sobre el ejemplo de Chad ofreciendo una forma de encontrar / eliminar esos registros. Usaremos al Cliente como el Padre y el Pedido como el niño. CustomerId es el campo común.

select * from Order Child 
left join Customer Parent on Child.CustomerId = Parent.CustomerId
where Parent.CustomerId is null 

si estás leyendo este hilo ... obtendrás resultados. Estos son niños huérfanos. seleccione * del Pedido Hijo izquierdo unirse al Cliente Principal en Child.CustomerId = Parent.CustomerId donde Parent.CustomerId es nulo Tenga en cuenta el recuento de filas en la parte inferior derecha.

¡Ve a verificar con quien necesites que vas a eliminar estas filas!

begin tran 
delete Order
from Order Child 
left join Customer Parent on Child.CustomerId = Parent.CustomerId
where Parent.CustomerId is null 

Ejecuta el primer bit. Verifique el recuento de filas = lo que esperaba

cometer el tran

commit tran 

Ten cuidado. La programación descuidada de alguien te metió en este lío. Asegúrese de comprender el por qué antes de eliminar a los huérfanos. Tal vez el padre necesita ser restaurado.

Greg
fuente
Gracias por la respuesta. Estoy jugando con la base de datos stackoverflow (gamedev en realidad) y encontré dos NULLs cuando dejé unirme a las insignias con los usuarios. No es de extrañar que las restricciones no funcionen ...
Nicholas Humphrey
1

En mi escenario, usando EF, al intentar crear esta nueva clave externa en los datos existentes, estaba tratando de completar los datos (hacer los enlaces) DESPUÉS de crear la clave externa.

La solución es completar sus datos antes de crear la clave externa, ya que los verifica a todos para ver si los enlaces son realmente válidos. Por lo tanto, no podría funcionar si aún no lo ha poblado.

jeromej
fuente
1

Me encuentro con algún problema en mi proyecto.

ingrese la descripción de la imagen aquí

En la tabla secundaria, no hay ningún ID de registro igual a 1 y 11

mago

Inserté la tabla DEAL_ITEM_THIRD_PARTY_PO cuyo Id es igual a 1 y 11, luego puedo crear FK

Metin Atalay
fuente
0

Primero elimine los datos de esa tabla y luego vuelva a ejecutar la migración. Obtendrás éxito

M. Arslan Riaz
fuente
0

Cuando define una Clave externa en la tabla B que hace referencia a la Clave primaria de la tabla A, significa que cuando un valor está en B, debe estar en A. Esto es para evitar modificaciones inconsistentes en las tablas.

En su ejemplo, sus tablas contienen:

tblDomare con PRIMARY KEY (PersNR) :

PersNR     |fNamn     |eNamn      |Erfarenhet
-----------|----------|-----------|----------
6811034679 |'Bengt'   |'Carlberg' |10
7606091347 |'Josefin' |'Backman'  |4
8508284163 |'Johanna' |'Backman'  |1
---------------------------------------------

tblBana:

BanNR
-----
1
2
3
-----

Esta declaración:

ALTER TABLE tblDomare
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);

dice que cualquier línea tblDomarecon clave PersNRdebe tener una correspondencia en la tabla tblBanaen clave BanNR. Su error es porque tiene líneas insertadas entblDomare sin correspondencia entblBana .

2 soluciones para solucionar su problema: agregue líneas tblBanaconBanNR in (6811034679, 7606091347, 8508284163) - or remove all lines in tblDomarethat have no correspondance in tblBana` (pero su tabla estaría vacía)

Consejo general : debe tener la restricción de clave externa antes de llenar las tablas. Las claves externas están aquí para evitar que el usuario de la tabla llene las tablas con inconsistencias.

belka
fuente
-3

y solo para su información, en caso de que haga todas sus verificaciones de referencia de datos y no encuentre datos incorrectos ... ¡aparentemente no es posible crear una restricción de clave externa entre dos tablas y campos donde esos campos son la clave principal en ambas tablas! No me preguntes cómo sé esto.

Doug Boude
fuente