J'ai créé une table appelée TableTest avec deux colonnes ent
et dep
. ent
est la clé primaire et dep
est la clé étrangère qui fait référence à ent
. Je crée le tableau en utilisant:
INSERT INTO TableTest(ent, dep) VALUES ('A1','A3');
Je dois montrer que les trois valeurs (A1, A2, A3) dépendent l'une de l'autre. A3 dépend de A1 etc. Cependant, lorsque j'essaye d'insérer une ligne dans ma table telle que:
CREATE TABLE TableTest ( ent varchar(2) NOT NULL, dep varchar(2), PRIMARY KEY (ent), FOREIGN KEY (dep) REFERENCES TableTest(ent) );
J'obtiens l'erreur suivante et après avoir fait des recherches, je suis toujours bloqué sur la façon de s'en sortir. Je suis très nouveau dans SQL.
ORA-02291: contrainte d'intégrité violée - clé parente introuvable
Toute aide est grandement appréciée!
3 Réponses :
Tout d'abord, vous devez insérer la valeur racine
.
> insert into TableTest values ('A1', null); > insert into TableTest values ('A3', 'A1');
cela ne signifierait-il pas A3 comme ent et A1 comme dépendant dans ce cas? A3 dépend de A1 et ne doit donc pas être commuté. Quand je fais cela, j'obtiens toujours une erreur similaire.
Il n'y a pas de «valeur racine» - l'OP n'a jamais dit que les données étaient un arbre. Et en effet ce n'est pas le cas; c'est un cycle. L'OP a déclaré que les dépendances sont circulaires. Je vois que votre réponse a déjà trois votes positifs; même ainsi, si j'étais vous, je le supprimerais, car vous n'avez clairement pas compris le problème.
La réponse de Pablo est correcte, mais vous pouvez également faire quelque chose si vous ne voulez pas avoir null
s; Insérez d'abord la même valeur pour PK
et FK
, puis insérez la relation:
insert into TableTest values ('A1', 'A1'); insert into TableTest values ('A3', 'A1');
Et puis DELETE ('A1', 'A1')? Cela ne fait pas partie des données du PO, il ne devrait donc pas être laissé dans le tableau.
@mathguy vous ne pourrez pas supprimer cette ligne, car la seconde en dépend.
@PabloSantaCruz - ce n'est pas ce que je voulais dire. Je crois avoir bien compris le problème de l'OP (contrairement à vous et à Null); J'ai peut-être raison, considérant que le PO a marqué ma réponse comme «correcte». À savoir, la tâche consiste à entrer trois lignes dans le tableau, avec les valeurs (A1, A3), (A3, A2) et (A2, A1). (Pourquoi vous vouliez tous les deux insérer (A3, A1) n'est pas clair pour moi.) Donc, supposons que nous commençons avec (A1, A1) comme béquille, puis nous ajoutons (A2, A1) et (A3, A2). Enfin, il faudrait maintenant mettre à jour la ligne (A1, A1) en la changeant en (A1, A3) - ce qui fonctionnera. Mais (A1, A1) ne doit pas rester là, et ce n'est pas obligatoire.
Il y a des cas, tout comme celui que vous avez publié, où les références circulaires (qui sont absolument parfaites d'ailleurs, pas de problème logique ici) sont en conflit avec le fonctionnement normal des contraintes d'intégrité relationnelle. Ceci est dû au fait que l'intégrité relationnelle a des fonctionnalités "directionnelles" (la clé primaire vient en premier, puis la clé étrangère) même si les dépendances peuvent être circulaires, comme vous l'avez vu.
Il existe plusieurs solutions de contournement. Le plus simple est de rendre la contrainte de clé étrangère différée
. Cela signifie que la contrainte n'est vérifiée que lorsque vous validez
, pas après chaque insertion
individuelle .
Une autre consiste à insérer toutes les valeurs en même temps ( dans la même instruction INSERT
); par exemple:
insert into tabletest(ent, dep) select 'A1', 'A3' from dual union all select 'A3', 'A2' from dual union all select 'A2', 'A1' from dual ;