Cursor in stored procedure of mysql not working - mysql

I am using following stored procedure and calling a cursor inside it but it is returning me zero data fetched or processed what is wrong in the procedure ?
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_ProcessData`(
DummyDate datetime
)
BEGIN
DECLARE MONTH BIGINT;
DECLARE YEAR BIGINT;
declare LBrCode VARCHAR(100);
declare EntryDate datetime;
declare VcrAcctId char(32);
declare DrCr VARCHAR(100);
declare FcyTrnAmt VARCHAR(100);
DECLARE CustName char(50);
DECLARE CreditAmount decimal(18,2);
DECLARE DebitAmount decimal(18,2);
DECLARE BatchCd char(15);
DECLARE SetNo BIGINT;
DECLARE ScrollNo BIGINT;
DECLARE BookType char(10);
DECLARE ActualAcctId varchar(50);
DECLARE ActualBrCode varchar(50);
DECLARE ActualBookType varchar(50);
declare curProcessAMLData cursor
for
select distinct * from DummyTable
WHERE EntryDate = DummyDate
AND (ActualBookType = 'XX');
open curProcessAMLData;
fetch next from curProcessAMLData into LBrCode,EntryDate,VcrAcctId,DrCr,FcyTrnAmt,BatchCd,SetNo,ScrollNo,BookType,ActualAcctId,ActualBrCode,ActualBookType;
while fetch_status = 0
DO
SET MONTH = MONTH(DummyDate);
SET YEAR = MONTH(DummyDate);
IF(DrCr = 'C')
THEN
SET CreditAmount = FcyTrnAmt;
IF NOT EXISTS (SELECT * FROM Master WHERE BranchCode = ActualBrCode AND AccNo = ActualAcctId AND TransMonth = MONTH and TransYear = YEAR)
THEN
INSERT INTO Master
(
TransDate,
BranchCode,
AccNo,
Credit,
TransMonth,
TransYear
)
SELECT
EntryDate,
ActualBrCode,
ActualAcctId,
CreditAmount,
MONTH,
YEAR
END;
ELSE
UPDATE Master
SET Credit = IFNULL(Credit,0) + CreditAmount
WHERE BranchCode = ActualBrCode AND AccNo = ActualAcctId
AND MONTH(TransDate) = MONTH
AND YEAR(TransDate) = YEAR;
END IF;
ELSE
SET DebitAmount = FcyTrnAmt;
IF NOT EXISTS (SELECT * FROM Master WHERE BranchCode = ActualBrCode AND AccNo = ActualAcctId AND TransMonth = MONTH and TransYear = YEAR)
THEN
INSERT INTO Master
(
TransDate,
BranchCode,
AccNo,
Debit,
TransMonth,
TransYear
)
SELECT
EntryDate,
ActualBrCode,
ActualAcctId,
DebitAmount,
MONTH,
YEAR
END;
ELSE
UPDATE Master
SET Debit = IFNULL(Debit,0) + DebitAmount
WHERE BranchCode = #ActualBrCode AND AccNo = ActualAcctId
AND MONTH(TransDate) = MONTH
AND YEAR(TransDate) = YEAR;
END IF;
END IF;
SET FcyTrnAmt = 0 ;
END WHILE;
fetch next from curProcessAMLData
into LBrCode,EntryDate,VcrAcctId,DrCr,FcyTrnAmt,BatchCd,SetNo,ScrollNo,BookType,ActualAcctId,ActualBrCode,ActualBookType;
CLOSE curProcessAMLData;
END
What changes will i have to make to make it working ?

Related

Insert multiple entries into table using procedure in MySQL

I have created a procedure in mysql to insert into table as below.
DELIMITER $$
CREATE PROCEDURE createOrderPR ( IN iv_productID INT,
IN iv_orderDate DATE,
IN iv_orderTime TIME,
IN iv_shopID INT,
IN iv_mobileNo varchar(10),
IN iv_quantity smallint,
IN iv_total float(10,2),
IN iv_discount float(10,2),
IN iv_taxable float(10,2),
IN iv_CGST float(10,2),
IN iv_SGST float(10,2)
)
BEGIN
DECLARE availQty smallint default 0;
SELECT stockCount INTO availQty FROM product WHERE productID = iv_productID;
SET availQty = availQty - iv_quantity;
start transaction;
set autocommit =0;
INSERT INTO orders(orderNo,productID,orderDate,orderTime,shopID,mobileNo,quantity,total,discount,taxable,CGST,SGST,orderStatus,deletionMark)
VALUES( null,iv_productID,iv_orderDate,iv_orderTime,iv_shopID,iv_mobileNo,iv_quantity,iv_total,iv_discount,iv_taxable,iv_CGST,iv_SGST,'Open',null);
UPDATE product SET stockCount = availQty WHERE productID = iv_productID;
COMMIT;
SELECT MAX(orderNo) FROM orders WHERE shopID = shopID AND mobileNo = mobileNo;
END
$$
Currently it will only allow single record.now I need to insert multiple records in that case how to define the IN parameter of the procedure. Please suggest.
Solved the issue by using the JSON IN parameter these are the sample code (Note:new column added in the table rest all no change)
DELIMITER $$
CREATE PROCEDURE createOrderMulti ( IN orderJson JSON,
IN length INT )
BEGIN
-- Date Declaration
DECLARE availQty smallint default 0;
DECLARE iv_productID INT;
DECLARE iv_orderDate DATE;
DECLARE iv_orderTime TIME;
DECLARE iv_shopID INT;
DECLARE iv_mobileNo varchar(10);
DECLARE iv_quantity smallint;
DECLARE iv_total float(10,2);
DECLARE iv_discount float(10,2);
DECLARE iv_taxable float(10,2);
DECLARE iv_CGST float(10,2);
DECLARE iv_SGST float(10,2);
DECLARE counter smallint default 0;
DECLARE item INT;
DECLARE orderNo INT DEFAULT null;
start transaction;
set autocommit = 0;
WHILE counter < length DO
-- Extract the JSON value
SELECT JSON_VALUE(orderJson, CONCAT('$[', counter, '].productID')) INTO iv_productID;
SELECT JSON_VALUE(orderJson, CONCAT('$[', counter, '].orderDate')) INTO iv_orderDate;
SELECT JSON_VALUE(orderJson, CONCAT('$[', counter, '].orderTime')) INTO iv_orderTime;
SELECT JSON_VALUE(orderJson, CONCAT('$[', counter, '].shopID')) INTO iv_shopID;
SELECT JSON_VALUE(orderJson, CONCAT('$[', counter, '].mobileNo')) INTO iv_mobileNo;
SELECT JSON_VALUE(orderJson, CONCAT('$[', counter, '].quantity')) INTO iv_quantity;
SELECT JSON_VALUE(orderJson, CONCAT('$[', counter, '].total')) INTO iv_total;
SELECT JSON_VALUE(orderJson, CONCAT('$[', counter, '].discount')) INTO iv_discount;
SELECT JSON_VALUE(orderJson, CONCAT('$[', counter, '].taxable')) INTO iv_taxable;
SELECT JSON_VALUE(orderJson, CONCAT('$[', counter, '].CGST')) INTO iv_CGST;
SELECT JSON_VALUE(orderJson, CONCAT('$[', counter, '].SGST')) INTO iv_SGST;
SELECT stockCount INTO availQty FROM product WHERE productID = iv_productID;
SET availQty = availQty - iv_quantity;
SET item = counter + 1;
INSERT INTO orders(orderNo,item,productID,orderDate,orderTime,shopID,mobileNo,quantity,total,discount,taxable,CGST,SGST,orderStatus,deletionMark)
VALUES( orderNo,item,iv_productID,iv_orderDate,iv_orderTime,iv_shopID,iv_mobileNo,iv_quantity,iv_total,iv_discount,iv_taxable,iv_CGST,iv_SGST,'Open',null);
SET orderNo = LAST_INSERT_ID();
UPDATE product SET stockCount = availQty WHERE productID = iv_productID;
SET counter = counter + 1;
END WHILE;
COMMIT;
--SELECT MAX(orderNo) FROM orders WHERE shopID = shopID AND mobileNo = mobileNo;
SELECT orderNo as orderNo;
END
$$

MySQL stores procedure cannot add values

DELIMITER $$
CREATE PROCEDURE GetCustomerLevel(p_barcode int)
BEGIN
DECLARE q1 int;
DECLARE q2 int;
DECLARE q3 int;
DECLARE total int;
SET total :=0;
SELECT sum(adjustment_quantity) INTO q1 FROM adjustment_inventory WHERE item_barcode = p_barcode group by adjustment_quantity;
SELECT sum(opening_stock) INTO q2 FROM openingstock
WHERE item_barcode = p_barcode group by opening_stock;
SELECT sum(inwardquantity) INTO q3
FROM inwardmaster WHERE item_barcode = p_barcode group by inwardquantity;
IF q1 IS NULL THEN
SET q1 := 0;
END IF;
IF q2 IS NULL THEN
SET q2 := 0;
END IF;
IF q3 IS NULL THEN
SET q3 := 0;
END IF;
SELECT q1;
SELECT q2;
SELECT q3;
SELECT q1+q2+q3;
END$$
It's return wrong answer everytime. For example q1=100 q2=200 q3=100 its return 100
you dont need to use stored procedure for this
set #barcode = '1234';
select
coalesce((
SELECT sum(coalesce(adjustment_quantity,0))
FROM adjustment_inventory
WHERE item_barcode = #p_barcode
),0) +
coalesce((
SELECT sum(opening_stock)
FROM openingstock
WHERE item_barcode = #p_barcode
), 0) +
coalesce((
SELECT
sum(coalesce(inwardquantity,0))
FROM inwardmaster WHERE item_barcode = #p_barcode
), 0) res
From Dual
;
If you really want to use procedure then check the code below
DELIMITER $$
CREATE PROCEDURE GetCustomerLevel(p_barcode int)
BEGIN
DECLARE q1 int;
DECLARE q2 int;
DECLARE q3 int;
DECLARE total int;
SET total :=0;
SELECT coalesce(sum(adjustment_quantity), 0) INTO q1 FROM adjustment_inventory WHERE item_barcode = p_barcode;
SELECT coalesce(sum(opening_stock), 0) INTO q2 FROM openingstockWHERE item_barcode = p_barcode;
SELECT coalesce(sum(inwardquantity), 0) INTO q3 FROM inwardmaster WHERE item_barcode = p_barcode;
SELECT q1;
SELECT q2;
SELECT q3;
set total = q1+q2+q3;
SELECT total;
END$$

stored procedure returns null value

i am making a stored procedure to give cashback based on the total transactions by a single person a month but when called it shows null value for cashback get
CREATE DEFINER=`root`#`localhost` PROCEDURE `stored_procedure_cashback`(IN a INT, IN b INT)
BEGIN
DECLARE cashback_get INT;
DECLARE total INT;
SELECT customers.`id_customers`, customers.`customers_name`, MONTH(transaction.`transaction_date`) AS month,
YEAR(transaction.`transaction_date`) AS year,
SUM((transaction_detail.`ammount`*transaction_detail.`price_per_piece`)-transaction_detail.`discount`) AS total,
cashback_get
FROM transaction_detail
INNER JOIN transaction ON transaction_detail.`id_transaction`=transaction.`id_transaction`
INNER JOIN customers ON transaction.`id_customers`=customers.`id_customers`
WHERE MONTH(transaction.`transaction_date`) = a AND YEAR(transaction.`transaction_date`) = b
GROUP BY customers.`id_customers`;
IF (total >= 20000) THEN
SET cashback_get = 2000;
ELSE
SET cashback_get = 0;
END IF;
You mised to put the result as OUT parameter.
CREATE DEFINER=`root`#`localhost` PROCEDURE.
`stored_procedure_cashback`(IN a INT, IN b INT, OUT cashback_get INT)
BEGIN
DECLARE total INT;
SELECT Sum( etc etc) into total
From table
etc etc
IF total >= 20000 Then
SET cashback_get = 2000;
ELSE
SET cashback_get = 0;
END IF;
END;

Loop based on parameter value

I need to create a temporary table that is populated based on two parameters:
declare #Start date = '01/01/2015'
declare #End date = '12/31/2015'
The temporary table should have a column that will capture YYYYMM for all the years and month that are between #Start and #End parameter.
Here's what I have so far. I want to stop it at 201412 and then start again at 201501. Instead, this loop keeps going in increment of plus 1 (I do not want to see 201413..so on):
declare #Start date = '01/01/2014'
declare #End date = '12/31/2015'
declare #monthstart as int
declare #monthend as int
declare #increment as int
set #monthstart = (SELECT LEFT(CONVERT(varchar, #Start,112),6))
set #monthend = (SELECT LEFT(CONVERT(varchar, #End,112),6))
create table #datetemp (RelevantYYYYMM int)
insert into #datetemp values (#monthstart)
set #increment = #monthstart
While #increment < #monthend
BEGIN
set #increment = (select Max(RelevantYYYYMM) + 1 from #datetemp)
insert into #datetemp values (#increment)
set #increment = (select Max(RelevantYYYYMM) from #datetemp)
IF (select Max(RelevantYYYYMM) from #datetemp) > #monthend
Break
else
continue
END
select * from #datetemp
You can use tally table and avoid loop:
CREATE TABLE #datetemp (RelevantYYYYMM INT);
DECLARE #Start DATE = '01/01/2015', #End DATE = '12/31/2015';
WITH tally_table AS
(
SELECT TOP 1000 rn = ROW_NUMBER() OVER(ORDER BY name) - 1
FROM master..spt_values
)
INSERT INTO #datetemp(RelevantYYYYMM)
SELECT LEFT(CONVERT(varchar, DATEADD(month, rn, #Start),112),6)
FROM tally_table
WHERE YEAR(DATEADD(month, rn, #Start)) <= YEAR(#End)
AND MONTH(DATEADD(month, rn, #Start)) <= MONTH(#End)
SELECT *
FROM #datetemp;
LiveDemo

In MySQL stored procedure getting output 1 in count and if I am executing only query then I am getting output 0

SELECT COUNT(id) INTO student_count FROM student_info WHERE roll_no=roll_no and division_id = division_id and institute_id=institute_id and academic_year_id = academic_year;
I am getting student_count = 1
when I am trying to execute stored procedure.
When I am executing direct query as below:
SELECT COUNT(*) AS c FROM student_info WHERE division_id=9 AND institute_id=1 and academic_year_id =11 and roll_no='12617690';
I am getting result 0 which is right. My procedure is:
**CREATE DEFINER = 'root'#'localhost'
PROCEDURE smart_school.create_student(IN academic_year int(11),IN standard_id int(11),IN division_id int(11),IN student_user_id int(11),IN gr_no VARCHAR(20),IN roll_no VARCHAR(50),IN institute_id INT(11),IN maker_id INT(11),OUT create_student_result varchar(20))
BEGIN
DECLARE student_id int;
DECLARE student_count int;
DECLARE semester varchar(10);
DECLARE exit handler for sqlexception
BEGIN
SET create_student_result = "failure";
SELECT #create_student_result;
ROLLBACK;
END;
IF NOT EXISTS (select id from role_user where user_id = student_user_id and role_id = 3 and institute_id=institute_id limit 0,1) THEN
BEGIN
select COUNT(id) INTO student_count from student_info WHERE roll_no=roll_no and division_id = division_id and institute_id=institute_id and academic_year_id = academic_year;
if student_count < 1 then
BEGIN
START TRANSACTION;
insert into student (is_active,user_id,maker_id,caste_id,category_id,created_at,updated_at) values ('1',student_user_id,maker_id,1,1,NOW(),NOW());
SET student_id = LAST_INSERT_ID();
select semester_id into semester from division where institute_id=institute_id and standard_id=standard_id limit 0,1;
insert into student_info (roll_no,is_active,institute_id,student_id,standard_id,semester_id,division_id,academic_year_id,maker_id,created_at,updated_at) values (roll_no,'1',institute_id,student_id,standard_id,semester,division_id,academic_year,maker_id,now(),now());
insert into institute_student (is_active,gr_no,institute_id,student_id,admission_standard_id,admission_year_id,created_at,updated_at) values ('1',gr_no,institute_id,student_id,standard_id,academic_year,now(),now());
insert into role_user (user_id,role_id,institute_id,is_active,joining_date,created_at) values (student_user_id,3,institute_id,'1',now(),now());
COMMIT;
SET create_student_result = "success";
SELECT #create_student_result;
END;
ELSE
BEGIN
SET create_student_result = "duplicate_rollno";
SELECT #create_student_result;
END;
END IF;
END;
ELSE
BEGIN
SET create_student_result = "already_exists";
SELECT #create_student_result;
END;
END IF;
END**