У меня есть процедура, в которой я увеличиваю идентификатор вручную, добавляя случайное число к значению идентификатора итеративно. Иногда это приводит к тому, что ID не увеличивается, хотя я могу подтвердить, что оператор (FLOOR(RAND()*(1000-2+1))+2)
всегда возвращает значение в диапазоне 2-1000. И еще следующее простое утверждение:
SET `nextid` = `nextid` + (FLOOR(RAND()*(1000-2+1))+2);
По-прежнему не удается увеличить nextid
время от времени. Если я разделю свое значение (FLOOR(RAND()*(1000-2+1))+2)
на отдельную переменную и добавлю две переменные, этого не произойдет. Ниже приведен минимальный пример теста, который воспроизводит поведение.
DELIMITER $$
CREATE PROCEDURE `test`()
BEGIN
DECLARE `nextid` BIGINT DEFAULT 793991813529600000;
DECLARE `previous` BIGINT DEFAULT 0;
DECLARE `i` BIGINT DEFAULT 0;
DECLARE `random` BIGINT DEFAULT 0;
WHILE `i` < 100000 DO
SET `previous` = `nextid`;
-- Produce a random number between 2 and 1000.
SET `random` = (FLOOR(RAND()*(1000-2+1))+2);
SET `nextid` = `nextid` + `random`;
-- Error if the nextid is no different from the previous ID.
-- This is successful every time.
IF `nextid` = `previous` THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Oh no!', MYSQL_ERRNO = 2000;
END IF;
SET `i` = `i` + 1;
END WHILE;
SET `i` = 0;
WHILE `i` < 100000 DO
SET `previous` = `nextid`;
-- Increment the ID by a random number and do the set in a single statment.
SET `nextid` = `nextid` + (FLOOR(RAND()*(1000-2+1))+2);
-- This fails randomly, but reliably.
IF `nextid` = `previous` THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Whoops!', MYSQL_ERRNO = 2000;
END IF;
SET `i` = `i` + 1;
END WHILE;
END $$
DELIMITER ;
CALL `test`();
DROP PROCEDURE IF EXISTS `test`;
Похоже, это может быть какая-то проблема с кастингом, но я не могу найти ничего, чтобы подтвердить. Итак, мой вопрос, что является причиной этого поведения?
Дополнительные сведения;
mysql --version
mysql Ver 14.14 Distrib 5.7.24, for Linux (x86_64) using EditLine wrapper