Я пытаюсь создать хранимую процедуру, которая будет вставлять запись в базу данных и возвращать вновь созданный идентификатор. Если запись с таким именем уже существует, она должна вернуть идентификатор этой записи. Это то, что у меня есть до сих пор, он работает для вновь вставленных записей, но ничего не возвращает, если запись уже существует.

CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_tag`(IN `tag_name_in` VARCHAR(255), OUT `tag_id_out` INT) NOT DETERMINISTIC NO SQL SQL SECURITY DEFINER 
BEGIN 
    INSERT INTO tag (name) VALUES (tag_name_in); 
    IF ROW_COUNT() = 1 THEN 
        SET tag_id_out = LAST_INSERT_ID(); 
    ELSE 
        SELECT id INTO tag_id_out FROM tag WHERE name=tag_name_in; 
    END IF; 
END
0
Asis 8 Июн 2021 в 16:12

2 ответа

Лучший ответ

Я вообще не вижу смысла использовать LAST_INSERT_ID().

CREATE 
DEFINER=`root`@`localhost` 
PROCEDURE `insert_tag`(IN `tag_name_in` VARCHAR(255), OUT `tag_id_out` INT) 
NOT DETERMINISTIC 
NO SQL 
SQL SECURITY DEFINER 
BEGIN 
    INSERT IGNORE INTO tag (name) VALUES (tag_name_in); 
    SELECT id INTO tag_id_out FROM tag WHERE name=tag_name_in; 
END

Из-за текста вопроса tag (name) определяется как УНИКАЛЬНЫЙ (возможно, даже ПЕРВИЧНЫЙ КЛЮЧ).

1
Akina 8 Июн 2021 в 13:19

Вместо этого ваша инструкция else должна быть такой: SET tag_id_out = SELECT id FROM tag WHERE name=tag_name_in;

В целом это будет выглядеть так:


CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_tag`(IN `tag_name_in` VARCHAR(255), OUT `tag_id_out` INT) NOT DETERMINISTIC NO SQL SQL SECURITY DEFINER 
BEGIN 
    INSERT INTO tag (name) VALUES (tag_name_in); 
    IF ROW_COUNT() = 1 THEN 
        SET tag_id_out = LAST_INSERT_ID(); 
    ELSE 
        SET tag_id_out = SELECT id FROM tag WHERE name=tag_name_in; 
    END IF; 
END

0
LeventHAN 8 Июн 2021 в 13:16