Я пишу процедуру, которая извлекает данные для сопоставления поля и вставки/обновления в другой таблице.Курсор процедуры MySQL останавливается после первой итерации
Моя проблема заключается в том, что мой курсор остановится после первой итерации без каких-либо ошибок, если функция сопоставления не найдет совпадений.
Вот моя функция:
BEGIN
DECLARE mapped_name VARCHAR(255);
SELECT mapped_field INTO mapped_name
FROM mapping_civility
WHERE original_field = nameVar
LIMIT 1;
IF mapped_name IS NULL THEN
RETURN 'INDEFINI';
ELSE
RETURN mapped_name;
END IF;
END
Протестировав его, я обнаружил, что, если есть соответствующее поле в моей таблице отображения она работает, но если SELECT, возвращает значение NULL, поскольку не отображается поле не найден , он остановит курсор на первой итерации.
Затем я попробовал его в другой базе данных, на другом сервере, и все прошло нормально, так что, возможно, проблема конфигурации? Оба имеют набор символов «latin1 - cp1252 западноевропейская» сортировка «latin1_swedish_ci».
Вот моя процедура код:
BLOCK1: BEGIN
DECLARE no_more_rows1 INT;
DECLARE my_name VARCHAR(255);
DECLARE civility VARCHAR(255);
DECLARE curseur1 CURSOR FOR
SELECT `name`
FROM source;
DECLARE CONTINUE handler FOR NOT FOUND SET no_more_rows1 = TRUE;
OPEN curseur1;
LOOP1: LOOP
FETCH curseur1 INTO my_name;
IF no_more_rows1 THEN
CLOSE curseur1;
LEAVE LOOP1;
END IF;
SET civility = get_civility(my_name);
INSERT INTO log (id, message, date) VALUES (NULL, CONCAT(my_name, ' : ', civility), NOW());
END LOOP LOOP1;
END BLOCK1;
Эта процедура вставит правильно, если имя хорошо отображается, но он остановится после первой строки, если имя не отображается.
Вы можете проверить это с помощью следующих таблиц
-- ----------------------------
-- Table structure for `source`
-- ----------------------------
DROP TABLE IF EXISTS `source`;
CREATE TABLE `source` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;
-- ----------------------------
-- Records of source
-- ----------------------------
INSERT INTO `source` VALUES ('1', 'Pierre');
INSERT INTO `source` VALUES ('2', 'David');
INSERT INTO `source` VALUES ('3', 'Kevin');
INSERT INTO `source` VALUES ('4', 'Pierre');
INSERT INTO `source` VALUES ('5', 'Donald Pierre');
-- ----------------------------
-- Table structure for `log`
-- ----------------------------
DROP TABLE IF EXISTS `log`;
CREATE TABLE `log` (
`id` int(5) NOT NULL AUTO_INCREMENT COMMENT 'id',
`message` text COMMENT 'message',
`date` varchar(64) DEFAULT NULL COMMENT 'date',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for `mapping_civility`
-- ----------------------------
DROP TABLE IF EXISTS `mapping_civility`;
CREATE TABLE `mapping_civility` (
`id` int(5) NOT NULL AUTO_INCREMENT COMMENT 'id',
`original_field` varchar(255) DEFAULT NULL COMMENT 'original_field',
`mapped_field` varchar(255) DEFAULT NULL COMMENT 'mapped_field',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of mapping_civility
-- ----------------------------
INSERT INTO `mapping_civility` VALUES ('1', 'kevin', 'H');
INSERT INTO `mapping_civility` VALUES ('2', 'pierre', 'H');
INSERT INTO `mapping_civility` VALUES ('3', 'isabelle', 'F');
Ваша функция can not возвращает NULL, но вместо этого строку «INDEFINI». Итак, почему вы говорите, что процедура останавливается, когда функция возвращает NULL? –
Так что код работает на одном сервере, а не на другом? Я нахожу, что ваш код трудно следовать, попробуйте уменьшить код до минимального примера, возможно, с некоторыми примерами данных и структур таблиц, которые могут воспроизвести вашу ошибку. Никто не хочет изучать код в течение 1 часа, чтобы понять, что он делает.Но быстрый галоп над вашим кодом вызывает у меня подозрение в том, что мы не инициализируем 'no_more_rows2', это будет верно после первого цикла и никогда не дойдет до этапа вставки. (То же самое для 'no_more_rows1', хотя кажется, что он не имеет эффекта). Похоже на то, что вы описываете (кроме части «null»). – Solarflare
@ThomasG, вы совершенно правы, я изменил свою функцию, чтобы добавить инструкцию IF mapped_ratecode IS NULL во время выполнения какого-либо теста, я изменю свой вопрос – Kvn91