MySQL Procedure with Cursor Parameter - mysql

I have the following code that is supposed to return a list of customers that are younger than the provided age parameter and a total count of found records.
My table consists of: columns ID, FIRST_FIRSTNAME, LASTNAME, DATE_OF_BIRTH
I could have easily made a few mistakes in the syntax, logic and formatting of this procedure but forgive me, I am new to this! The following is my sql procedure:
DELIMITER $$
DROP PROCEDURE IF EXISTS sample_procedure$$
CREATE PROCEDURE sample_procedure(IN actualinput INT)
BEGIN
DECLARE no_more_customers int(4);
DECLARE l_customer_count int(4);
DECLARE l_id varchar(1);
DECLARE l_first_name varchar(10);
DECLARE l_last_name varchar(10);
DECLARE l_date_of_birth varchar(20);
DECLARE customer_list varchar(250);
DECLARE dateinput DATE;
SET dateinput=DATE_SUB(now(), interval actualinput year);
DECLARE cid CURSOR FOR
SELECT ID, FIRST_FIRSTNAME, LAST_NAME, DATE_OF_BIRTH
FROM customers WHERE DATE_OF_BIRTH >= dateinput;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_customers=1;
SET no_more_customers=0;
SET l_customer_count=0;
OPEN cid;
cid_cursor: REPEAT
FETCH cid INTO l_id, l_first_name, l_last_name, l_date_of_birth; IF no_more_customers THEN
LEAVE cid_cursor;
END IF;
SET customer_list=concat(customer_list, l_id,',',l_first_name,',',l_last_name,',',l_date_of_birth);
SET l_customer_count=1+l_customer_count;
UNTIL no_more_customers
END REPEAT cid_cursor;
CLOSE cid;
SET no_more_customers=0;
SELECT customer_list AS Customers;
SELECT concat(l_customer_count);
END;
$$
I appear to have an error in the method I used to calculate the age of customers, possibly an issue with the method I used to call the cursor and my final list of customers is only returning null.
Thanks in advance...

I can suppose that variable 'customer_list' should be initialized, e.g. -
...
DECLARE customer_list VARCHAR(250) DEFAULT '';
...
because 'SET customer_list = CONCAT(customer_list, ...)' when customer_list is NULL, will return NULL too.
Take advantage of MySQL Stored Procedure Debugger. Hope this feature will help you.

Related

Why MySQL Cursor stopped looping while reporting a success

I created a procedure as below in MySQL workbench 8.0.12 community, win10. A cursor is declared to loop through more than 16000 member's ID in a table to insert their number of orders created in different dates into another table.
Member's IDs and their dates of registration are selected here for the cursor. select distinct BAG,AAA from DICT_ALLE_AAAF where AAA>=Date_Memb_Star. Once I call it call PRO_MIDD_MEMB_AAAA_1('2017/01/01','2019/11/10',60), it only looped through 5 member's IDs and did not report any error. But if I took the while loop out of the procedure and with select Var_BAG on, the cursor loop went selecting more than 200 member's IDs until it asked me to cancel it. Can anyone tell me what is wrong in my code? Many thanks.
delimiter //
create procedure PRO_MIDD_MEMB_AAAA_1
(in Date_Memb_Star date,
in Date_Sale_End date,
in Int_Inte int)
begin
declare Int_Floo int default 0;
declare Int_Ceil int;
declare Int_MembAll int;
declare Int_Loop int default 1;
declare Int_MaxiLoop int;
declare Int_DaySpen int default 30;
declare Int_Done int;
declare Var_BAG varchar(16);
declare Date_Memb_Regi date;
declare Cur_Memb cursor for
select distinct BAG,AAA from DICT_ALLE_AAAF where AAA>=Date_Memb_Star order by BAG;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET Int_Done = 1;
truncate table MIDD_MEMB_AAAA;
open Cur_Memb;
read_loop:loop
fetch Cur_Memb into Var_BAG,Date_Memb_Regi;
if Int_Done=1 then
leave read_loop;
end if;
/*select Var_BAG;*/
set Int_MaxiLoop=ceil(datediff(Date_Sale_End,Date_Memb_Regi)/Int_Inte);
set Int_Floo=0;
while Int_Loop<=Int_MaxiLoop do
set Int_Ceil=Int_Floo+Int_Inte;
insert into MIDD_MEMB_AAAA
select Var_BAG,Int_Floo,Int_Ceil,
count(distinct BAK)*(Int_DaySpen/Int_Inte) as Numb_Con_Avg
from OPER_SALE_AAAB
where BAG=Var_BAG
and timestampdiff(hour,Date_Memb_Regi,AAA)/24>Int_Floo
and timestampdiff(hour,Date_Memb_Regi,AAA)/24<=Int_Ceil
and AAB>0;
set Int_Floo=Int_Floo+Int_Inte;
set Int_Loop=Int_Loop+1;
end while;
end loop read_loop;
close Cur_Memb;
end//
delimiter ;
Little oversight: you forgot to reset your variable Int_Loop, so after the first run, it only enters the loop when Int_MaxiLoop has a new maximum value.
Reinitialize it (to 1, I assume) before the loop:
...
set Int_Floo=0;
set Int_Loop=1;
while Int_Loop<=Int_MaxiLoop do ...

how to read data from CURSOR - mysql stored procedure

I have implemented the CURSOR inside mysql stored procedure... I am getting challenge while reading the cursor... Basically I want to read column value from cursor & store the same into a variable.. but I am getting the variable value as NULL... What would be the solution... Please help me.. Thanks in advance...
My code is like below,
delimiter //
CREATE PROCEDURE placeOrder(IN cartId INT)
BEGIN
DECLARE countitem INT DEFAULT 0;
DECLARE productId INT;
DECLARE quantity INT;
DECLARE itemDicountAmt DOUBLE DEFAULT 0;
DECLARE v_finished INT DEFAULT 0;
DEClARE cart_cursor CURSOR FOR
SELECT ProductId, Quantity FROM TBL_SHOPPING_CART_ITEM;
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET v_finished = 1;
OPEN cart_cursor;
get_cart: LOOP
FETCH cart_cursor into productId, quantity;
IF v_finished = 1 THEN
LEAVE get_cart;
END IF;
-- build email list
insert into debugtable select concat('PRODUCT :', productId);
insert into debugtable select concat('QUANTITY :', quantity);
END LOOP get_cart;
CLOSE cart_cursor;
END//
delimiter ;
OUTPUT:
tmptable
NULL
NULL
As I am having one record in my shopping cart table...
See C.1 Restrictions on Stored Programs :: Name Conflicts within Stored Routines.
Option 1:
...
/*DEClARE cart_cursor CURSOR FOR
SELECT ProductId, Quantity FROM TBL_SHOPPING_CART_ITEM;*/
DEClARE cart_cursor CURSOR FOR
SELECT
TBL_SHOPPING_CART_ITEM.ProductId,
TBL_SHOPPING_CART_ITEM.Quantity
FROM TBL_SHOPPING_CART_ITEM;
...
Option 2:
...
/*DECLARE productId INT;
DECLARE quantity INT;*/
DECLARE _productId INT;
DECLARE _quantity INT;
...
/*FETCH cart_cursor into productId, quantity;*/
FETCH cart_cursor into _productId, _quantity;
...
/*insert into debugtable select concat('PRODUCT :', productId);
insert into debugtable select concat('QUANTITY :', quantity);*/
insert into debugtable select concat('PRODUCT :', _productId);
insert into debugtable select concat('QUANTITY :', _quantity);
...

Reading XML in a procedure for select query

I have created a procedure in which I am passing a xml type data. I am trying to read that data but it is always giving null.
delimiter //
create procedure SP_LogIn(xml text)
begin
declare AgentId varchar(30);
declare pass varchar(30);
set #AgentId=ExtractValue(#xml,'/operation/userName');
set #Pass=ExtractValue(#xml,'/operation/paasword');
select * from am_agentmasteraccount where am_AgentId=#AgentId and am_AgentPassword=#Pass;
end //
delimiter;
here I am calling the procedure
call SP_Login('<operation><userName>RAJ0560111</userName><password>rajpratha</password></operation>');
try this it would work.
delimiter //
create procedure SP_LogIn(xml text)
begin
declare AgentId varchar(30);
declare pass varchar(30);
set AgentId:=(ExtractValue(xml,'/operation/userName'));
set Pass:=(ExtractValue(xml,'/operation/password'));
select * from am_agentmasteraccount where am_AgentId=AgentId and am_AgentPassword=Pass;
select AgentId,pass;
end //
delimiter;

MySQL 5.6 Declare Issue

Let's see if I can edit this and put the whole procedure in.
I am trying to convert an Oracle database to MySQL. I have all the tables, keys, indexes, and views converted. I now need to convert a stored procedure to MySQL.
I have most of it done, and there is only one hang up on my code:
set dns1_tmp = X.X.X.X;
SET dns2_tmp = X.X.X.X;
This gives me an error of 1064 Syntax Error: Missing semicolon
I have tested the rest of my procedure, and it works fine. It creates it, runs it, and retrieves data from it, but only if I remove those two lines.
Any ideas on what I can do?
Whole stored procedure:
DELIMITER //
USE `TEST`//
DROP PROCEDURE IF EXISTS `proc_IN`//
CREATE DEFINER=`root`#`localhost` PROCEDURE `proc_IN`
(IN DNIS VARCHAR(20),
IN MSISDN VARCHAR(20),
IN AVPAIR1 VARCHAR(20),
IN AVPAIR2 VARCHAR(20),
IN GROUPID VARCHAR(20),
OUT DNS1 VARCHAR(15),
OUT DNS2 VARCHAR(15),
OUT AUTHSTAT VARCHAR(100))
BEGIN
declare dns1_tmp varchar(15);
declare dns2_tmp varchar(15);
set dns1_tmp = X.X.X.X;
SET dns2_tmp = X.X.X.X;
DECLARE avpair1_tmp varchar(15);
DECLARE avpair2_tmp varchar(15);
DECLARE grpid_tmp varchar(15);
DECLARE C_USER CURSOR FOR SELECT AVPAIR1, AVPAIR2, DNS1, DNS2, GROUPID FROM GRP, ALLMEMBER WHERE ALLMEMBER.GROUPID=GRP.GROUPID
UNION
SELECT AVPAIR1, AVPAIR2, DNS1, DNS2, GROUPID FROM GRP;
OPEN C_USER;
FETCH C_USER INTO AVPAIR1, AVPAIR2, DNS1, DNS2, GROUPID;
LOOP
FETCH C_USER INTO avpair1_tmp, avpair2_tmp, dns1_tmp, dns2_tmp, grpid_tmp;
INSERT INTO duplog VALUES(DNIS, MSISDN, avpair1_tmp, avpair2_tmp, dns1_tmp,dns2_tmp, grpid_tmp, SYSDATE);
END LOOP;
IF C_USER%ROWCOUNT > 1 THEN
INSERT INTO duplog VALUES(DNIS, MSISDN, AVPAIR1, AVPAIR2, DNS1,DNS2, GROUPID, SYSDATE);
SET AUTHSTAT := 'ok';
elseif C_USER%ROWCOUNT = 1 THEN
SET AUTHSTAT := 'ok';
ELSE
SET AUTHSTAT := NULL;
END IF;
CLOSE C_USER;
COMMIT;
END //
DELIMITER ;

MySQL Error: 1337

I'm getting this error while trying to create a procedure in MySQL:
Error Code: 1337
Variable or condition declaration after cursor or handler declaration
even after doing a lot of Googling I found no relevant solution to my problem. My procedure is as below:
DELIMITER //
CREATE PROCEDURE emp_dates(IN startDate DATE, IN endDate DATE)
BEGIN
DECLARE fromDt DATETIME;
DECLARE toDt DATETIME;
DECLARE done INT DEFAULT FALSE;
DECLARE employees CURSOR FOR SELECT empid FROM employees;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
DECLARE emp VARCHAR(20);
SET fromDt=startDate;
SET toDt=endDate;
OPEN employees;
WHILE fromDt<=toDt DO
REPEAT
FETCH employees INTO emp;
IF NOT done THEN
INSERT INTO new_attendance_2(attid,empid,dt) VALUES(DEFAULT,emp,fromDt);
END IF
UNTIL done END REPEAT;
SET fromDt=DATE_ADD(fromDt, INTERVAL 1 DAY);
LOOP
CLOSE employees;
END
DELIMITER ;
The purpose is to create a procedure which will take two dates as input and insert records in other table for every day that comes in between of those two.
Somebody please help! I appreciate any little help. Thanks a lot in advance.
It's complaining about:
Variable or condition declaration after cursor or handler declaration
So I would be looking at that location, where you do indeed declare variables after the cursor and handler:
DECLARE employees CURSOR FOR SELECT empid FROM employees;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
>> DECLARE emp VARCHAR(20);
If you modify your declarations thus, it should be okay:
DECLARE fromDt DATETIME;
DECLARE toDt DATETIME;
DECLARE done INT DEFAULT FALSE;
DECLARE emp VARCHAR(20);
DECLARE employees CURSOR FOR SELECT empid FROM employees;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
The order has to be, as per here:
Cursor declarations must appear before handler declarations and after variable and condition declarations.
You need to re-order your declarations.
Cursor declarations must appear before handler declarations
and after variable and condition declarations.
http://dev.mysql.com/doc/refman/5.1/en/cursors.html