Qu’est-ce qui cause ERROR: il n’y a pas de contrainte unique correspondant aux clés données pour la table référencée?

La structure du tableau ci-dessous donne une ERREUR: il n’y a pas de contrainte unique correspondant aux clés données pour la table référencée, et après l’avoir regardée pendant un moment, je n’arrive pas à comprendre pourquoi cette erreur survient dans cette situation.

BEGIN; CREATE TABLE foo ( name VARCHAR(256) PRIMARY KEY ); CREATE TABLE bar( pkey SERIAL PRIMARY KEY, foo_fk VARCHAR(256) NOT NULL REFERENCES foo(name), name VARCHAR(256) NOT NULL, UNIQUE (foo_fk,name) ); CREATE TABLE baz( pkey SERIAL PRIMARY KEY, bar_fk VARCHAR(256) NOT NULL REFERENCES bar(name), name VARCHAR(256) ); COMMIT; 

L’exécution du code ci-dessus génère l’erreur suivante, ce qui n’a aucun sens pour moi. Quelqu’un peut-il expliquer pourquoi cette erreur se produit? J’utilise postgres 9.1

 NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo" NOTICE: CREATE TABLE will create implicit sequence "bar_pkey_seq" for serial column "bar.pkey" NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "bar_pkey" for table "bar" NOTICE: CREATE TABLE / UNIQUE will create implicit index "bar_foo_fk_name_key" for table "bar" NOTICE: CREATE TABLE will create implicit sequence "baz_pkey_seq" for serial column "baz.pkey" NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "baz_pkey" for table "baz" ERROR: there is no unique constraint matching given keys for referenced table "bar" ********** Error ********** ERROR: there is no unique constraint matching given keys for referenced table "bar" SQL state: 42830 

C’est parce que la colonne name de la table à bar n’a pas la contrainte UNIQUE .

Imaginez donc que vous ayez 2 lignes sur la bar des bar contenant le nom 'ams' et que vous insérez une ligne sur baz avec 'ams' sur bar_fk , quelle ligne sur la bar ferait-elle référence car il y a deux lignes correspondantes?

Dans postgresql, toutes les clés étrangères doivent faire référence à une clé unique dans la table parent. Dans votre table à bar , vous devez donc avoir un index unique (name) .

Voir aussi http://www.postgresql.org/docs/9.1/static/ddl-constraints.html#DDL-CONSTRAINTS-FK et plus précisément:

Enfin, il convient de mentionner qu’une clé étrangère doit faire référence à des colonnes qui sont soit une clé primaire, soit une contrainte unique.

Accent mis à moi.

quand vous faites UNIQUE comme contrainte de niveau table comme vous l’avez fait alors ce que votre définition est un peu comme une clé primaire composite voir contraintes ddl , en voici un extrait

 "This specifies that the *combination* of values in the indicated columns is unique across the whole table, though any one of the columns need not be (and ordinarily isn't) unique." 

Cela signifie que les deux champs peuvent avoir une valeur non unique à condition que la combinaison soit unique et que cela ne corresponde pas à votre contrainte de clé étrangère.

très probablement vous voulez que la contrainte soit au niveau de la colonne. alors plutôt que de les définir en tant que contraintes au niveau de la table, ajoutez « UNIQUE » à la fin de la définition de colonne comme le name VARCHAR(60) NOT NULL UNIQUE ou spécifiez des contraintes de niveau table individuelles pour chaque champ.

Vous devez avoir la colonne de nom comme contrainte unique. Voici 3 lignes de code pour changer vos problèmes

1.Tout d’abord, trouvez les principales contraintes en tapant ce code

\ d nom_table

vous êtes montré comme ceci en bas “some_constraint” PRIMARY KEY, btree (colonne)

2.drop la contrainte:

ALTER TABLE nom_table DROP CONSTRAINT some_constraint

3.Ajouter une nouvelle colonne de clé primaire avec une existante:

ALTER TABLE nom_table ADD CONSTRAINT some_constraint PRIMARY KEY (COLUMN_NAME1, COLUMN_NAME2);

C’est tout.