it-swarm.com.de

Was ist die Ursache von FEHLER: Es gibt keine eindeutige Einschränkung, die mit den angegebenen Schlüsseln für die referenzierte Tabelle übereinstimmt?

Die folgende Beispieltabellenstruktur gibt einen FEHLER an: Es gibt keine eindeutige Einschränkung für bestimmte Schlüssel für die referenzierte Tabelle, und nachdem ich sie für eine Weile angestarrt habe, kann ich nicht herausfinden, warum dieser Fehler in dieser Situation auftritt.

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;

Das Ausführen des obigen Codes ergibt den folgenden Fehler, der für mich keinen Sinn ergibt. Kann mir jemand erklären, warum dieser Fehler auftritt. Ich benutze 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
113
ams

Dies liegt daran, dass die Spalte name in der Tabelle bar nicht die Bedingung UNIQUE enthält.

Stellen Sie sich vor, Sie haben 2 Zeilen in der Tabelle bar, die den Namen 'ams' Enthalten, und Sie fügen eine Zeile in baz mit 'ams' In bar_fk, auf welche Zeile in bar wird verwiesen, da zwei Zeilen übereinstimmen?

122
Diego

In postgresql müssen alle Fremdschlüssel auf einen eindeutigen Schlüssel in der übergeordneten Tabelle verweisen, sodass Sie in Ihrer bar -Tabelle eine unique (name) Index.

Siehe auch http://www.postgresql.org/docs/9.1/static/ddl-constraints.html#DDL-CONSTRAINTS-FK und speziell:

Schließlich sollten wir erwähnen, dass ein Fremdschlüssel auf Spalten verweisen muss, die entweder ein Primärschlüssel sind oder eine eindeutige Einschränkung bilden.

Betonung meiner.

64

wenn Sie UNIQUE als Einschränkung auf Tabellenebene ausführen, wie Sie es getan haben, ist Ihre Definition ein bisschen wie ein zusammengesetzter Primärschlüssel, siehe ddl-Einschränkungen , hier ist ein Auszug

"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."

dies bedeutet, dass jedes Feld möglicherweise einen nicht eindeutigen Wert haben kann, vorausgesetzt, die -Kombination ist eindeutig und entspricht nicht Ihrer Fremdschlüsseleinschränkung.

höchstwahrscheinlich soll die Einschränkung auf Spaltenebene liegen. Definieren Sie sie lieber als Einschränkungen auf Tabellenebene, 'hängen' Sie UNIQUE an das Ende der Spaltendefinition an, z. B. name VARCHAR(60) NOT NULL UNIQUE, oder geben Sie für jedes Feld individuelle Einschränkungen auf Tabellenebene an.

5
T I

Sie sollten eine Namensspalte als eindeutige Einschränkung haben. Hier sind 3 Codezeilen, um Ihre Probleme zu ändern

  1. Ermitteln Sie zuerst die Primärschlüsseleinschränkungen, indem Sie diesen Code eingeben

    \d table_name
    

    sie werden unten so angezeigt "some_constraint" PRIMARY KEY, btree (column)

  2. Löschen Sie die Einschränkung:

    ALTER TABLE table_name DROP CONSTRAINT some_constraint
    
  3. Fügen Sie eine neue Primärschlüsselspalte mit der vorhandenen hinzu:

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

Das ist alles.

4
Hari Bharathi