#mysql #database-design
#mysql #база данных-дизайн
Вопрос:
Здравствуйте, я работаю над назначением базы данных, и я застрял на том, как выполнить эту единственную хранимую процедуру. Хотя это работает, вроде как…
РАЗДЕЛИТЕЛЬ //
CREATE PROCEDURE AddANewCustomer(IN firstName char(20), IN lastName char(20), IN companyName char(45), IN streetAddress char(60), IN city char(30), IN province char(45), IN postalCode char(6), IN phoneNumber int(10))
BEGIN
DECLARE PersonID INT;
SELECT idPerson FROM Persons WHERE Persons.firstName = firstName AND Persons.lastName = lastName INTO PersonID;
IF PersonID IS NULL THEN
INSERT INTO Persons(firstName, lastName, streetAddress, city, province, postalCode, phoneNumber) VALUES (firstName, lastName, streetAddress, City, Province, postalCode, phoneNumber);
SELECT idPerson FROM Persons WHERE firstName = firstName AND lastName = lastName INTO PersonID;
END IF;
INSERT INTO Customers(idCustomer, companyName) VALUES (Last_Insert_ID(), companyName);
END //
DELIMITER ;
В основном я работаю с супер / подтипами. Я хочу получить информацию от пользователя, а затем обновить свою родительскую таблицу (Persons) и передать оставшуюся информацию в мою дочернюю таблицу (Customers). idPerson — это автоматически увеличивающийся PK для таблицы Persons, и я хочу использовать его как PK / FK для идентификатора таблицы Customers, idCustomer.
Если я запущу процедуру один раз, она выдаст ошибку «Результат состоит из более чем одной строки», и будет обновлена только родительская таблица… Но если я запущу ее снова, она обновит дочернюю таблицу должным образом. Что заставляет меня думать, что параметр Last_Insert_ID() в первый раз равен нулю, а идентификатор обновляется только после завершения процедуры.
Я всю ночь искал исправление, и теперь я абсолютно озадачен тем, как это решить.
Ответ №1:
Ой.
В основном я работаю с супер / подтипами.
Я так не думаю, но я могу ошибаться. Клиент обычно описывает отношения между двумя сторонами, одна из которых является покупателем, а другая — продавцом.
Если я запущу процедуру один раз, она выдаст ошибку «Результат состоит из более чем одной строки»
Как вы думаете, что это значит? Возвращает ли этот запрос какие-либо строки?
SELECT lastname, firstname, count(*)
FROM Persons
GROUP BY lastname, firstname
HAVING count(*) > 1;
Вы проверяете наличие нулевого идентификационного номера,
IF PersonID IS NULL THEN
но вы игнорируете возможность того, что ваш оператор SELECT может возвращать 2, или 3, или 42 разных идентификационных номера, все для людей с одинаковыми именем и фамилией. Разумно ли это? Другими словами, есть ли у вас УНИКАЛЬНОЕ ограничение на {firstname, lastname}?
Если PersonID равен нулю, вы вставляете строку в Persons, которая задает значение, которое может вернуть LAST_INSERT_ID(). Но ваша вторая ВСТАВКА пытается использовать LAST_INSERT_ID() независимо от того, была ли строка ранее вставлена в Persons.
Наконец, у вас есть две немного отличающиеся версии
SELECT idPerson
FROM Persons
WHERE Persons.firstName = firstName
AND Persons.lastName = lastName
INTO PersonID;
Я почти уверен, что вам нужна максимум одна.