phpMyAdmin
 sql >> Datenbank >  >> Database Tools >> phpMyAdmin

So richten Sie eine Beziehung zwischen Tabellen in phpMyAdmin ein

Die Fremdschlüsseleinschränkung von table2 bedeutet, dass jeder Wert von table2 customerId als customerId in table1 erscheinen muss. Sie erhalten den Fehler, weil Sie eine Kunden-ID in Tabelle2 einfügen, die nicht in Tabelle1 erscheint.

Da das DBMS die Kunden-IDs von Tabelle1 durch automatisches Inkrement generiert, müssen Sie beim Einfügen einer Zeile diesen Wert erhalten, um eine Zeile mit dieser Kunden-ID in Tabelle2 einzufügen.

Ich denke, Sie sagen "Ich habe bereits eine Beziehung zwischen Tabelle1 und Tabelle2 hergestellt", um zu bedeuten, dass "Ich eine Fremdschlüsseleinschränkung deklariert habe". Und ich denke, Sie denken, das bedeutet "nach dem Einfügen in Tabelle1 verwendet das DBMS den automatisch generierten Schlüsselwert als Fremdschlüsselwert, wenn ich in Tabelle2 einfüge". Aber das bedeutet es nicht. Das musst du selbst machen. Die Fremdschlüsseleinschränkung bedeutet lediglich, dass das DBMS prüft, ob jeder Kunden-ID-Wert von Tabelle 2 als Kunden-ID-Wert von Tabelle 1 erscheint.

Sie können und müssen jeden zuvor eingefügten Schlüsselwert als entsprechenden Wert verwenden, wenn Sie in eine Tabelle mit einem Fremdschlüssel zu diesem Schlüssel einfügen.

Um den vom DBMS generierten automatisch inkrementierten Schlüsselwert zurückzuerhalten, verwenden Sie LAST_INSERT_ID() :

INSERT INTO table1 (CustomerName,Address,State)
VALUES('value1','value2','value3');
INSERT INTO table2 (customerId,product,cost)
VALUES(LAST_INSERT_ID(),'valueA','valueB');

Dafür ist es da. Aber hier sind die Probleme, wenn Sie es nicht verwenden.

Erstens, wenn Sie sich nicht in einer serialisierten Transaktion befinden, müssen Sie LAST_INSERT_ID() verwenden. Denn nach Ihrer Einfügung von Tabelle1, aber vor Ihrer Einfügung von Tabelle2 könnten andere Zeilen hinzugefügt und/oder Zeilen gelöscht haben, einschließlich Ihrer neuen Zeile, und/oder Zeilen geändert haben, einschließlich Ihrer neuen Zeile. Sie können sich also nicht darauf verlassen, dass die Abfrage von table1 nach der Einfügung einen Kunden-ID-Wert erhält, von dem Sie wissen, dass Sie ihn hinzugefügt haben.

Nehmen wir zweitens an, Sie befinden sich in einer serialisierten Transaktion und verwenden LAST_INSERT_ID() nicht.

Wenn (Kundenname, Adresse, Staat) auch ein Superschlüssel ist von Tabelle1, dh ihre Werte sind eindeutig, dh SQL UNIQUE/KEY/PK ist für alle oder einige ihrer Spalten deklariert, dann können Sie damit nach der zugehörigen neuen Kunden-ID fragen:

set @customerId = (
    SELECT customerId
    FROM table1
    WHERE CustomerName = 'value1'
    AND Address = 'value2'
    AND State = 'value3');
INSERT INTO table2 (customerId,product,cost)
VALUES(@customerId,'valueA','valueB');

Aber wenn (Kundenname, Adresse, Staat) kein Superschlüssel ist von table1 dann können Sie dies nicht tun. Weil andere Zeilen, die Duplikate für diese Unterzeile sind, in Tabelle1 enthalten sein könnten. So könnten Sie mehrere Zeilen zurückbekommen. Sie würden also nicht wissen, welches das neueste ist. Stattdessen müssen Sie table1 vor dem Einfügen abfragen, dann einfügen und dann den Unterschied zwischen dem alten und dem neuen Satz von Kunden-IDs finden:

CREATE TEMPORARY TABLE table1old (
    customerId (int) PRIMARY KEY
    );
INSERT INTO table1old
SELECT customerId FROM table1;

INSERT INTO table1 (CustomerName,Address,State)
VALUES('value1','value2','value3');

set @customerId = (
    SELECT customerId
    FROM table1
    WHERE CustomerName NOT IN table1old);
INSERT INTO table2 (customerId,product,cost)
VALUES(@customerId,'valueA','valueB');

Verwenden Sie einfach LAST_INSERT_ID().

PS:Interessanterweise könnte man angesichts der Tabellendefinitionen idealerweise schreiben:

INSERT INTO (
    SELECT CustomerName,Address,State,A,B
    FROM table1 JOIN table2
    USING (CustomerId))
VALUES('value1','value2','value3','valueA','valueB')

da es nur ein Paar neuer table1- und table2-Werte gibt, die sich ergeben können. Es gibt einige legale Aktualisierungen durch Ansichten in SQL, obwohl derzeit keine mehrere Tabellen in MySQL betrifft