【问题标题】:error in loop of procedure using a cursor使用游标的过程循环错误
【发布时间】:2015-12-05 11:29:50
【问题描述】:

我有这个 MySQL 过程,我使用游标来:

CREATE DEFINER=`root`@`localhost` PROCEDURE `tax_to_salary`()
BEGIN
DECLARE basic_salary INTEGER;
DECLARE new_salary INTEGER;
DECLARE done INTEGER;
declare count INTEGER;

DECLARE counter INTEGER default 0;
DECLARE cur1 CURSOR FOR SELECT salary FROM employee;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

SELECT count(id) INTO count FROM employee;
SET @counter:=0;

OPEN cur1;
l1:LOOP
FETCH cur1 INTO basic_salary;
SET @counter:=@counter+1;
IF @counter>count THEN
leave l1;
end if;
IF basic_salary>2500 THEN
SET @new_salary := 500;
SET @basic_salary := @basic_salary - @new_salary;
else
SET @new_salary := 200;
SET @basic_salary := @basic_salary - @new_salary;
END IF;
SELECT emp_name, salary, basic_salary AS 'Salary after taxes' FROM employee; 

END LOOP;
END

我得到了这个结果:

但是我的程序应该从所有超过 2500 的工资中删除 500,并从低于 2500 的工资中删除 200。 我试图将最终的 SELECT 查询放在循环中,但我得到了 5 个选项卡,每个选项卡都包含相同的下图。

【问题讨论】:

    标签: mysql sql stored-procedures cursor


    【解决方案1】:

    架构

    create table employee
    (   id int auto_increment primary key,
        emp_name varchar(100) not null,
        salary int not null
    );
    
    insert employee (emp_name,salary) values
    ('John',4400),
    ('Sarah',2700),
    ('Peter',2150),
    ('Ali',2650),
    ('Ashley',2650);
    

    请注意,您的语言大于 2500,也您说小于 2500。但它没有条件确切地等于 2500 的薪水。因此,以下是对该概念的一种修复(否则不会减少)。

    情况

    最适合多种情况,而不是你的情况

    select emp_name,salary, 
    CASE when salary>=2500 then salary-500 
    ELSE 
        salary-200 
    END as modified_salary 
    from employee;
    +----------+--------+-----------------+
    | emp_name | salary | modified_salary |
    +----------+--------+-----------------+
    | John     |   4400 |            3900 |
    | Sarah    |   2700 |            2200 |
    | Peter    |   2150 |            1950 |
    | Ali      |   2650 |            2150 |
    | Ashley   |   2650 |            2150 |
    +----------+--------+-----------------+
    

    如果

    对于像你这样的简单条件

    select emp_name,salary,  
    if(salary>=2500,salary-500,salary-200) as modified_salary  
    from employee;
    +----------+--------+-----------------+
    | emp_name | salary | modified_salary |
    +----------+--------+-----------------+
    | John     |   4400 |            3900 |
    | Sarah    |   2700 |            2200 |
    | Peter    |   2150 |            1950 |
    | Ali      |   2650 |            2150 |
    | Ashley   |   2650 |            2150 |
    +----------+--------+-----------------+
    

    没有理由像您一样使用逐行游标。这就是人们有时刚开始使用 sql 时所做的事情。它们不仅速度慢,而且通常慢得让人难以忍受,而且它们还使您无法利用关系的力量来使 sql 大放异彩。

    换句话说,您正在尝试编写过程代码,并通过帮助 sql 引擎以这种心态解决问题,从而参与其中。它不希望以这种方式进行优化。你可以,但你会非常慢。

    正如您所说,您获得多个选项卡的原因是您的策略,即使它在数字方面运行良好,每个 select 语句都会返回一个结果集。通过危险的游标路线,您返回了其中的五个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-28
      • 2011-03-14
      • 2017-02-16
      • 2020-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-29
      相关资源
      最近更新 更多