在学习游标的使用,弄了两个表,一个girls(girlId,name,tel),另一个Tels(tel),其中一个girls表tel字段都是空的,想建立存储过程利用游标逐一地将Tels表内数据搬到girls的tel属性上,但是发现自己建的循环体内总是会把tel第二行起的数据给游标:
'''
DROP TABLE IF EXISTS girls;
CREATE TABLE girls(
girlId int auto_increment primary key,
girlName varchar(20)
);
INSERT INTO girls(girlName) VALUES ('Maria');
INSERT INTO girls(girlName) VALUES ('Ringo');
INSERT INTO girls(girlName) VALUES ('Messa');
INSERT INTO girls(girlName) VALUES ('Alice');
ALTER TABLE girls add tel varchar(20);
DROP TABLE IF EXISTS TELS;
CREATE TABLE TELS (
tel varchar(20)
);
INSERT INTO TELS VALUES ('11111111');
INSERT INTO TELS VALUES ('22222222');
INSERT INTO TELS VALUES ('33333333');
INSERT INTO TELS VALUES ('44444444');
DROP PROCEDURE IF EXISTS TravarseTEL;
CREATE PROCEDURE TravarseTEL()
BEGIN
DECLARE telvalue VARCHAR(20);
DECLARE i INT DEFAULT 0;
DECLARE len INT DEFAULT 0;
DECLARE FOUND BOOLEAN DEFAULT TRUE;
DECLARE telcur CURSOR FOR SELECT tel FROM TELS;
Declare continue handler for not found set FOUND = false;
SELECT COUNT(*) FROM girls INTO len;
OPEN telcur;
FETCH telcur into telvalue;
WHILE i <= len and found DO
SELECT telvalue;
UPDATE girls SET tel = telvalue WHERE girlId = i;
FETCH telcur into telvalue;
set i = i+1;
end while;
close telcur;
end;
call TravarseTEL();
'''
感觉第一段fetch语句已经拉取了第一行了,但不知道为什么进入循环体里首先被添加的就是第二行,后面发现,只要在循环体里又加了一个fetch语句就会从第二起开始取,无论循环体之前有没有加fetch语句都是这样。
你这个问题跟游标的使用没有关系, 你进行游标的获取并没有错误.
结果不正确是因为你的 update 代码有问题:
UPDATE girls SET tel = telvalue WHERE girlId = i;
这里的 i
你是从 0 开始的,而你的 girls
的主键是从 1 开始的. 所以你循环中第一次执行是不正确的,因此你的循环相当于:
UPDATE girls SET tel = '11111111' WHERE girlId = 0;
UPDATE girls SET tel = '22222222' WHERE girlId = 1;
UPDATE girls SET tel = '33333333' WHERE girlId = 2;
UPDATE girls SET tel = '44444444' WHERE girlId = 3;
因此你这里,只需要把 i
和 girlsId
对应即可.