简体   繁体   English

MySQL如果不存在,则会在存储过程中给我一个错误

[英]Mysql if not exists gives my an error in a stored-procedure

I have the following stored procedure in phpmyadmin using mysql : 我在使用mysql phpmyadmin具有以下存储过程:

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;

However, I got 2 errors in IF NOT EXISTS : 但是, IF NOT EXISTS ,我会遇到2个错误:

  1. Unrecognized keyword. 无法识别的关键字。 (near IF NOT EXISTS ) 如果不存在附近)
  2. Unexpected token. 意外的标记。 (near() (近()

Personally, if I had a requirement to write a procedure that performed the specified operations, and returned a resultset, I'd write it like this: 就个人而言,如果我需要编写一个执行指定操作并返回结果集的过程,则可以这样编写:

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 ;

If a row exists, we don't need to run two SELECT statements. 如果存在一行,则无需运行两个SELECT语句。 We can do the check for the row AND get the address_id with a single SELECT . 我们可以做该行的检查, 得到一个单一的ADDRESS_ID SELECT

If we didn't get a matching row, then we insert a row, and retrieve the auto-increment id. 如果没有得到匹配的行,则插入一行,并获取自动增量ID。

In either case (found row, or added row), return the address_id as a resultset. 无论哪种情况(找到的行或添加的行),都将address_id作为结果集返回。 Again, we can do that with a single SELECT statement, rather than two different statements. 同样,我们可以使用单个SELECT语句而不是两个不同的语句来完成此操作。

To me, it makes more sense to limit the number of places we are returning resultsets, and limit the number of times we query the database. 对我来说,限制返回结果集的位置数和限制查询数据库的次数更有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM