Я потратил на это 24 часа, и мне нужно использовать имеющиеся знания для ускорения.
У меня есть эта функция mysql:
DELIMITER $$
USE `db`$$
DROP FUNCTION IF EXISTS `insertindb`$$
CREATE DEFINER=`root`@`localhost` FUNCTION `insertindb`(itemtype VARCHAR(10), dname VARCHAR (50), id INTEGER, fname VARCHAR(50), lname VARCHAR(50)) RETURNS INT(11)
DETERMINISTIC
BEGIN
DECLARE ret INT;
DECLARE ret2 INT;
IF itemtype = 'state' THEN
INSERT IGNORE INTO state (`name`) VALUES (dname);
SELECT LAST_INSERT_ID() INTO ret;
IF ret = 0 THEN
SELECT `id` INTO ret2 FROM state WHERE `name` LIKE dname;
SET ret = ret2;
END IF;
END IF;
RETURN ret;
END$$
DELIMITER ;
Цель? Когда состояние уже существует в таблице state
, оно должно возвращать столбец id (который является ключом автоинкремента). Если он не существует, он должен вставить его и вернуть новый (автоматически) назначенный идентификатор.
Функция работает, но делать 2 вещи я не хочу:
1) когда запись уже существует, она возвращает ноль, а не идентификатор существующей записи. Мой код предназначен для решения этой проблемы, но он не работает. Пожалуйста, обратите внимание, что я определил индекс в таблице, чтобы обеспечить уникальность state.name в таблице, чтобы INSERT IGNORE работал
2) LAST_INSERT_ID() продолжает увеличиваться, даже если запись существует и, следовательно, ничего не было вставлено. Так, например, если в таблице состояний есть только одна запись для начала (скажем, id ==> 1, имя ==> «Состояние A»), если я вызову функцию 2 раза, чтобы попытаться повторно вставить «Состояние A» (что не будет вставляться, как указано в пункте 1 выше), а затем снова вызовите его, чтобы вставить «Состояние B», теперь таблица будет иметь вторую запись с идентификатором ==> 4, имя ==> «Состояние B», пропуская значения идентификатора 2 и 3 , Есть ли способ заставить LAST_INSERT_ID работать по-другому?
Мой код сейчас
BEGIN
DECLARE ret,ret2 INT;
IF itemtype = 'state' THEN
SELECT `id` INTO ret FROM state WHERE `name` LIKE dname;
#insert into debug (dump1,dump2) values ('ret will be',ret);
IF ret IS NULL OR ret = '' THEN
INSERT IGNORE INTO state (`name`) VALUES (dname);
SELECT LAST_INSERT_ID() INTO ret2;
#SELECT `id` INTO ret FROM state WHERE `name` LIKE dname;
RETURN ret2;
ELSE
RETURN ret;
END IF;
END IF;
END$$