CURSOR 看起来为空,但 SELECT 返回非空数据

问题描述 投票:0回答:1

我有一个 mysql 程序,用于向社会活跃的学生发放津贴。在此程序中,我正在更新学生表。在此过程中,我定义了一个游标,它提供 2 个值(student_id 和 Student_participations - 学生参与的活动数量)。这意味着在我的 select 语句中,我采用了 2 个表:学生以及学生和参与表的子查询。因为我知道这个选择查询返回过程之外的数据,所以我无法弄清楚为什么光标保持为空。

程序:

DELIMITER //
create procedure update_st_value_by_participation(in how_much int)
begin

    declare student_id, value_multiplier int;
    declare is_end int default 0;
    
    declare students_cursor cursor for 
    select studs.st_id, tb1.st_participations from studs, 
    (select student_id as st_id, count(student_id) as st_participations 
    from participation group by student_id) as tb1
    where tb1.st_participations > 1 and tb1.st_id = studs.st_id;
    
    declare continue handler for not found set is_end=1;
    
    open students_cursor;
        curs: Loop
            fetch students_cursor into student_id, value_multiplier;
            
            if is_end then
                leave curs;
            end if;
            update studs
            set st_value = st_value + how_much * (value_multiplier - 1)
            where st_id = student_id;
        end loop curs;
    
    close students_cursor;
end //

(is_end 以某种方式取值=1)

我一直在使用的表格:

create table studs(
st_id int primary key auto_increment,
st_name varchar(30),
st_surname varchar(30),
st_course int,
st_speciality enum('km', 'webs', 'mobile', 'mech'),
st_form enum('free', 'not free'),
st_value float
);

create table activities(
activity_id int primary key auto_increment,
activity_name varchar(50),
activity_description varchar(200),
activity_date date,
activity_place varchar(50),
activity_organizer varchar(30)
);

create table participation(
participation_id int primary key auto_increment,
student_id int,
activity_id int,
participation_role varchar(20),
participation_result varchar(50),

constraint ref_studs_to_participation foreign key (student_id) references studs (st_id),
constraint ref_activities_to_participation foreign key (activity_id) references activities (activity_id)
);
mysql subquery procedure database-cursor
1个回答
1
投票

你的问题是你的变量叫做studento_id。

规则是永远不要使用列名作为变量名。

遵守规则的最简单方法是为每个变量使用像 p_ 这样的前缀,这样就不会出现重复的名称(就像没有以 p_ 开头的列名称一样,但这只是一个示例。

更改变量名称并简化光标后。

create table studs(
st_id int primary key auto_increment,
st_name varchar(30),
st_surname varchar(30),
st_course int,
st_speciality enum('km', 'webs', 'mobile', 'mech'),
st_form enum('free', 'not free'),
st_value float
);

create table activities(
activity_id int primary key auto_increment,
activity_name varchar(50),
activity_description varchar(200),
activity_date date,
activity_place varchar(50),
activity_organizer varchar(30)
);

create table participation(
participation_id int primary key auto_increment,
student_id int,
activity_id int,
participation_role varchar(20),
participation_result varchar(50),

constraint ref_studs_to_participation foreign key (student_id) references studs (st_id),
constraint ref_activities_to_participation foreign key (activity_id) references activities (activity_id)
);
INSERT INTO studs VALUES(NULL ,'testA','testB',1,'km','free', 1.6);
INSERT INTO studs VALUES(NULL ,'testA1','testB1',2,'km','free', 1.1);
INSERT INTO studs VALUES(NULL ,'testA2','testB2',3,'km','free', 1.1);
INSERT INTO activities VALUEs (NULL,'test1','test2', NOW(),'test4','test5');
INSERT INTO activities VALUEs (NULL,'test11','test21', NOW(),'test41','test51');
INSERT INTO activities VALUEs (NULL,'test12','test22', NOW(),'test42','test52');
INSERT INTO participation VALUES (NULL,1,1,'test','test');
INSERT INTO participation VALUES (NULL,1,2,'test','test');
INSERT INTO participation VALUES (NULL,1,3,'test','test');
INSERT INTO participation VALUES (NULL,2,1,'test','test');
INSERT INTO participation VALUES (NULL,2,2,'test','test');
INSERT INTO participation VALUES (NULL,3,3,'test','test');
INSERT INTO participation VALUES (NULL,3,2,'test','test');
INSERT INTO participation VALUES (NULL,3,3,'test','test');
create procedure update_st_value_by_participation(in p_how_much int)
begin

    declare p_student_id, p_value_multiplier int;
    declare is_end int default 0;
    
    declare students_cursor cursor for 
     select student_id, count(student_id) as st_participations 
    from participation group by student_id;
    
    declare continue handler for not found set is_end=1;
    
    open students_cursor;
        curs: Loop
            fetch students_cursor into p_student_id, p_value_multiplier;
            
            if is_end then
                leave curs;
            end if;
            update studs
            set st_value = st_value + p_how_much * (p_value_multiplier - 1)
            where st_id = p_student_id;
        end loop curs;
    
    close students_cursor;
end
CALL update_st_value_by_participation(21)
SELECT * FROM studs
st_id st_name st_姓氏 st_课程 st_专业 st_表格 st_值
1 测试A 测试B 1 公里 免费 43.6
2 测试A1 测试B1 2 公里 免费 22.1
3 测试A2 测试B2 3 公里 免费 43.1

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.