Как правильно написать курсор внутри функции? - PullRequest
0 голосов
/ 11 октября 2019

Мне нужна твоя помощь, потому что я отчасти потерян. Я пытался найти в google курсоры в функциях и ссылки на них, но мне кажется, что я не совсем понимаю эту концепцию. У меня есть домашнее задание, где мне нужно:

  • Создать функции, в которых я использую курсоры
  • Запись представляет собой процент увеличения зарплаты (например: 5% - это 0,05)
  • Функции должны обновить зарплату с новой увеличенной ценой
  • Показать новую среднюю зарплату
  • И устранить возможные ошибки

Этоэто то, что я сделал до сих пор ...

Можете ли вы помочь мне решить проблему с подсказкой или хотя бы с простыми примерами / ресурсами курсоров в функциях, чтобы я мог лучше понять концепцию.

DROP FUNCTION IF EXISTS Program;
DELIMITER //
CREATE FUNCTION Program(IncSal DECIMAL(3,2))
RETURNS DECIMAL(8,2)
DETERMINISTIC
    BEGIN
        DECLARE Salaire DECIMAL (8,2);
        DECLARE end BOOLEAN DEFAULT FALSE;
        DECLARE CurSalary CURSOR FOR
            SELECT Sala_EMPL
                        FROM EMPLOYE;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET end = TRUE;      

        OPEN CurSalary;
            loop_cursor: LOOP
                IF end THEN 
                    LEAVE loop_cursor; 
                END IF;
                UPDATE EMPLOYE
                SET Sala_EMPL=(Sala_EMPL*IncSal);
            END LOOP;
        CLOSE CurSalary;

        RETURN AVG(CurSalary);
    END; 
    //
    DELIMITER ;

1 Ответ

0 голосов
/ 12 октября 2019

Если вы используете курсор, вы должны выбрать FETCH из курсора (пожалуйста, просмотрите https://dev.mysql.com/doc/refman/8.0/en/fetch.html) без выборки, цикл бесконечен. AVG - агрегатная функция, вы не можете AVG по курсору (вам нужно выбрать. .from). Ваше заявление об обновлении будет применяться ко всем сотрудникам каждый раз, когда вы повторяете цикл курсора (логически абсурдно). Лично я бы никогда не использовал функцию, потому что то, что вы пытаетесь сделать, не совсем подходит для функции (я бы использовалпроцедура).

пример «работающей», но неправильной функции

DROP FUNCTION IF EXISTS f;
DELIMITER //
CREATE FUNCTION f(IncSal DECIMAL(3,2))
RETURNS DECIMAL(8,2)
DETERMINISTIC
    BEGIN
        DECLARE Salaire DECIMAL (8,2);
        DECLARE end BOOLEAN DEFAULT FALSE;
        DECLARE CurSalary CURSOR FOR
        SELECT salary FROM EMPLOYEe;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET end = TRUE;      

        OPEN CurSalary;
            loop_cursor: LOOP
                 fetch cursalary into salaire;
                IF end THEN 
                    LEAVE loop_cursor; 
                END IF;
                UPDATE EMPLOYEe
                            SET Salary=salary + (salary*incsal);
            END LOOP;
        CLOSE CurSalary;

        #RETURN AVG(CurSalary);
        return (select avg(salary) from employee);
    END; 
    //
    DELIMITER ;

MariaDB [sandbox]> select * from employee;
+------------+-----------+--------------+--------+
| employeeid | firstname | departmentid | salary |
+------------+-----------+--------------+--------+
|          1 | aaa       |            1 |  10000 |
|          2 | bbb       |            2 |  10000 |
|          3 | ccc       |            3 |  10000 |
+------------+-----------+--------------+--------+
3 rows in set (0.00 sec)

MariaDB [sandbox]>
MariaDB [sandbox]>     select f(.05);
+----------+
| f(.05)   |
+----------+
| 11576.00 |
+----------+
1 row in set (0.00 sec)

MariaDB [sandbox]>
MariaDB [sandbox]>     select * from employee;
+------------+-----------+--------------+--------+
| employeeid | firstname | departmentid | salary |
+------------+-----------+--------------+--------+
|          1 | aaa       |            1 |  11576 |
|          2 | bbb       |            2 |  11576 |
|          3 | ccc       |            3 |  11576 |
+------------+-----------+--------------+--------+
3 rows in set (0.00 sec)
...