Operand should contain 1 column(s) stored procedure - mysql

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

Related

MYSQL := is not a valid at this position, expecting an identifier

The task is create a stored procedure which creates a statistic of students by city. The result should be like - -
`
delimiter $$
create procedure courcity()
begin
declare list_stud text default '';
declare _cty varchar(50);
declare _count int;
declare _name_stud varchar(50);
declare done integer default FALSE;
declare cty_cur cursor for select cty, count(*) as count from student group by cty order by cty;
declare stud_cur cursor for select name_stud from student where cty = _cty;
declare continue handler for NOT found set done = TRUE;
create temporary table return_table(
cty varchar(50),
count_stud int,
list_stud text default ''
);
begin
declare list_stud text default '';
declare _cty varchar(50);
declare _count int;
declare _name_stud varchar(50);
declare done integer default FALSE;
declare cty_cur cursor for select cty, count(*) as count from student group by cty order by cty;
declare stud_cur cursor for select name_stud from student where cty = _cty;
open cty_cur;
open stud_cur;
read_loop: LOOP
fetch cty_cur into _cty, _count;
IF done THEN
LEAVE read_loop;
read_loop1: loop
fetch stud_cur into _name_stud;
if done then leave read_loop1;
list_stud := list_stud || _name_stud || ', ';//here is the problem
end loop;
close stud_cur;
insert into return_table values (_cty, _count, list_stud);
list_stud := '';
end loop;
close cty_cur;
select * from return_table;
end;$$
delimiter ;
`
Can't create this procedure due to this problem.Can't find mistake.
IF THEN must be closed with END IF;
https://www.mysqltutorial.org/mysql-if-statement/
IF condition THEN
statements;
END IF;
|| is definitely not correct in MySQL. on the right side of := you should have a variable or a valid expression.

mysql CURSOR - UNABLE TO ITERATE THROUGH THE RECORDS

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;
;;

splitting text data in mysql

i want to split my row something like this:
example:
id data
1 23#4#
2 2#4#5#
to be like this
id data
1 23
1 4
2 2
2 4
2 5
i have looking for this problem in stack overflow but the solution is not satisfaction me. please help me.
i try to make a store procedure in mysql, the code it's ok no error, but the result is not ok.
drop procedure if exists pecah_lokasi_sp;
create procedure pecah_lokasi_sp()
begin
DECLARE ii INT;
DECLARE ki varchar(255);
DECLARE ulang int DEFAULT 1;
DECLARE hasil varchar(255) DEFAULT '';
DECLARE selesai INT DEFAULT FALSE;
DECLARE kursor CURSOR FOR
SELECT id_iklan, lokasi_kerja_utama
FROM iklan_lowongan_tb
WHERE status = 'Aktif';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET selesai = TRUE;
DELETE FROM temp_lok_tb;
OPEN kursor;
read_loop: LOOP
FETCH kursor INTO ii, ki;
IF selesai THEN
LEAVE read_loop;
END IF;
WHILE (ulang < LENGTH(ki)) DO
IF SUBSTRING(ki, ulang, 1) <> '#' THEN
SET hasil = CONCAT(hasil, SUBSTRING(ki, ulang, 1));
ELSE
INSERT INTO temp_lok_tb (id_iklan, id_kota) VALUES(ii, hasil);
SET hasil = '';
END IF;
SET ulang = ulang+1;
END WHILE;
SET ulang = 1;
END LOOP read_loop;
CLOSE kursor;
select * from temp_lok_tb;
end;
i think i can solve my problem myself.
this is my revision code, the result is true.
drop procedure if exists pecah_lokasi_sp;
create procedure pecah_lokasi_sp()
begin
DECLARE ii INT;
DECLARE ki varchar(255);
DECLARE ulang int DEFAULT 1;
DECLARE hasil varchar(255) DEFAULT '';
DECLARE selesai INT DEFAULT FALSE;
DECLARE jmlkarakter int;
DECLARE kursor CURSOR FOR
SELECT id_iklan, lokasi_kerja_utama
FROM iklan_lowongan_tb
WHERE status = 'Aktif';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET selesai = TRUE;
DELETE FROM temp_lok_tb;
OPEN kursor;
read_loop: LOOP
FETCH kursor INTO ii, ki;
IF selesai THEN
LEAVE read_loop;
END IF;
SET jmlkarakter = LENGTH(ki) - LENGTH(REPLACE(ki, '#', '')) ;
WHILE (ulang <= jmlkarakter) DO
IF ulang = 1 THEN
INSERT INTO temp_lok_tb(id_iklan, id_kota) VALUES(ii, SUBSTRING_INDEX(ki,'#',1));
ELSE
INSERT INTO temp_lok_tb(id_iklan, id_kota) VALUES(ii, SUBSTRING_INDEX(SUBSTRING_INDEX(ki,'#', ulang),'#',-1));
END IF;
SET ulang = ulang+1;
END WHILE;
SET ulang = 1;
END LOOP read_loop;
CLOSE kursor;
select * from temp_lok_tb;
end;

Using for loop in MySql data set

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 ;

check if cursor returns anything

How can you in a procedure function in mysql check if the cursor returns anything?
Is it possible to avoid doing the IF (SELECT COUNT(*) FROM stock ... and instead check up on the _cur variable somehow?
procedure function
DELIMITER $$
DROP FUNCTION IF EXISTS `stock_first_available_id` $$
CREATE DEFINER=`dynaccount`#`localhost` FUNCTION `stock_first_available_id`(_running_total_limit INT, _product_id INT, _group_id INT) RETURNS INT
BEGIN
DECLARE _running_count INT default 0;
DECLARE _id INT;
DECLARE _current_id INT;
DECLARE _sum_count INT;
DECLARE _cur CURSOR FOR SELECT id, count FROM stock WHERE group_id=_group_id && type=2 && product_id=_product_id ORDER BY time DESC, id DESC;
IF (SELECT COUNT(*) FROM stock WHERE group_id=_group_id && type=2 && product_id=_product_id) = 0 THEN
RETURN 0;
END IF;
OPEN _cur;
read_loop: LOOP
FETCH _cur INTO _id, _sum_count;
SET _running_count = _running_count + _sum_count;
SET _current_id = _id;
IF _running_count > _running_total_limit THEN
LEAVE read_loop;
END IF;
END LOOP read_loop;
CLOSE _cur;
RETURN _current_id;
END $$
DELIMITER ;
Add a continue handler to your cursor. See exanples from MySQL documentation.
http://dev.mysql.com/doc/refman/5.0/en/cursors.html