Лично, если бы у меня было требование написать процедуру, которая выполняла указанные операции и вернула набор результатов, я написал бы это так:
DELIMITER $$
CREATE DEFINER=`user`@`localhost` PROCEDURE `set_address`
(IN `patient_street` VARCHAR(128)
,IN `patient_city` VARCHAR(45)
,IN `patient_post_code` VARCHAR(45)
,IN `patient_state_or_province` VARCHAR(45)
,IN `patient_country` VARCHAR(45)
)
NOT DETERMINISTIC SQL SECURITY DEFINER
BEGIN
DECLARE li_address_id BIGINT DEFAULT NULL;
-- check for existing row and get address_id
SELECT a.address_id
INTO li_address_id
FROM address a
WHERE a.street = patient_street
AND a.city = patient_city
AND a.post_code = patient_post_code
AND a.country = patient_country
LIMIT 1 ;
-- if we didn't find a matching row
IF li_address_id IS NULL THEN
-- add a row and get the new address_id
INSERT INTO address (street, city, post_code, state_or_province, country) VALUES
(patient_street, patient_city, patient_post_code, patient_state_or_province, patient_country);
SELECT LAST_INSERT_ID() INTO li_address_id;
END IF;
-- return address_id (either found existing row, or newly added row) as a resultset
SELECT li_address_id AS address_id;
END$$
DELIMITER ;
Если строка существует,нам не нужно запускать два SELECT
оператора.Мы можем выполнить проверку для строки AND , чтобы получить address_id с одним SELECT
.
Если мы не получили совпадающую строку, то мы вставляем строку и извлекаемидентификатор автоинкремента.
В любом случае (найденная строка или добавленная строка) вернуть address_id в качестве результирующего набора.Опять же, мы можем сделать это с помощью одного оператора SELECT, а не двух разных операторов.
Для меня более логично ограничить количество мест, которые мы возвращаем наборы результатов, и ограничить количество запросовбаза данных.