mysql - updating a table setting a column with a complex condition - mysql

I have been working on this for a while now and this seems to be too complex. What I want to do is to update a column (x) with the operation: (p * (100/c) ) / 100.
p corresponds to a value of a date x and c corresponds to a value of date x minus one day.
I tried to create a stored procedure with loop but select statement doesnt work for me in the loop statement.
Here is my procedure which update nothing :
BEGIN
DECLARE firstqDate,date2 date;
DECLARE p, c float;
DECLARE cpt, val int;
SET #val = 0;
SET #cpt = (select count(*)-1 from quotes);
WHILE (val < 3) DO
SET #firstqDate = (select qDate from quotes ORDER BY YEAR(qDate) ASC, MONTH(qDate) ASC, DAY(qDate) ASC limit 1,1);
SET date2 = (select qDate from quotes where qDate like DATE_ADD(#firstqDate, INTERVAL 1 DAY );
SET p = (select qOp from quotes where qDate like date2);
SET c = (select qCl from quotes where qDate like DATE_SUB(date2, INTERVAL val DAY));
update quotes
set qCh = (p * (100/c) ) / 100;
set val = val + 1;
end while;
END
EDIT : I did some updates to the stored procedure but still updating no lines!
BEGIN
DECLARE firstqDate,date2 date;
DECLARE p, c float;
DECLARE cpt, val int;
SET #val = 0;
SET #cpt = (select count(*)-1 from quotes);
SET firstqDate = (select qDate from quotes ORDER BY YEAR(qDate) ASC, MONTH(qDate) ASC, DAY(qDate) ASC limit 1,1);
WHILE (val < 3) DO
SET date2 = (select qDate from quotes where qDate like DATE_ADD(#firstqDate, INTERVAL val DAY ));
SET p = (select qOp from quotes where qDate like date2);
SET c = (select qCl from quotes where qDate like DATE_SUB(date2, INTERVAL val+1 DAY));
set val = val + 1;
update quotes
set qCh = (p * (100/c) ) / 100
where qOp = p AND qCl = c;
end while;
END
I did some updates again to the stored procedures but no changes. i used some functions.
BEGIN
DECLARE p, c float;
DECLARE cpt, val int;
SET #val = 0;
SET #cpt = (select count(*)-1 from quotes);
WHILE (#val < 3) DO
SET p = getp(#val, getd());
SET c = getc(#val+1, getd());
set #val = #val + 1;
update quotes
set qCh = (#p * (100/#c) ) / 100
where qOp = #p AND qCl = #c;
end while;
END
functions :
get p:
BEGIN
declare d date;
select qDate into d from quotes ORDER BY YEAR(qDate) ASC, MONTH(qDate) ASC, DAY(qDate) ASC limit 1,1;
return d;
END
get c:
BEGIN
DECLARE c float;
DECLARE qDa date;
select qDate into qDa from quotes where qDate like DATE_SUB(qD, INTERVAL v DAY );
SELECT qCl INTO c FROM quotes WHERE qDate = qDa;
RETURN c;
END
getd:
BEGIN
declare d date;
select qDate into d from quotes ORDER BY YEAR(qDate) ASC, MONTH(qDate) ASC, DAY(qDate) ASC limit 1,1;
return d;
END
this stored procedure must calculate all qCh from p of qDate and c of the qDate minus one day.
Thank you!
EDIT - Solved
Ouf! I finally managed to write this stored procedure :
BEGIN
DECLARE p, c float;
DECLARE cpt, val int;
SET #val = 0;
SET #cpt = (select count(*)-1 from quotes);
WHILE (#val <= 2) DO
SET p := getp(#val, getd());
SET c := getc(#val+1, getd());
set #val := #val + 1;
update quotes q
set q.qCh = (getp(#val, getd()) * (100/getc(#val-1, getd())) ) / 100
where q.qOp = getp(#val, getd());
end while;
END
new getC
BEGIN
DECLARE c float;
DECLARE qDa date;
select qDate into qDa from quotes where qDate like DATE_ADD(qD, INTERVAL v DAY );
SELECT qCl INTO c FROM quotes WHERE qDate = qDa;
RETURN c;
END
I changed the code of function getC to add (-1) in the first iteration. now it is working!
Thank you everyone for your help!

Your update cycle looks ok, even if i don't understand why you make 3 cycles. Shouldn't you use:
WHILE (#val < 3) DO
Instead of
WHILE (val < 3) DO
? Hope it helps
EDIT:
You need to debug your cycle to know where the problem is.
Try this:
BEGIN
DECLARE #p, #c float;
DECLARE #cpt, #val int;
SET #val = 0;
SET #cpt = (select count(*)-1 from quotes);
SELECT 'Enter Cycle';
WHILE (#val < 3) DO
SELECT 'In Cyle';
SET #p = getp(#val, getd());
SELECT #p;
SET c = getc(#val+1, getd());
set #val = #val + 1;
update quotes
set qCh = (#p * (100/#c) ) / 100
where qOp = #p AND qCl = #c;
end while;
END
Does you SP prints 'Enter Cycle' and 'In Cyle'? Does the value of p Variable prints? It is correct?

Related

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

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

Procedure not returning or modifying any rows

Below is my procedure that is not modifying any records. When I run it in peices everything works. I'm assuming I'm not using my variables correctly. Can anyone confirm? Thanks.
BEGIN
DECLARE a, b, c, d, e INT;
DECLARE cur1 CURSOR FOR SELECT a.team_id, a.league_id, a.bid, f.roster_id, f.winning_team_id FROM kl_faa f, kl_faa_audit a, faa_times t WHERE t.id = f.faa_times_id AND f.id = a.faa_id AND f.auction_end_date IS NULL AND (DATE_ADD(f.last_bid_date, INTERVAL t.hours HOUR)) <= NOW() AND a.faa_id != (SELECT MAX(ref_id) FROM kl_faa_audit WHERE faa_id = a.faa_id);
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO a, b, c, d, e;
UPDATE kl_user_league SET cash_balance = cash_balance + #c WHERE league_id = #b and team_id = #a;
END LOOP;
CLOSE cur1;
UPDATE kl_team_roster SET team_id = #e, status = 0 WHERE roster_id = #d;
UPDATE kl_faa f LEFT JOIN faa_times t ON t.id = f.faa_times_id
SET f.auction_end_date = NOW()
WHERE t.id = f.faa_times_id AND f.auction_end_date IS NULL AND (DATE_ADD(f.last_bid_date, INTERVAL t.hours HOUR)) <= NOW();
END;
END

Cursor in stored procedure of mysql not working

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 ?

Whats wrong with my Mysql trigger - Syntax error thrown

When i execute this trigger it throws error as
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'END' at line 27
delimiter //
CREATE TRIGGER `after_tblgps_insert` AFTER INSERT ON `tbl_gps`
FOR EACH ROW BEGIN
DECLARE cab_meter_new VARCHAR(10);
DECLARE cab_cost_new VARCHAR(10);
DECLARE cab_meter_old VARCHAR(10);
DECLARE cab_cost_old VARCHAR(10);
DECLARE pr_pnr_no VARCHAR(15);
DECLARE pr_dest_id VARCHAR(15);
select NEW.gps_rs232,NEW.gps_cab_bus,gps_rs232,gps_cab_bus into #cab_meter_new,#cab_cost_new,#cab_meter_old,#cab_cost_old from tbl_gps where gps_imei = NEW.gps_imei order by gps_id asc limit 0,1;
IF #cab_meter_new = 1 and #cab_meter_old = 0 THEN
BEGIN
select `booking_pnr_no` into #pr_pnr_no from tbl_booking where booking_alloted_vehicle = (select taxi_id from tbl_taxi where taxi_imei = NEW.gps_imei ) AND booking_status = 13;
select trip_dst_area_id into #pr_dest_no from tbl_trip where pnr_id = #pr_pnr_no order by trip_id desc limit 0,1;
update tbl_taxi set taxi_cur_status = 12,taxi_cur_area = #pr_dest_no where taxi_id = NEW.gps_cab_bus;
update tbl_booking set booking_status = 9 where booking_pnr_no = #pr_pnr_no;
END;
ELSE IF #cab_meter_new = 0 and #cab_meter_old = 1 THEN
BEGIN
select `booking_pnr_no` into #pr_pnr_no from tbl_booking where booking_alloted_vehicle = (select taxi_id from tbl_taxi where taxi_imei = NEW.gps_imei ) AND booking_status = 9;
select trip_dst_area_id into #pr_dest_no from tbl_trip where pnr_id = #pr_pnr_no order by trip_id desc limit 0,1;
update tbl_taxi set taxi_cur_status = 10,taxi_cur_area = #pr_dest_no where taxi_id = NEW.gps_cab_bus;
update tbl_booking set booking_status = 8 where booking_pnr_no = #pr_pnr_no;
END;
END IF
END //
delimiter ;
try this code
delimiter //
CREATE TRIGGER `after_tblgps_insert` AFTER INSERT ON `tbl_gps`
FOR EACH ROW BEGIN
DECLARE cab_meter_new VARCHAR(10);
DECLARE cab_cost_new VARCHAR(10);
DECLARE cab_meter_old VARCHAR(10);
DECLARE cab_cost_old VARCHAR(10);
DECLARE pr_pnr_no VARCHAR(15);
DECLARE pr_dest_id VARCHAR(15);
select NEW.gps_rs232,NEW.gps_cab_bus,gps_rs232,gps_cab_bus into #cab_meter_new,#cab_cost_new,#cab_meter_old,#cab_cost_old from tbl_gps where gps_imei = NEW.gps_imei order by gps_id asc limit 0,1;
IF #cab_meter_new = 1 and #cab_meter_old = 0 THEN
BEGIN
select `booking_pnr_no` into #pr_pnr_no from tbl_booking where booking_alloted_vehicle = (select taxi_id from tbl_taxi where taxi_imei = NEW.gps_imei ) AND booking_status = 13;
select trip_dst_area_id into #pr_dest_no from tbl_trip where pnr_id = #pr_pnr_no order by trip_id desc limit 0,1;
update tbl_taxi set taxi_cur_status = 12,taxi_cur_area = #pr_dest_no where taxi_id = NEW.gps_cab_bus;
update tbl_booking set booking_status = 9 where booking_pnr_no = #pr_pnr_no;
END;
END IF;
IF #cab_meter_new = 0 and #cab_meter_old = 1 THEN//break IF into separate IF
BEGIN
select `booking_pnr_no` into #pr_pnr_no from tbl_booking where booking_alloted_vehicle = (select taxi_id from tbl_taxi where taxi_imei = NEW.gps_imei ) AND booking_status = 9;
select trip_dst_area_id into #pr_dest_no from tbl_trip where pnr_id = #pr_pnr_no order by trip_id desc limit 0,1;
update tbl_taxi set taxi_cur_status = 10,taxi_cur_area = #pr_dest_no where taxi_id = NEW.gps_cab_bus;
update tbl_booking set booking_status = 8 where booking_pnr_no = #pr_pnr_no;
END;
END IF;
END; //
delimiter ;
You have misstyped semicolon after END IF.