it-swarm.com.de

Wie füge ich einer bereits vorhandenen Tabelle eine Spalte mit einer Fremdschlüsseleinschränkung hinzu?

Ich habe die folgenden Tabellen,

CREATE TABLE users (id int PRIMARY KEY);

-- already exists with data
CREATE TABLE message ();

Wie ändere ich die Tabelle messages so, dass

  1. eine neue Spalte mit dem Namen sender wird hinzugefügt
  2. dabei ist sender ein Fremdschlüssel, der auf die Tabelle users verweist

Das hat nicht funktioniert

# ALTER TABLE message ADD FOREIGN KEY (sender) REFERENCES users;
ERROR:  column "sender" referenced in foreign key constraint does not exist

Erstellt diese Anweisung nicht auch die Spalte?

11
Hassan Baig

Was relativ einfach ist - Sie müssen nur einen weiteren Schritt hinzufügen.

Die Spalte FOREIGN KEY muss vorhanden sein , um daraus ein FK zu machen. Ich habe folgendes gemacht (von hier und Dokumentation ):

CREATE TABLE x(t INT PRIMARY KEY);

CREATE TABLE y(s INT);

ALTER TABLE y ADD COLUMN z INT;    

ALTER TABLE y
  ADD CONSTRAINT y_x_fkey FOREIGN KEY (z)
      REFERENCES x (t)
      ON UPDATE CASCADE ON DELETE CASCADE;

Ein paar Punkte zu beachten:

[~ # ~] Geben Sie Ihren Fremdschlüsseln immer [~ # ~] aussagekräftige Namen. Es ist nicht sehr hilfreich zu erfahren, dass der Schlüssel "SYS_C00308108" verletzt wird. Siehe die Geige hier für das Verhalten von Oracle unter diesen Umständen variiert der Schlüsselname von Geige zu Geige, ist jedoch eine beliebige Zeichenfolge, die mit SYS _... beginnt.)

In Anbetracht Ihrer Aussage:

ALTER TABLE message ADD FOREIGN KEY (sender) REFERENCES users;

Es wäre ein "Nice-to-Have", wenn das RDBMS automatisch das gewünschte Feld mit dem Datentyp erstellen könnte, der mit dem referenzierten Feld übereinstimmt. Ich würde nur sagen, dass das Ändern von DDL eine selten verwendete Operation ist (oder zumindest sein sollte) und nicht etwas, das Sie regelmäßig durchführen möchten. Es besteht auch die Gefahr, dass eine bereits ziemlich umfangreiche Dokumentation ergänzt wird.

Zumindest versucht PostgreSQL, etwas Vernünftiges zu tun - es verkettet den Tabellennamen, den Feldnamen FOREIGN KEY Und _fkey Und fügt sogar DETAIL: Key (sender_id)=(56) is not present in table "user_". hinzu, um einem Menschen etwas zu geben, das für einen Menschen sinnvoll sein könnte Sein - siehe Geige hier .

18
Vérace

Ich bin mir nicht sicher, warum Ihnen alle sagen, dass Sie dies in zwei Schritten tun müssen. Tatsächlich nicht . Sie haben versucht, ein FOREIGN KEY Hinzufügen, das davon ausgeht, dass die Spalte vorhanden ist, und diesen Fehler auslöst, wenn die Spalte nicht vorhanden ist. Wenn Sie das COLUMN hinzufügen, können Sie es bei der Erstellung mit REFERENCES explizit zu einem FOREIGN KEY Machen.

ALTER TABLE message
  ADD COLUMN sender INT
  REFERENCES users;  -- or REFERENCES table(unique_column)

Wird gut funktionieren. Sie können siehe die Syntax von ALTER TABLE Hier

ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
action [, ... ]

Mit "action" as,

ADD [ COLUMN ] [ IF NOT EXISTS ] column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]

Diese Beispiele finden Sie sogar in den Dokumenten.

ALTER TABLE distributors
  ADD CONSTRAINT distfk
  FOREIGN KEY (address)
  REFERENCES addresses (address);

ALTER TABLE distributors
  ADD CONSTRAINT distfk
  FOREIGN KEY (address)
  REFERENCES addresses (address)
  NOT VALID;

All dies wird jedoch nicht benötigt, da wir uns auf die automatische Benennung und die Primärschlüsselauflösung verlassen können (wenn nur der Tabellenname angegeben wird, verweisen Sie auf den Primärschlüssel).

8
Evan Carroll

CASE1: Wenn Sie beim Erstellen einer neuen Tabelle einen Fremdschlüssel erstellen müssen

CREATE TABLE table1(
id SERIAL PRIMARY KEY,
column1 varchar(n) NOT NULL,
table2_id SMALLINT REFERENCES table2(id)
); 

Mit den obigen Befehlen wird eine Tabelle mit dem Namen 'table1' und drei Spalten mit den Namen 'id' (Primärschlüssel), 'column1', 'table2_id' (Fremdschlüssel von Tabelle1, der auf die ID-Spalte von Tabelle2 verweist) erstellt.

DATATYPE 'serial' erstellt die Spalte, die diesen Datentyp als automatisch generierte Spalte verwendet. Wenn Sie Werte in die Tabelle einfügen, müssen Sie diese Spalte überhaupt nicht erwähnen, oder Sie können 'default' ohne Anführungszeichen an der Wertstelle angeben.

Dem Index der Tabelle wird immer eine Primärschlüsselspalte mit dem Wert 'tablename_pkey' hinzugefügt.

Wenn zum Zeitpunkt der Tabellenerstellung ein Fremdschlüssel hinzugefügt wird, wird ein CONSTRAINT mit dem Muster '(vorhandener_Tabellenname) _ (Fremdschlüssel_ID_Name) _fkey' hinzugefügt.

Wenn wir einen Fremdschlüssel hinzufügen, müssen wir das Schlüsselwort 'REFERENCES' neben dem Spaltennamen eingeben, da wir den Postgres mitteilen möchten, dass diese Spalte auf eine Tabelle verweist, und dann neben den Verweisen die Tabelle als Referenz angeben und in Klammern die Spaltenname der referenzierten Tabelle, normalerweise werden Fremdschlüssel als Primärschlüsselspalten angegeben.

FALL 2: Wenn Sie einen Fremdschlüssel für eine vorhandene Tabelle in einer vorhandenen Spalte wünschen

ALTER TABLE table1
ADD CONSTRAINT table1_table2_id_id_fkey
FOREIGN KEY (table2_id) REFERENCES table2(id);

HINWEIS: Klammern '()' nach FOREIGN KEY und REFERENCES tabel2 sind obligatorisch, da sonst Postgres einen Fehler auslösen.

0
Ashok Allu

Ich kenne das Problem. Die Spaltennamen sind unterschiedlich. Möglicherweise wird in einer Spalte nach Ihrem Spaltennamen ein Leerzeichen hinzugefügt. Stellen Sie daher sicher, dass Ihre Spaltennamen genau gleich benannt wurden.

0
XIN WANG