MySQL - Использование оператора SELECT INTO внутри курсора в хранимой процедуре - PullRequest
0 голосов
/ 30 января 2019

Я пишу хранимую процедуру в базе данных MySQL, используя курсор для итерации по записям.Я могу получить записи внутри переменных, указанных в инструкции FETCH, но когда я использую SELECT внутри курсора, я не могу сохранить результат в переменных.Я знаю, что это возможно, но не могу понять, почему он не работает в нижеприведенном коде MySQL.

CREATE DEFINER=`root`@`localhost` PROCEDURE `add_monthly_leave_entitlement`
(IN `emp` INT(10), OUT `experience` INT(10), OUT `entitlement` DECIMAL(10,4)) DETERMINISTIC
BEGIN 

DECLARE emp_no INT(10);
DECLARE current_month_exp INT(10);
DECLARE previous_month_end_exp INT(10);
DECLARE emp_status INT(10);

DECLARE done INT DEFAULT FALSE;
DECLARE monthly_entitlement decimal(8,4) DEFAULT 0;

DECLARE emp_cursor CURSOR FOR
SELECT e.`emp_number` AS emp_no, 
TIMESTAMPDIFF( YEAR, e.`joined_date` , NOW( ) ) AS month_start_exp, 
TIMESTAMPDIFF( YEAR, e.`joined_date`, LAST_DAY(NOW()- INTERVAL 1 MONTH) ) AS last_month_end_exp, e.`emp_status` AS emp_status 
FROM `hs_hr_employee` AS e 
WHERE e.`termination_id` is null AND e.`emp_number`=emp;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

OPEN emp_cursor;

read_loop : LOOP
FETCH emp_cursor INTO emp_no, current_month_exp, previous_month_end_exp, emp_status;
    IF done THEN
        LEAVE read_loop;
    END IF;

    /*Monthly entitlement as per experience*/       
    SELECT `monthly_entitlement` INTO monthly_entitlement 
    FROM `ohrm_leave_entitlement_conf` 
    WHERE `year_completion` = IF(previous_month_end_exp >4 , 5, previous_month_end_exp) 
    AND `leave_type_id` = 4;

   SET experience = previous_month_end_exp;
   SET entitlement = monthly_entitlement;

END LOOP;

CLOSE emp_cursor;
END

Невозможно получить значение внутри month_entitlement или право ,значение всегда 0,0000 .Я попытался запустить ежемесячный запрос прав в отдельной процедуре, он возвращает правильное значение.У меня совпадают типы данных столбца и переменных таблицы.

Может кто-нибудь помочь мне понять, что здесь не так?

Ответы [ 2 ]

0 голосов
/ 31 июля 2019

Как подсказывают другие, имя локальной переменной и имя столбца должны отличаться, поэтому здесь изменения

CREATE DEFINER=`root`@`localhost` PROCEDURE `add_monthly_leave_entitlement`
(IN `emp` INT(10), OUT `experience` INT(10), OUT `entitlement` DECIMAL(10,4)) DETERMINISTIC
BEGIN 

DECLARE v_emp_no INT(10);
DECLARE v_current_month_exp INT(10);
DECLARE v_previous_month_end_exp INT(10);
DECLARE v_emp_status INT(10);

DECLARE done INT DEFAULT FALSE;
DECLARE v_monthly_entitlement decimal(8,4) DEFAULT 0;

DECLARE emp_cursor CURSOR FOR
SELECT e.`emp_number` AS emp_no, 
TIMESTAMPDIFF( YEAR, e.`joined_date` , NOW( ) ) AS month_start_exp, 
TIMESTAMPDIFF( YEAR, e.`joined_date`, LAST_DAY(NOW()- INTERVAL 1 MONTH) ) AS last_month_end_exp, e.`emp_status` AS emp_status 
FROM `hs_hr_employee` AS e 
WHERE e.`termination_id` is null AND e.`emp_number`=emp;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

OPEN emp_cursor;

read_loop : LOOP
FETCH emp_cursor INTO v_emp_no, v_current_month_exp, v_previous_month_end_exp, v_emp_status;
    IF done THEN
        LEAVE read_loop;
    END IF;

    /*Monthly entitlement as per experience*/       
    SELECT `monthly_entitlement` INTO v_monthly_entitlement 
    FROM `ohrm_leave_entitlement_conf` 
    WHERE `year_completion` = IF(v_previous_month_end_exp >4 , 5, v_previous_month_end_exp) 
    AND `leave_type_id` = 4;

   SET experience = v_previous_month_end_exp;
   SET entitlement = v_monthly_entitlement;

END LOOP;

CLOSE emp_cursor;
END
0 голосов
/ 16 февраля 2019

Избегайте именования локальных переменных в качестве имени столбцов, см. Глава 2 Ограничения для хранимых программ :: Конфликты имен в хранимых подпрограммах .Попробуйте изменить следующее:

...
-- DECLARE monthly_entitlement decimal(8,4) DEFAULT 0;
DECLARE _monthly_entitlement decimal(8,4) DEFAULT 0;
...
/*Monthly entitlement as per experience*/
-- SELECT `monthly_entitlement` INTO monthly_entitlement
SELECT `monthly_entitlement` INTO _monthly_entitlement
...
-- SET entitlement = monthly_entitlement;
SET entitlement = _monthly_entitlement;
...
...