Ограничението за външен ключ table2 означава, че всяка стойност table2 customerId трябва да се появи като customerId в table1. Получавате грешката, защото вмъквате клиентски идентификатор в таблица 2, който не се показва в таблица 1.
Тъй като СУБД генерира table1 customerID чрез автоматично увеличение, ако вмъкнете ред, трябва да получите тази стойност, за да вмъкнете ред, използващ този customerID в таблица 2.
Предполагам, че казвате "Вече установих връзка между таблица1 и таблица2", което означава "Аз декларирах ограничение за външен ключ". И предполагам, че мислите, че това означава "след като вмъкна в таблица 1, СУБД ще използва автоматично генерираната стойност на ключа като стойност на външен ключ, когато вмъкна в таблица 2". Но това не означава това. Вие трябва да направите това сами. Ограничението за външния ключ просто означава, че СУБД проверява дали всяка стойност на table2 customerId се появява като стойност table1 customerId.
Можете и трябва да използвате всяка по-рано вмъкната стойност на ключ като съответна стойност, когато вмъквате в таблица с външен ключ към този ключ.
За да върнете автоматично увеличената стойност на ключа, генерирана от СУБД, използвайте 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');
Ето за какво е. Но ето проблемите, ако не го използвате.
Първо, ако не сте в сериализирана транзакция, тогава трябва да използвате LAST_INSERT_ID(). Защото след вмъкването на таблица 1, но преди вмъкването на таблица 2, други биха могли да добавят редове и/или да изтриват редове, включително новия ви ред, и/или да променят редове, включително новия ви ред. Така че не можете да разчитате на заявка table1 след нейното вмъкване да получите някаква стойност на customerId, която знаете, че сте добавили.
Второ, да предположим, че сте в сериализирана транзакция и не използвате LAST_INSERT_ID().
Ако (CustomerName,Address,State) е също суперключ на таблица1, т.е. нейните стойности са уникални, т.е. SQL UNIQUE/KEY/PK е деклариран във всички или някои от колоните му, след което можете да го използвате за заявка за асоциирания нов customerId:
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');
Но ако (CustomerName,Address,State) не е суперключ на table1, тогава не можете да направите това. Тъй като други редове, които са дублирани за тази подреда, могат да бъдат в таблица 1. Така че можете да върнете няколко реда назад. Така че няма да знаете коя е най-новата. Вместо това трябва да потърсите table1 преди вмъкването, след това да вмъкнете и след това да намерите разликата между стария и новия набор от customerIds:
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');
Просто използвайте LAST_INSERT_ID().
PS:Интересното е, че като се имат предвид дефинициите на таблицата, в идеалния случай може да се напише:
INSERT INTO (
SELECT CustomerName,Address,State,A,B
FROM table1 JOIN table2
USING (CustomerId))
VALUES('value1','value2','value3','valueA','valueB')
тъй като има само една двойка нови стойности table1 и table2, които могат да се получат. Има някои правни актуализации чрез изгледи в SQL, въпреки че в момента нито една не включва множество таблици в MySQL