MySQL while循环插入
MySQL while loop insert
我在 MySQL
上插入 while 循环时遇到一个非常奇怪的问题
这是我测试的背景信息:
CREATE TABLE test_table (
`token` varchar(16) NOT NULL,
`val1` varchar(256) DEFAULT NULL,
PRIMARY KEY (`token`)
);
DELIMITER $$
CREATE PROCEDURE sp_test(
IN token VARCHAR(16),
IN token1 VARCHAR(16),
IN token2 VARCHAR(16),
IN token3 VARCHAR(16),
IN token4 VARCHAR(16),
IN val1 VARCHAR(256)
)
BEGIN
DECLARE tokenUsed VARCHAR(16);
DECLARE trial INT DEFAULT 0;
DECLARE tmpTok VARCHAR(16);
WHILE (tokenUsed IS NULL AND trial < 5)
DO
SET tmpTok = CASE trial WHEN 0 THEN token WHEN 1 THEN token1 WHEN 2 THEN token2
WHEN 3 THEN token3 WHEN 4 THEN token4 END;
IF NOT EXISTS(SELECT 1 FROM test_table WHERE token = tmpTok)
THEN
SET tokenUsed = tmpTok;
INSERT INTO test_table (token) VALUES(tmpTok);
END IF;
SET trial = trial + 1;
END WHILE;
IF tokenUsed IS NOT NULL
THEN
UPDATE test_table SET val1 = val1 WHERE token = tokenUsed;
END IF;
SELECT * FROM test_table WHERE token = tokenUsed;
END$$
DELIMITER ;
然后我会像这样调用存储过程服务时间
CALL sp_test ('test1', 'test2', 'test3', 'test4', 'test5', 'happy');
我想要达到的目标
- 将 5 个随机令牌提供给 sp
- 插入第一个可用的令牌(即 test_table 中不存在)
- 使用插入的标记更新记录的其余部分,return 该记录
症状如下
- 第一次调用 sp_test,没问题,sp returned |测试1 |快乐 |
- 第二次调用 sp_test,没有错误,但 sp return 什么也没做; test2 已插入,但 val1 未更新,即 |测试2 |空 |
- 第三次调用 sp_test 崩溃
Error Code: 1062. Duplicate entry 'test2' for key 'PRIMARY'
while 循环确实移动到令牌 test2 并将其插入到 test_table 但没有继续,在 test2[=51 之后更新也失败了=].
存储过程非常简单,我不知道为什么会这样。有什么想法吗?
- 在你的 SP 中有一行
UPDATE test_table SET val1 = val1 WHERE token = tokenUsed;
其中的val1
都是SP参数中定义的局部变量。 token
也一样。必须是
UPDATE test_table SET test_table.val1 = val1 WHERE test_table.token = tokenUsed;
另请检查您的代码是否存在其他语句中的相同问题。
我在 MySQL
上插入 while 循环时遇到一个非常奇怪的问题这是我测试的背景信息:
CREATE TABLE test_table (
`token` varchar(16) NOT NULL,
`val1` varchar(256) DEFAULT NULL,
PRIMARY KEY (`token`)
);
DELIMITER $$
CREATE PROCEDURE sp_test(
IN token VARCHAR(16),
IN token1 VARCHAR(16),
IN token2 VARCHAR(16),
IN token3 VARCHAR(16),
IN token4 VARCHAR(16),
IN val1 VARCHAR(256)
)
BEGIN
DECLARE tokenUsed VARCHAR(16);
DECLARE trial INT DEFAULT 0;
DECLARE tmpTok VARCHAR(16);
WHILE (tokenUsed IS NULL AND trial < 5)
DO
SET tmpTok = CASE trial WHEN 0 THEN token WHEN 1 THEN token1 WHEN 2 THEN token2
WHEN 3 THEN token3 WHEN 4 THEN token4 END;
IF NOT EXISTS(SELECT 1 FROM test_table WHERE token = tmpTok)
THEN
SET tokenUsed = tmpTok;
INSERT INTO test_table (token) VALUES(tmpTok);
END IF;
SET trial = trial + 1;
END WHILE;
IF tokenUsed IS NOT NULL
THEN
UPDATE test_table SET val1 = val1 WHERE token = tokenUsed;
END IF;
SELECT * FROM test_table WHERE token = tokenUsed;
END$$
DELIMITER ;
然后我会像这样调用存储过程服务时间
CALL sp_test ('test1', 'test2', 'test3', 'test4', 'test5', 'happy');
我想要达到的目标
- 将 5 个随机令牌提供给 sp
- 插入第一个可用的令牌(即 test_table 中不存在)
- 使用插入的标记更新记录的其余部分,return 该记录
症状如下
- 第一次调用 sp_test,没问题,sp returned |测试1 |快乐 |
- 第二次调用 sp_test,没有错误,但 sp return 什么也没做; test2 已插入,但 val1 未更新,即 |测试2 |空 |
- 第三次调用 sp_test 崩溃
Error Code: 1062. Duplicate entry 'test2' for key 'PRIMARY'
while 循环确实移动到令牌 test2 并将其插入到 test_table 但没有继续,在 test2[=51 之后更新也失败了=]. 存储过程非常简单,我不知道为什么会这样。有什么想法吗?
- 在你的 SP 中有一行
UPDATE test_table SET val1 = val1 WHERE token = tokenUsed;
其中的val1
都是SP参数中定义的局部变量。 token
也一样。必须是
UPDATE test_table SET test_table.val1 = val1 WHERE test_table.token = tokenUsed;
另请检查您的代码是否存在其他语句中的相同问题。