Mysql, если не существует, выдает ошибку в хранимой процедуре - PullRequest
0 голосов
/ 21 ноября 2018

У меня есть следующая хранимая процедура в phpmyadmin с использованием mysql:

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 NO SQL SQL SECURITY 
DEFINER 
BEGIN 
IF NOT EXISTS (SELECT a.address_id FROM address as a where a.street = patient_street and a.city = patient_city and a.post_code = patient_post_code and a.country = patient_country) 
THEN 
BEGIN 
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(); 
END; 
ELSE 
BEGIN 
SELECT a.address_id FROM address as a where a.street = patient_street and a.city = patient_city and a.post_code = patient_post_code and a.country = patient_country 
END; 
END IF; 
END;

Однако я получил 2 ошибки в IF NOT EXISTS:

  1. Неопознанное ключевое слово.(около ЕСЛИ НЕ СУЩЕСТВУЕТ )
  2. Неожиданный токен.(около ()

1 Ответ

0 голосов
/ 21 ноября 2018

Лично, если бы у меня было требование написать процедуру, которая выполняла указанные операции и вернула набор результатов, я написал бы это так:

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, а не двух разных операторов.

Для меня более логично ограничить количество мест, которые мы возвращаем наборы результатов, и ограничить количество запросовбаза данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...