Mysql cursor fetches only first row and when it has fetched the second row the row_not_found variable is set to false and cursor close.
Please look into below SP:
CREATE DEFINER = 'root'#'localhost'
PROCEDURE billingv2test.SP_CreateRecurringBillingOrders(IN _billingDate DATETIME,
IN _defaultBillingFrequency INT,
IN _IsForcedExecution BIT)
BEGIN
DECLARE _userId char(36);
DECLARE _billingStartDate datetime;
DECLARE _billingEndDate datetime;
DECLARE _cmd VARCHAR(4000);
DECLARE _userBillingHistoryId char(36);
DECLARE _paymentOrderId char(36);
DECLARE _orderNumber VARCHAR(100);
DECLARE _totalChargeAmount DECIMAL(15, 6);
DECLARE _couponChargeAmount DECIMAL(15, 6);
DECLARE _pendingChargeAmount DECIMAL(15, 6);
DECLARE _isError BIT;
DECLARE _noOfUsersProcessed BIT;
DECLARE _billingResourceType VARCHAR(20);
DECLARE _RowNo INT;
DECLARE _defaultDateTime DATETIME;
DECLARE record_not_found INTEGER DEFAULT 0;
DECLARE user_list varchar(200);
DECLARE ProcessUsersForRecurringBilling_Cursor CURSOR FOR
SELECT OwnerId FROM UserBillingInfo
WHERE NextBillingDate IS NOT NULL
AND cast(NextBillingDate as date) <= cast( _billingDate as date)
AND IsProcessPending = 0
AND IsDeleted = 0
AND BillingStatus <> 'Delinquent'
ORDER BY NextBillingDate;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET record_not_found = 1;
SET _isError = 0;
SET _noOfUsersProcessed = 0;
SET _defaultDateTime = '1900-01-01 00:00:00';
SET _userBillingHistoryId = UUID();
INSERT INTO BillingHistory( Id, BillingStartTime, BillingEndTime, Status, NoOfUsersProcessed, CreateTime, UpdateTime )
VALUES ( _userBillingHistoryId, UTC_TIMESTAMP(), NULL , 'Started', 0, UTC_TIMESTAMP(), UTC_TIMESTAMP());
OPEN ProcessUsersForRecurringBilling_Cursor;
allusers: LOOP
FETCH ProcessUsersForRecurringBilling_Cursor INTO _userId;
IF record_not_found THEN
LEAVE allusers;
END IF;
SET user_list = CONCAT(IFNULL(user_list,''),", ",_userId);
SET _isError = 0;
SET _orderNumber = '';
SET _totalChargeAmount = '0';
SET _couponChargeAmount = '0';
SET _pendingChargeAmount = '0';
UPDATE UserBillingInfo SET IsProcessPending = 1 WHERE OwnerId = _userId;
SET _billingStartDate = _defaultDateTime;
SELECT
IFNULL(InvoiceDate, _defaultDateTime) INTO _billingStartDate
FROM
PaymentOrder
WHERE OwnerId = _userId AND OrderStatus IN ('Success', 'Submitted')
ORDER BY CreateTime DESC
LIMIT 1;
SELECT NextBillingDate INTO _billingEndDate FROM UserBillingInfo WHERE OwnerId = _userId;
SET _orderNumber = UUID();
SET _orderNumber = SUBSTRING(_orderNumber, 0, LOCATE('-', _orderNumber));
-- CALL SP_CreateRecurringBillingPaymentOrder
CALL SP_CreateRecurringBillingPaymentOrder
(_userId, _billingStartDate, _billingEndDate, _orderNumber, _userBillingHistoryId, _paymentOrderId);
SELECT Amount INTO _totalChargeAmount FROM PaymentOrder WHERE Id = _paymentOrderId;
SET _pendingChargeAmount = _totalChargeAmount;
UPDATE PaymentOrder set ChargeAmount = _pendingChargeAmount, UpdateTime = UTC_TIMESTAMP()
WHERE Id = _paymentOrderId;
UPDATE ResourceUsageProcessed SET BillingStatus = 'Completed'
WHERE PaymentOrderId = _paymentOrderId AND BillingStatus = 'Processing';
SET _noOfUsersProcessed = _noOfUsersProcessed + 1;
END LOOP allusers;
CLOSE ProcessUsersForRecurringBilling_Cursor;
UPDATE BillingHistory SET NoOfUsersProcessed = _noOfUsersProcessed, Status = 'Completed', BillingEndTime = UTC_TIMESTAMP()
WHERE Id = _userBillingHistoryId;
END
hey this may sound silly but try this
IF record_not_found=1 THEN
LEAVE allusers;
Related
As per the use case, this procedure should return 30 rows with 15 unique lead id's corresponding to all 15 in activity=1; randomly 10 participate in activity = 2; and from those 10, 5 leads randomly correspond to activity=3.
When I run the stored procedure, it goes on until populating 25 records; which correspond to uniquely getting 15 id's for activity=1 and 10 out of them for activity=2; but, I am unable to fetch the records right after.
If you check down in the code; I have mentioned a SELECT statement just before closing cur2 (SELECT COUNT(*) FROM task2), which should return Count=25; but it's not. So, apparently, the program isn't even going further into the cur3 which I have declared for activity=3.
I have tried using Continue Handler with cursor, too; but it didn't seem to work!
Can anyone help resolve this issue?
BEGIN
DROP TABLE IF EXISTS task2;
CREATE TABLE task2 (
ID int(11) NOT NULL AUTO_INCREMENT,
type_id int(11) DEFAULT NULL,
url varchar(100) DEFAULT NULL,
lead_id int(11) DEFAULT NULL,
createdDate datetime DEFAULT NULL,
month varchar(20) DEFAULT NULL,
year int(11) DEFAULT NULL,
month_year varchar(20) DEFAULT NULL,
PRIMARY KEY (ID)
)
BEGIN
-- INSERTING DATA FOR ACTIVITY = 1
DECLARE nurl VARCHAR(100);
DECLARE nleadid INTEGER;
DECLARE ncreateddate DATETIME;
DECLARE l_count INTEGER;
DECLARE loop_count INTEGER;
-- LOOP COUNT = 15
SET l_count = 15;
SET loop_count = 1;
read_loop:LOOP
IF loop_count > l_count THEN
LEAVE read_loop;
END IF;
IF loop_count = 1
THEN
SET nleadid = 100;
SET ncreateddate = ('2012-09-08 01:09:30');
ELSE
SET nleadid = 100 + loop_count - 1;
SET ncreateddate = (SELECT MAX(createdDate) FROM task2);
SET ncreateddate = DATE_ADD(ncreateddate, INTERVAL ELT(0.5 + RAND() * 6, '3', '5', '45', '34', '23', '68') MINUTE);
END IF;
SET nurl = ELT(0.5 + RAND() * 3, 'g.com', 'y.com', 'm.com');
INSERT INTO task2 (type_id, url, lead_id, createdDate)
VALUES ('1', nurl, nleadid, ncreateddate);
UPDATE task2
SET month = MONTHNAME(createddate), year = YEAR(createddate), month_year = CONCAT(MONTHNAME(createddate),'-', YEAR(createddate));
SET loop_count = loop_count + 1;
END LOOP read_loop;
END;
-- INSERTING THE DATA FOR ACTIVITY = 2
BEGIN
DECLARE nurl VARCHAR(100);
DECLARE nleadid INTEGER;
DECLARE ncreateddate DATETIME;
DECLARE l_count INTEGER;
DECLARE loop_count INTEGER;
-- CURSOR DECLARATION TO FETCH 10 RANDOM RECORDS FROM ACTIVITY=1
DECLARE cur2 CURSOR FOR
SELECT DISTINCT lead_id FROM task2 WHERE type_id = 1 ORDER BY RAND() LIMIT 10;
SET l_count = 10;
SET loop_count = 1;
OPEN cur2;
read_loop:LOOP
FETCH cur2 INTO nleadid;
IF loop_count > l_count THEN
SELECT loop_count_2, l_count_2;
LEAVE read_loop;
END IF;
SET nurl = ELT(0.5 + RAND() * 3, 'g.com', 'y.com', 'm.com');
SET ncreateddate = (SELECT MAX(createdDate) FROM task2 WHERE lead_id = nleadid);
SET ncreateddate = DATE_ADD(ncreateddate, INTERVAL ELT(0.5 + RAND() * 6, '3', '5', '45', '34', '23', '68') MINUTE);
INSERT INTO task2 (type_id, url, lead_id, createdDate)
VALUES ('2', nurl, nleadid, ncreateddate);
UPDATE task2
SET month = MONTHNAME(createddate), year = YEAR(createddate), month_year = CONCAT(MONTHNAME(createddate),'-', YEAR(createddate));
SET loop_count = loop_count + 1;
SELECT COUNT(*) FROM task2;
END LOOP read_loop;
SELECT COUNT(*) FROM task2;
CLOSE cur2;
END;
-- INSERTING DATA FOR ACTIVITY = 3
BEGIN
DECLARE nurl VARCHAR(100);
DECLARE nleadid INTEGER;
DECLARE ncreateddate DATETIME;
DECLARE l_count INTEGER;
DECLARE loop_count INTEGER;
-- CURSOR DECLARATION FOR SELECTING 5 RANDOM LEADS FROM ACTIVITY=2
DECLARE cur3 CURSOR FOR
SELECT DISTINCT lead_id FROM task2 WHERE type_id = 2 ORDER BY RAND() LIMIT 5;
SET l_count = 5;
SET loop_count = 1;
OPEN cur3;
read_loop:LOOP
IF loop_count > l_count THEN
LEAVE read_loop;
END IF;
FETCH cur3 INTO nleadid;
SET nurl = CONCAT(ELT(0.5 + RAND() * 3, 'g.com', 'y.com', 'm.com'), ELT(0.5 + RAND() * 3, '/home.html', '/index.html', '/about.html'));
SELECT nurl;
SET ncreateddate = (SELECT MAX(createdDate) FROM task2 WHERE lead_id = nleadid);
SET ncreateddate = DATE_ADD(ncreateddate, INTERVAL ELT(0.5 + RAND() * 6, '3', '5', '45', '34', '23', '68') MINUTE);
SELECT ncreateddate;
INSERT INTO task2 (type_id, url, lead_id, createdDate)
VALUES ('3', nurl, nleadid, ncreateddate);
UPDATE task2
SET month = MONTHNAME(createddate), year = YEAR(createddate), month_year = CONCAT(MONTHNAME(createddate),'-',YEAR(createddate));
SET loop_count =loop_count + 1;
END LOOP read_loop;
CLOSE cur3;
END;
SELECT * FROM task2;
END
This is my Stored procedure . I have problem to assign value to Declared variable . When I Execute it, Insert and Update Command work fine but VALUE of Declared Variable remain 0; But I have some value in Database. How can i Do this Corectly.
BEGIN
DECLARE PaidFee INT DEFAULT 0;
DECLARE DueFee INT DEFAULT 0;
DECLARE CourseFee INT DEFAULT 0;
INSERT INTO `creditdirectory`(`TypeID`, `PersonName`, `CreditBy`, `PersonID`, `ModeOfPayment`,`Details`,`Amount`,`CompanyID`)
VALUES(1,PersonName,CreditBy, AddmissionID, ModeOfPayment, 'Installment', PaidAmount,
CompanyID);
SELECT `CourseFee`,`PaidFee`,`DueFee` INTO CourseFee,PaidFee,DueFee FROM `studentcoursedetails` WHERE `ID`= CourseID;
SET PaidFee = PaidFee + PaidAmount;
SET DueFee = CourseFee - PaidFee;
IF (NextDueDate !='') THEN
UPDATE `studentcoursedetails` SET `PaidFee` = PaidFee, `DueFee` = DueFee, `DueDate` = NextDueDate WHERE `ID`= CourseID;
ELSE
UPDATE `studentcoursedetails` SET `PaidFee` = PaidFee, `DueFee` = DueFee, `DueDate` = NULL WHERE `ID` = CourseID;
END IF;
END
Don't use variables with same name of columns, the query will take preference on table column names.
A good idea is use variables with prefix:
BEGIN
DECLARE p_PaidFee INT DEFAULT 0;
DECLARE p_DueFee INT DEFAULT 0;
DECLARE p_CourseFee INT DEFAULT 0;
INSERT INTO `creditdirectory`(`TypeID`, `PersonName`, `CreditBy`, `PersonID`, `ModeOfPayment`,`Details`,`Amount`,`CompanyID`)
VALUES(1,PersonName,CreditBy, AddmissionID, ModeOfPayment, 'Installment', PaidAmount,
CompanyID);
SELECT `CourseFee`,`PaidFee`,`DueFee` INTO p_CourseFee,p_PaidFee,p_DueFee FROM `studentcoursedetails` WHERE `ID`= CourseID;
SET p_PaidFee = p_PaidFee + PaidAmount;
SET p_DueFee = p_CourseFee - p_PaidFee;
IF (NextDueDate !='') THEN
UPDATE `studentcoursedetails` SET `PaidFee` = p_PaidFee, `DueFee` = p_DueFee, `DueDate` = NextDueDate WHERE `ID`= CourseID;
ELSE
UPDATE `studentcoursedetails` SET `PaidFee` = p_PaidFee, `DueFee` = p_DueFee, `DueDate` = NULL WHERE `ID` = CourseID;
END IF;
END
CREATE PROCEDURE KC_update_pricing()
BEGIN
DECLARE u_sku VARCHAR(10) DEFAULT "";
DECLARE u_product_size VARCHAR(4) DEFAULT "";
DECLARE u_product_name VARCHAR(100) DEFAULT "";
DECLARE u_chargeble_area DECIMAL DEFAULT 0.0;
DECLARE u_user_id VARCHAR(10) DEFAULT "";
DECLARE u_last_update DATE;
DECLARE cur1 CURSOR FOR
SELECT
sku,
product_size,
product_name,
chargeble_area,
user_id,
last_update
FROM kcproduct_test_load
WHERE last_update >= (SELECT DATE_FORMAT(DATE_SUB(max(last_update), INTERVAL 1 DAY), '%d-%m-%Y')
FROM kcpricing_test_load);
OPEN Cur1;
LOOP
FETCH cur1
INTO u_sku, u_product_size, u_product_name, u_chargeble_area, u_user_id, u_last_update;
IF (u_product_size = 'S')
THEN
SET u_shipping = 99;
ELSEIF (u_product_size = 'M')
THEN
SET u_shipping = 149;
ELSEIF (u_product_size = 'L')
THEN
SET u_shipping = 199;
ELSEIF (u_product_size = 'XS')
THEN
SET u_shipping = 99;
ELSEIF (u_product_size = 'XXS')
THEN
SET u_shipping = 69;
ELSE
SET u_shipping = 199;
END IF;
UPDATE kcpricing_test_load
SET base_price = (u_chargeble_area * 150)
WHERE sku = u_SKU;
END LOOP;
END;
have an exception command in the cursor some thing like below :
Exception
When NO_DATA_FOUND then
continue
end;
it will help to avoid no data found error.
I have created this procedure to insert upc_id and relevent values in the table product_universal_description.
CREATE PROCEDURE veealpha
(
IN s_po_id INT(11),
IN s_supplier_id INT(11),
IN s_location_id VARCHAR(32),
IN s_warehouse_id INT(11),
IN s_user_id INT(11),
OUT message VARCHAR(64),
OUT error_code INT(4)
)
BEGIN
DECLARE temp_upc VARCHAR(32);
DECLARE i INT;
DECLARE finished INTEGER DEFAULT 0;
DECLARE loop_count int(4);
DECLARE upc varchar(32);
DECLARE p_product_id int(11);
DECLARE p_model varchar(64);
DECLARE counter_cursor CURSOR FOR
SELECT product_id,model,quantity FROM product
WHERE model in('CFB0040','CFB0042','CFB0043','CFB0044')
AND quantity > 0;
DECLARE CONTINUE HANDLER FOR 1062
SET message = 'Duplicate Keys Found';
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET finished = 1;
OPEN counter_cursor;
add_data : LOOP
FETCH counter_cursor INTO p_product_id, p_model, loop_count;
SET i = 1;
WHILE loop_count > 0 DO
CASE i
WHEN i < 10 THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-000',i);
WHEN (i >= 10 AND i < 100) THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-00',i);
WHEN (i >= 100 AND i < 1000) THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-0',i);
ELSE
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-',i);
END CASE;
INSERT INTO product_universal_description
(
`upc_id`,
`po_id`,
`supplier_id`,
`location_id`,
`warehouse_id`,
`product_id`,
`model_no`,
`added_by`,
`updated_by`,
`date_added`,
`date_modified`
) VALUES (
temp_upc,
s_po_id,
s_supplier_id,
s_location_id,
s_warehouse_id,
p_product_id,
p_model,
s_user_id,
s_user_id,
NOW(),
NOW()
);
SET i=i+1;
SET loop_count = loop_count - 1;
END WHILE;
IF finished = 1 THEN
LEAVE add_data;
END IF;
END LOOP add_data;
CLOSE counter_cursor;
END
CALL veealpha(123,45,'UP',1,56,#msg,#err);
ON Execution I getting the result like this.
How ever I have given the conditions there for UPC_ID that it should be well mannered as per case. But leaving for i = 1 FOR all it takes the ELSE condition at CASE. Can anybody tell me .. what's wrong happened and how could i get the desired result.
Try:
...
-- CASE i
CASE
WHEN i < 10 THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-000',i);
WHEN (i >= 10 AND i < 100) THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-00',i);
WHEN (i >= 100 AND i < 1000) THEN
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-0',i);
ELSE
SET temp_upc = CONCAT(s_po_id,'-','CFC','-','30','-','APR14','-',p_model,'-',i);
END CASE;
...
can anybody help me to write the following MS-SQL sp to MySQL sp,
use of this:
CREATE PROCEDURE sp_InputWork
#_DelimitedString nvarchar(MAX)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #_DataRow nvarchar(MAX)
DECLARE #_DescriptionOfWorkDone nvarchar(MAX)
DECLARE #_TemporaryStorage nvarchar(MAX)
DECLARE #_QTY int
DECLARE #_Total int
DECLARE #_CurrentField int
WHILE CHARINDEX(';', #_DelimitedString) > 0
BEGIN
SET #_DataRow = CAST(SUBSTRING(#_DelimitedString, 0, CHARINDEX(';', #_DelimitedString)) AS nvarchar(MAX))
SET #_CurrentField = 1
WHILE CHARINDEX(',', #_DataRow) > 0
BEGIN
SET #_TemporaryStorage = CAST(SUBSTRING(#_DataRow, 0, CHARINDEX(',', #_DataRow)) AS nvarchar(MAX))
IF #_CurrentField = 1
SET #_QTY = CAST(#_TemporaryStorage AS int)
IF #_CurrentField = 2
SET #_DescriptionOfWorkDone = #_TemporaryStorage
IF #_CurrentField = 3
SET #_Total = CAST(#_TemporaryStorage AS int)
SET #_DataRow = SUBSTRING(#_DataRow, CHARINDEX(',', #_DataRow) + 1, LEN(#_DataRow))
SET #_CurrentField = #_CurrentField + 1
END
INSERT INTO tblWorkDone (QTY, DescriptionOfWorkDone, Total) VALUES (#_QTY, #_DescriptionOfWorkDone, #_Total)
SET #_DelimitedString = SUBSTRING(#_DelimitedString, CHARINDEX(';', #_DelimitedString) + 1, LEN(#_DelimitedString))
END
END
I have changed the SP to Mysql
BEGIN
DECLARE _DataRow VARCHAR(21000);
DECLARE _DescriptionOfWorkDone VARCHAR(21000);
DECLARE _TemporaryStorage VARCHAR(21000) ;
DECLARE _QTY int;
DECLARE _Total int;
DECLARE _CurrentField int;
WHILE INSTR(_DelimitedString, ';') >0 DO
SET _DataRow = CAST(SUBSTRING(_DelimitedString, 1, INSTR(_DelimitedString,';' )) AS CHAR);
SET _CurrentField = 1;
WHILE INSTR(_DataRow,',' ) > 0 DO
SET _TemporaryStorage = CAST(SUBSTRING(_DataRow, 1, INSTR(_DataRow,',' )-1) AS CHAR);
IF _CurrentField = 1 then
SET _QTY = CAST(_TemporaryStorage AS UNSIGNED);
end if;
IF _CurrentField = 2 then
SET _DescriptionOfWorkDone = _TemporaryStorage;
end if;
IF _CurrentField = 3 then
SET _Total = CAST(_TemporaryStorage AS UNSIGNED) ;
end if;
SET _DataRow = SUBSTRING(_DataRow, INSTR( _DataRow,',') + 1, LENGTH(_DataRow));
SET _CurrentField = _CurrentField + 1;
END while;
INSERT INTO tblWorkDone (QTY, DescriptionOfWorkDone, Total) VALUES (_QTY, _DescriptionOfWorkDone, _Total);
SET _DelimitedString = SUBSTRING(_DelimitedString, INSTR(_DelimitedString,';' ) + 1, LENGTH(_DelimitedString));
END WHILE;END
Data inserted
CALL `sp_InputWork`('1,TEST,100,;2,TEST1,200,;3,TEST3,300,;')
Successfully looped and inserted to Mysql Table