为什么WHILE循环中的SELECT
语句只返回第一次迭代的值?
INSERT IGNORE
和第二INSERT
都在工作,并且正在插入等于amount
的行。
如果我将amount
设置为10,我只会从第一个插入的行中获得结果。但是,该过程会INSERT
amount
行到rand_strings
和rand_strings_info
表。
程序:
DROP PROCEDURE if exists test_while;
DELIMITER $$
CREATE PROCEDURE test_while(amount INT, description VARCHAR(255))
BEGIN
WHILE amount > 0 DO
INSERT IGNORE INTO rand_strings(rand_string) /*WORKS EVERY ITERATION*/
SELECT generate_rand_string(); /*function to generate a random string.*/
SELECT * FROM rand_strings WHERE id = LAST_INSERT_ID(); /*ONLY WORKS FIRST TIME */
INSERT INTO rand_strings_info(id, col2, col3) /*WORKS EVERY ITERATION*/
VALUES (LAST_INSERT_ID(), now(), description);
SET amount = amount - 1;
END WHILE;
END$$
DELIMITER ;
CALL test_while(10, 'This is the description of the string…')
RESULTS:
id | rand_string
1 | jgdlkjaht
答案 0 :(得分:0)
某些界面未按预期显示所有结果,但代码正确运行。
您可以在下面的 SQL Fiddle 中看到,只显示存储过程运行时rand_strings
表中的第一条记录,但在MySQL命令行上运行相同的代码结果如下:
mysql> CALL `test_while`(5, 'This is the description of the string...');
+----+------------------------------------------+
| id | rand_string |
+----+------------------------------------------+
| 1 | f4c77a3155d95ad1e818b1b06a62deec8e0b6754 |
+----+------------------------------------------+
1 row in set (0.00 sec)
+----+------------------------------------------+
| id | rand_string |
+----+------------------------------------------+
| 2 | 7cbcca49596262836f5af91643303d10b3804900 |
+----+------------------------------------------+
1 row in set (0.00 sec)
+----+------------------------------------------+
| id | rand_string |
+----+------------------------------------------+
| 3 | 2ba2c7276c0b66e3dcbb971b7f54af9bced578a4 |
+----+------------------------------------------+
1 row in set (0.00 sec)
+----+------------------------------------------+
| id | rand_string |
+----+------------------------------------------+
| 4 | d52426b19a59c515b02268347c508383873d4d73 |
+----+------------------------------------------+
1 row in set (0.00 sec)
+----+------------------------------------------+
| id | rand_string |
+----+------------------------------------------+
| 5 | fbc25c6204b609e8f4f4f8a33b534bff9a011e5f |
+----+------------------------------------------+
1 row in set (0.00 sec)
Query OK, 1 row affected (0.00 sec)
<强>更新强>
DELIMITER $$
CREATE PROCEDURE `test_while`(`amount` INT, `description` VARCHAR(255))
BEGIN
DECLARE `_LAST_INSERT_ID`, `_first_inserted_in_this_run` INT UNSIGNED DEFAULT NULL;
CREATE TEMPORARY TABLE IF NOT EXISTS `temp_generate_rand_string` (
`insert_id` INT UNSIGNED PRIMARY KEY,
`first_inserted_in_this_run` INT UNSIGNED
) ENGINE=MEMORY;
WHILE `amount` > 0 DO
INSERT IGNORE INTO `rand_strings`(`rand_string`) /*WORKS EVERY ITERATION*/
SELECT `generate_rand_string`(); /*function to generate a random string.*/
SET `_LAST_INSERT_ID` := LAST_INSERT_ID();
IF (`_first_inserted_in_this_run` IS NULL) THEN
SET `_first_inserted_in_this_run` := `_LAST_INSERT_ID`;
END IF;
INSERT INTO `temp_generate_rand_string` (`insert_id`, `first_inserted_in_this_run`)
VALUES
(`_LAST_INSERT_ID`, `_first_inserted_in_this_run`);
-- SELECT * FROM `rand_strings` WHERE `id` = `_LAST_INSERT_ID`; /*ONLY WORKS FIRST TIME */
INSERT INTO `rand_strings_info`(`id`, `col2`, `col3`) /*WORKS EVERY ITERATION*/
VALUES (`_LAST_INSERT_ID`, NOW(), `description`);
SET `amount` := `amount` - 1;
END WHILE;
SELECT `rs`.`id`, `rs`.`rand_string`
FROM `rand_strings` `rs`
INNER JOIN `temp_generate_rand_string` `tgrs` ON
`tgrs`.`first_inserted_in_this_run` = `_first_inserted_in_this_run` AND
`rs`.`id` = `tgrs`.`insert_id`;
DELETE
FROM `temp_generate_rand_string`
WHERE `first_inserted_in_this_run` = `_first_inserted_in_this_run`;
END$$
DELIMITER ;