Restriktionen för den främmande nyckeln tabell2 innebär att varje kund-ID-värde för tabell2 måste visas som ett kund-ID i tabell1. Du får felet eftersom du infogar ett kund-ID i tabell2 som inte visas i tabell1.
Eftersom DBMS genererar kund-ID:n för tabell1 automatiskt, om du infogar en rad måste du få det värdet för att kunna infoga en rad med det kund-ID:t i tabell2.
Jag antar att du säger "Jag har redan etablerat en relation mellan tabell1 och tabell2" för att betyda "Jag har deklarerat en främmande nyckel-begränsning". Och jag antar att du tror att det betyder "efter att jag infogat i tabell1 kommer DBMS att använda det automatiskt genererade nyckelvärdet som främmande nyckelvärde när jag infogar i tabell2". Men det betyder inte det. Det måste du göra själv. Den främmande nyckel-begränsningen betyder bara att DBMS kontrollerar att varje tabell2 kund-ID-värde visas som ett värde för tabell1 kund-ID.
Du kan och måste använda alla tidigare infogade nyckelvärden som motsvarande värde när du infogar i en tabell med en främmande nyckel till den nyckeln.
För att få tillbaka det automatiskt ökade nyckelvärdet som genererats av DBMS, använd 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');
Detta är vad det är till för. Men här är problemen om du inte använder den.
För det första, om du inte är i en serialiserad transaktion måste du använda LAST_INSERT_ID(). Eftersom efter din infogning av tabell1 men innan din infogning av tabell2 kan andra ha lagt till rader och/eller raderat rader inklusive din nya rad och/eller ändrade rader inklusive din nya rad. Så du kan inte lita på att fråga tabell1 efter att dess infogning får ett kund-ID-värde som du vet att du lagt till.
För det andra, anta att du är i en serialiserad transaktion och att du inte använder LAST_INSERT_ID().
If (CustomerName,Address,State) är också en supernyckel av tabell1, dvs dess värden är unika, dvs SQL UNIQUE/KEY/PK deklareras i alla eller några av dess kolumner, då kan du använda den för att fråga efter det associerade nya kund-ID:
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');
Men om (kundnamn, adress, stat) inte är en supernyckel av tabell1 kan du inte göra detta. Eftersom andra rader som är dubbletter för den underraden kan finnas i tabell1. Så du kan få tillbaka flera rader. Så du skulle inte veta vilken som är den nyaste. Istället måste du fråga tabell1 före infogningen, sedan infoga och sedan hitta skillnaden mellan den gamla och nya uppsättningen kund-ID:
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');
Använd bara LAST_INSERT_ID().
PS:Intressant nog, med tanke på tabelldefinitionerna, skulle man helst kunna skriva:
INSERT INTO (
SELECT CustomerName,Address,State,A,B
FROM table1 JOIN table2
USING (CustomerId))
VALUES('value1','value2','value3','valueA','valueB')
eftersom det bara finns ett par nya tabell1- och tabell2-värden som kan resultera. Det finns några juridiska uppdateringar genom vyer i SQL, även om ingen involverar flera tabeller i MySQL för närvarande