Tabel2-fremmednøglebegrænsningen betyder, at enhver tabel2 customerId-værdi skal vises som et customerId i tabel1. Du får fejlen, fordi du indsætter et kunde-id i tabel2, der ikke vises i tabel1.
Da DBMS genererer tabel1 kunde-id'er ved automatisk stigning, hvis du indsætter en række, skal du få den værdi for at indsætte en række ved hjælp af dette kunde-id i tabel2.
Jeg gætter på, at du siger "Jeg har allerede etableret et forhold mellem tabel1 og tabel2" for at betyde "Jeg har erklæret en fremmednøglebegrænsning". Og jeg gætter på, at du tror, det betyder "efter at jeg indsætter i tabel1, vil DBMS bruge den autogenererede nøgleværdi som fremmednøgleværdien, når jeg indsætter i tabel2". Men det betyder det ikke. Det skal du selv gøre. Begrænsningen for fremmednøgle betyder blot, at DBMS kontrollerer, at hver tabel2 kunde-id-værdi vises som en tabel1-kunde-id-værdi.
Du kan og skal bruge enhver tidligere indsat nøgleværdi som den tilsvarende værdi, når du indsætter i en tabel med en fremmednøgle til denne nøgle.
Brug for at få den automatisk øgede nøgleværdi, der genereres af DBMS'et, tilbage. 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');
Det er hvad det er til. Men her er problemerne, hvis du ikke bruger det.
For det første, hvis du ikke er i en serialiseret transaktion, skal du bruge LAST_INSERT_ID(). Fordi efter din tabel1-indsættelse, men før din tabel2-indsættelse, kunne andre have tilføjet rækker og/eller slettet rækker inklusive din nye række og/eller ændret rækker inklusive din nye række. Så du kan ikke stole på, at forespørgsler i tabel1, efter at den er blevet indsat, får en kunde-id-værdi, som du ved, du har tilføjet.
For det andet, antag, at du er i en serialiseret transaktion, og at du ikke bruger LAST_INSERT_ID().
If (CustomerName,Address,State) er også en supernøgle af tabel1, dvs. dens værdier er unikke, dvs. SQL UNIQUE/KEY/PK er erklæret på alle eller nogle af dens kolonner, så kan du bruge den til at forespørge efter det tilknyttede nye kunde-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 hvis (kundenavn, adresse, stat) ikke er en supernøgle af tabel1, så kan du ikke gøre dette. Fordi andre rækker, der er dubletter for den underrække, kunne være i tabel1. Så du kan få flere rækker tilbage. Så du ville ikke vide, hvilken der er den nyeste. I stedet skal du forespørge tabel1 før indsættelsen, derefter indsætte og derefter finde forskellen mellem det gamle og nye sæt kunde-id'er:
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');
Brug bare LAST_INSERT_ID().
PS:Interessant nok, givet tabeldefinitionerne, kunne man ideelt set skrive:
INSERT INTO (
SELECT CustomerName,Address,State,A,B
FROM table1 JOIN table2
USING (CustomerId))
VALUES('value1','value2','value3','valueA','valueB')
da der kun er et par nye tabel1- og tabel2-værdier, der kan resultere. Der er nogle juridiske opdateringer gennem visninger i SQL, selvom ingen involverer flere tabeller i MySQL i øjeblikket