I am new to mysql store procedure. I want my store procedure to check date value in Field date and compare to current date. If current date is bigger than date value in table, I want to update value in field status_number to '0'.
Here is my query :
DELIMITER $$
DROP PROCEDURE IF EXISTS check_status$$
CREATE PROCEDURE check_status()
BEGIN
DECLARE dd DATE;
DECLARE bDone INT;
DECLARE Count INT;
DEClARE my_status CURSOR FOR SELECT dates FROM t_date;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;
OPEN my_status;
SET bDone = 0;
REPEAT
FETCH my_status INTO dd;
IF (dd < DATE(NOW()))
UPDATE t_date SET (status_number) VALUES (1);
END IF;
UNTIL bDone END REPEAT;
CLOSE my_status;
END$$
DELIMITER ;
Error message :
Thank for answering.
DELIMITER $$
DROP PROCEDURE IF EXISTS check_status$$
CREATE PROCEDURE check_status()
BEGIN
DECLARE dd DATE;
DECLARE bDone INT;
DECLARE Count INT;
DEClARE my_status CURSOR FOR SELECT dates FROM t_date;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;
OPEN my_status;
SET bDone = 0;
REPEAT
FETCH my_status INTO dd;
IF (dd < DATE(NOW()))
-- UPDATE t_date SET (status_number) VALUES (1);
UPDATE t_date SET status_number = 1;
END IF;
UNTIL bDone END REPEAT;
CLOSE my_status;
END$$
DELIMITER ;
Check it. its tested on mssql. I try to convert it for mysql but not tested on mysql but i hope it will works.
DELIMITER //
CREATE PROCEDURE check_status()
BEGIN
DECLARE NOT_FOUND INT DEFAULT 0;
DECLARE v_dd DATE;
-- DECLARE #bDone INT;
-- DECLARE #Count INT;
DECLARE v_name VARCHAR(50); -- database name
DECLARE v_path VARCHAR(256); -- path for backup files
DECLARE v_fileName VARCHAR(256); -- filename for backup
DECLARE v_fileDate VARCHAR(20); -- used for file name
DECLARE db_cursor CURSOR FOR
SELECTdates INTO v_dd
FROM t_date
OPEN
DECLARE CONTINUE HANDLER FOR NOT FOUND SET NOT_FOUND = 1;db_cursor
-- SET #bDone = 0;
FETCH NEXT FROM; db_cursor INTO v_dd
WHILE NOT_FOUND = 0
DO
IF (v_dd < cast (Now() as date) )
Then
UPDATE t_date SET status_number = 1;
END IF;
FETCH NEXT FROM; db_cursor INTO v_dd
END WHILE;
CLOSE db_cursor;
END;
//
DELIMITER ;
Related
THE CURSOR IS NOT GOING TO THE ELSE STATEMENT. WHAT AM I DOING WRONG? HOW CAN I DEBUG IN MYSQL ?
I am trying to get the list of task Ids with null values and then for each taskID, I am calling a SP to create start data and due date of the missing tasks(greater than the max(start_date available) until the current_date
DROP PROCEDURE IF EXISTS zcursor_ADDTA1;
DELIMITER ;;
CREATE PROCEDURE zcursor_ADDTA1(
#out retCount int
)
BEGIN
#DECLARE C_ID INT;
DECLARE C_TASK_ID INT;
DECLARE C_pattern varchar(100);
DECLARE C_REM INT;
DECLARE ACT_T_STTM VARCHAR(100);
DECLARE ACT_T_DTTM VARCHAR(100);
DECLARE TZ VARCHAR(100);
DECLARE T_STDT DATE;
DECLARE T_EXDT DATE;
DECLARE retCount INT;
DECLARE done INT DEFAULT FALSE;
DECLARE TA_MAX_ST_DT DATE;
#DECLARE P1 INT;
DECLARE cursor_i CURSOR FOR SELECT TASK_ID, PATTERN, reminder_days_before, ACTUAL_TASK_START_TIME,ACTUAL_TASK_DUE_TIME,TIMEZONE,
START_DT,EXP_DT FROM OCC_ML_TASK_RECURRENCE TR WHERE PATTERN = 'DAILY' AND CALENDAR_TYPE='' AND IS_CANCELED =0 AND EXP_DT>CURRENT_DATE();
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SET retCount = 0;
OPEN cursor_i;
read_loop: LOOP
FETCH NEXT FROM cursor_i INTO C_TASK_ID,C_pattern,C_REM,ACT_T_STTM,ACT_T_DTTM,
TZ,T_STDT,T_EXDT;
IF done THEN
LEAVE read_loop;
ELSE
SELECT MAX(TA.START_DTM)FROM
OCC_ML_TASK_ACTIVITY TA
WHERE TA.TASK_ID=C_TASK_ID INTO TA_MAX_ST_DT;
SELECT DATE_ADD(TA_MAX_ST_DT,INTERVAL 1 DAY) INTO TA_MAX_ST_DT;
WHILE (TA_MAX_ST_DT<=CURRENT_DATE())
DO
BEGIN
IF WEEKDAY(TA_MAX_ST_DT)=4 THEN
CALL ZTA_MISSINGDATA_INSERT(C_TASK_ID ,TA_MAX_ST_DT);
SELECT DATE_ADD(TA_MAX_ST_DT,INTERVAL 3 DAY)INTO TA_MAX_ST_DT;
ELSEIF WEEKDAY(TA_MAX_ST_DT)=5 THEN
#"NO INSERT "
SELECT DATE_ADD(TA_MAX_ST_DT,INTERVAL 2 DAY)INTO TA_MAX_ST_DT;
ELSEIF WEEKDAY(TA_MAX_ST_DT)=6 THEN
#"NO INSERT "
SELECT DATE_ADD(TA_MAX_ST_DT,INTERVAL 1 DAY)INTO TA_MAX_ST_DT;
ELSE
CALL ZTA_MISSINGDATA_INSERT(C_TASK_ID ,TA_MAX_ST_DT);
SELECT DATE_ADD(TA_MAX_ST_DT,INTERVAL 1 DAY) INTO TA_MAX_ST_DT;
END IF;
END;
END WHILE;
END IF;
END LOOP;
CLOSE cursor_i;
END;
;;
Below procedure code running with out error . Line select FOUND_ROWS() returning n no. rows but cursor curs did not loop all rows
CREATE DEFINER=`root`#`%` PROCEDURE `middleLocationAutoUpdatePorc`()
BEGIN
declare vname varchar(45);
declare vmobile varchar(20);
declare vsapid varchar(6);
declare vuser varchar(45);
declare vday date;
declare vmintime time;
declare vmaxtime time;
declare vminLocation mediumtext;
declare vmaxLocation mediumtext;
declare vmiddlelocation mediumtext;
declare vdistance int(11);
declare vdrdid int(11);
declare vn_no_details int(11);
declare uatt varchar(45) default 'X';
declare adatta varchar(45) default 'X';
declare b_not_found BOOL DEFAULT FALSE;
declare curs CURSOR FOR
SELECT user ,day, mintime,maxtime_mobile,minLocation,maxLocation,distance,n_no_details,drdid FROM mydb.statusreport where day >= '2017-06-26';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET b_not_found = true;
OPEN curs;
loop1: LOOP
FETCH curs INTO vuser,vday,vmintime,vmaxtime,vminLocation,vmaxLocation,vdistance,vn_no_details,vdrdid;
IF b_not_found THEN
LEAVE loop1;
END IF;
-- select FOUND_ROWS();
case substring_index(vuser,"-",-1)
when 'RSM' then
select username,Name,mobile into vsapid,vname,vmobile from mydb.supervisor where idSu=CONVERT(substring_index(vuser,"-",1),UNSIGNED INTEGER);
when 'ASM' then
select userName,name,mobile into vsapid,vname,vmobile from mydb.executive where exeid=CONVERT(substring_index(vuser,"-",1),UNSIGNED INTEGER);
when 'F' then
select sapId,name,phone into vsapid,vname,vmobile from mydb.user where idUser=CONVERT(substring_index(vuser,"-",1),UNSIGNED INTEGER);
end case;
select userGiven , adminGiven into uatt ,adatta from userdaystatus st where st.date =vday and st.idUser=CONVERT(substring_index(vuser,"-",1),UNSIGNED INTEGER) and st.userType=substring_index(vuser,"-",-1);
set vmiddlelocation=( select location from mydb.dailyReportDetails as dtb where dtb.idDailyReport=vdrdid and dtb.counter>=(abs(vn_no_details/2) ) order by dtb.idDailyReportDetails asc limit 1);
call mydb.addOMiddleLocation(day(vday), month(vday),
year(vday),vuser, vname,
vsapid, vmobile, vmintime,
vmaxtime, SUBTIME(vmaxtime,vmintime),
vminLocation,
vmiddlelocation,
vmaxLocation,Round(vdistance/1000,2),
uatt, adatta);
END LOOP;
CLOSE curs;
END
The Procedure call mydb.addOMiddleLocation() just inserting Row on another table.There does not have any data type validation .
So what can be the problem ?
It happen for log wait time for a particular Query line
set vmiddlelocation=( select location from mydb.dailyReportDetails as dtb where dtb.idDailyReport=vdrdid and dtb.counter>=(abs(vn_no_details/2) ) order by dtb.idDailyReportDetails asc limit 1);
How to use for loop in MySQL data set ?
FOR x IN (SELECT column FROM table_name WHERE column_2 = input_val)
LOOP
sum_total := sum_total + x.column ;
END LOOP;
This is an example how I used to loop data set in oracle.
How can this be achieved in MySql ?
How about not looping at all. It's SQL after all.
SELECT SUM(`column`) total
FROM table_name
WHERE column_2 = <input_val>
Otherwise use CURSOR
Now, equivalent loop using CURSOR will look like
DELIMITER $$
CREATE PROCEDURE sp_loop(IN input_val INT)
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE sum_current, sum_total INT DEFAULT 0;
DECLARE cur1 CURSOR FOR SELECT column1 FROM table_name WHERE column2 = input_val;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO sum_current;
IF done THEN
LEAVE read_loop;
END IF;
SET sum_total = sum_total + sum_current;
END LOOP;
CLOSE cur1;
SELECT sum_total;
END$$
DELIMITER ;
Here is SQLFiddle
DROP PROCEDURE IF EXISTS `foo`.`usp_cursor_example`;
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `foo`.`usp_cursor_example`(
IN name_in VARCHAR(255)
)
READS SQL DATA
BEGIN
DECLARE name_val VARCHAR(255);
DECLARE status_update_val VARCHAR(255);
-- Declare variables used just for cursor and loop control
DECLARE no_more_rows BOOLEAN;
DECLARE loop_cntr INT DEFAULT 0;
DECLARE num_rows INT DEFAULT 0;
-- Declare the cursor
DECLARE friends_cur CURSOR FOR
SELECT
name
, status_update
FROM foo.friend_status
WHERE name = name_in;
-- Declare 'handlers' for exceptions
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET no_more_rows = TRUE;
OPEN friends_cur;
select FOUND_ROWS() into num_rows;
the_loop: LOOP
FETCH friends_cur
INTO name_val
, status_update_val;
IF no_more_rows THEN
CLOSE friends_cur;
LEAVE the_loop;
END IF;
select name_val, status_update_val;
-- count the number of times looped
SET loop_cntr = loop_cntr + 1;
END LOOP the_loop;
-- 'print' the output so we can see they are the same
select num_rows, loop_cntr;
END
DELIMITER ;
The following procedure did not update any rows. Is there an obvious mistake in the syntax? I'm new to MySQL
set autocommit = 0;
DROP procedure IF EXISTS update_fee;
delimiter //
CREATE PROCEDURE update_fee()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE t_fee_id int(10);
DECLARE t_pubco_id int(10);
DECLARE t_auditor_id int(10);
declare fiscal_period_end_id int(10);
declare t_fiscal_year int(4);
DECLARE t_audit_id int(10);
DECLARE cur1 CURSOR FOR SELECT fee_id, pubco_id, auditor_id, fiscal_period_end_id, fiscal_year
from a_fees;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO t_fee_id, t_pubco_id,
t_auditor_id , fiscal_period_end_id, t_fiscal_year;
IF done THEN
LEAVE read_loop;
END IF;
set t_audit_id = get_audit_id (t_pubco_id,
t_auditor_id,
concat('''', t_fiscal_year, '-',
(select concat(fiscal_period_end_month, '-', fiscal_period_end_day, ''''
)
from a_fiscal_period_end
where t_fiscal_period_end_id = a_fiscal_period_end.fiscal_period_end_id
), ''''
)
);
update a_fees set audit_id = t_audit_id;
END LOOP;
CLOSE cur1;
END;
delimiter ;
set autocommit = 0; mean that you must COMMIT your changes manually. Use START TRANSACTION and COMMIT or ROLLBACK.
I was trying use multiple select at one procedure to assign the value of variable.
but i got error like this "Operand should contain 1 column(s)"
this is my code :
DELIMITER $$
DROP PROCEDURE IF EXISTS `bankdb`.`charge` $$
CREATE PROCEDURE `bankdb`.`charge` ()
BEGIN
DECLARE idcust_val INT;
DECLARE balance_val FLOAT;
DECLARE balance_val1 FLOAT;
DECLARE balance_val2 FLOAT;
DECLARE productCd_val VARCHAR(10);
DECLARE productType_val VARCHAR(10);
DECLARE no_more_rows INT DEFAULT 0;
DECLARE num_rows INT DEFAULT 0;
DECLARE col_cur CURSOR FOR
select a.cust_id, a.avail_balance, a.product_cd, p.product_type_cd
from account a, product p
where a.product_cd = p.product_cd;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_rows = 1;
OPEN col_cur;
select FOUND_ROWS() into num_rows;
read_loop: LOOP
IF no_more_rows THEN
CLOSE col_cur;
LEAVE read_loop;
END IF;
FETCH col_cur INTO idcust_val, balance_val, productCd_val, productType_val;
SELECT idcust_val, balance_val, productCd_val;
IF productType_val = 'ACCOUNT' THEN
IF productCd_val = 'SAV' || productCd_val = 'CD' THEN
IF balance_val < 2000 THEN
SELECT (balance_val-10) INTO balance_val;
END IF;
ELSE
SELECT (balance_val+(balance_val*0,05)) INTO balance_val;
END IF;
ELSE
SELECT (balance_val-(balance_val*0,1)) INTO balance_val;
END IF;
/*UPDATE account SET avail_balance = balance_val WHERE account_id = idcust_val;*/
END LOOP read_loop;
END $$
DELIMITER ;
please help!
Change decimal point ',' to '.'
0,05 -> 0.05
0,1 - 0.1