sasi242
October 29th, 2004, 12:24 AM
Hi All
I have two tables
1.purchase
2.sold
i have written pl/sql code to restart the fifo-first in first out match where i found a mistake in the existing data.here operator has enterd a wrong data.i.e.,it can be rate or quantity in any of the two tables.so can this code be tuned and reduce the number of cursors.
purchase table
SNO P_SCODE DOP PQTY RATE VALUEQTY SOLD
1 ATL 01-SEP-04 100 15.75 1575
2 BPL 02-SEP-04 800 20.00 16000
3 ATL 04-SEP-04 500 17.00 8500
4 ATL 06-SEP-04 750 20.00 15000
5 BPL 07-SEP-04 250 15.00 3750
6 ATL 07-SEP-04 100 15.00 1500
7 ATL 08-SEP-04 250 16.00 4000
8 BPL 09-SEP-04 300 17.00 5100
SOLD TABLE
SNO S_SCODE DOS S_QTY RATE VALUE COSTPROFIT
1 ATL 02-SEP-04 50 16.00 800
2 ATL 06-SEP-04 500 15.00 7500
3 ATL 08-SEP-04 300 20.00 6000
4 BPL 07-SEP-04 300 25.00 7500
5 ATL 10-SEP-04 100 15.00 1500
6 ATL 08-SEP-04 250 16.00 4000
7 BPL 10-SEP-04 1000 18.00 18000
8 ATL 11-SEP-04 400 20.00 8000
CREATE OR REPLACE PROCEDURE my_shares
( new_code IN VARCHAR2,
type IN VARCHAR2,
sno IN NUMBER,
new_qty IN NUMBER,
new_rate IN NUMBER)
IS
ls_qty NUMBER:=0;
ls_rate NUMBER:=0;
lcost_price NUMBER:=0;
lp_qty NUMBER:=0;
lqty_sold NUMBER:=0;
lp_rate NUMBER:=0;
lprofit NUMBER:=0;
lvalue NUMBER:=0;
sum_pur NUMBER:=0;
sum_sale NUMBER:=0;
error_row NUMBER:=0;
before_qty NUMBER:=0;
s_error NUMBER:=0;
p_error NUMBER:=0;
temp NUMBER:=0;
before_cp NUMBER:=0;
new_svalue NUMBER:=0;
old_rate NUMBER:=0;
cannot_sell EXCEPTION;
wrong_code EXCEPTION;
/*FETCHES SALES RECORD FROM THE EFFECTED SALE ROW*/
CURSOR sales IS
SELECT * FROM s_shares WHERE s_no>=s_error AND s_code=new_code ORDER BY s_date;
s1 sales%ROWTYPE;
/*FETCHES PURCHASE RECORD FROM THE EFFECTED PURCHASE ROW*/
CURSOR purchase IS
SELECT * FROM p_shares
WHERE p_code=s1.s_code AND p_qty-qty_sold> 0 AND p_no>=p_error ORDER BY p_date;
p1 purchase%ROWTYPE;
/*FETCHES ALL RECORDS ORDER BY SHARECODE*/
CURSOR sales_rec IS
SELECT * FROM s_shares WHERE s_code = new_code ORDER BY s_code, s_date;
s2 sales%ROWTYPE;
/*FETCHES PURCHASE RECORDS OF SAME SHARECODE FETCHED BY SALES_REC*/
CURSOR purchase_rec IS
SELECT * FROM p_shares WHERE p_code = new_code ORDER BY p_code, p_date;
p2 purchase%ROWTYPE;
BEGIN
/* IF ERRORTABLE IS SALE THEN THIS LOOP EXECUTES*/
IF
type='S' THEN
/*GIVES SUM OF SALE QTY BEFORE ERROR ROW*/
SELECT SUM(s_qty) INTO sum_sale FROM s_shares WHERE s_no < sno AND s_code = new_code;
UPDATE s_shares SET cost_price = 0,profit=0 WHERE s_no >= sno AND s_code = new_code;
OPEN purchase_rec;
LOOP
FETCH purchase_rec INTO p2;
EXIT WHEN purchase_rec%NOTFOUND;
sum_pur := sum_pur + p2.p_qty; /*SUM OF PUR RECORDS BEFORE ERROR ROW*/
before_qty := sum_pur-sum_sale;
IF
before_qty < 0
THEN
error_row := p2.p_no+1; /*EFFECTED PURCHASE ROW FOR SALE UPDATE*/
lqty_sold := sum_sale - sum_pur;/*MATCHED SOLD QTY*/
ELSE
UPDATE p_shares SET qty_sold=0 WHERE p_no=p2.p_no;
END IF;
END LOOP;
CLOSE purchase_rec;
new_svalue:=new_qty*new_rate;
UPDATE s_shares SET s_qty=new_qty , s_rate=new_rate ,s_value=new_svalue WHERE s_no=sno;
UPDATE p_shares SET qty_sold=lqty_sold WHERE p_no=error_row;
s_error := sno; /*LIMIT FOR CURSOR SALES*/
p_error := error_row; /*LIMIT FOR CURSOR PURCHASE*/
/* IF ERRORTABLE IS PURCHASE THEN THIS LOOP EXECUTES*/
ELSIF
type='P' THEN
/*SUM OF PURCHASE QTY OF ALL ROWS ABOVE ERROR ROW*/
SELECT SUM(p_qty) INTO sum_pur FROM p_shares WHERE p_no < sno AND p_code = new_code;
UPDATE p_shares SET qty_sold = 0 WHERE p_no >= sno AND P_code = new_code;
UPDATE p_shares SET p_value = new_qty*new_rate WHERE p_no = sno;
SELECT p_rate INTO old_rate FROM p_shares WHERE p_no=sno;
OPEN sales_rec;
LOOP
FETCH sales_rec INTO S2;
sum_sale := sum_sale + s2.s_qty;
before_qty := sum_sale - sum_pur; /*BEFORE SALE QTY*/
error_row := s2.s_no; /*EFFECTED SALE ROW FOR PURCHASE UPDATE*/
EXIT WHEN before_qty > 0 ; /*EXITS FROM LOOP WHEN EFFECTED ROW FOUND*/
END LOOP;
before_cp:=s2.cost_price - (before_qty*old_rate);
CLOSE sales_rec;
UPDATE s_shares SET cost_price = 0,profit=0 WHERE s_no > sno AND s_code=new_code;
UPDATE s_shares SET cost_price = before_cp WHERE s_no=error_row;
UPDATE p_shares SET p_qty=new_qty,p_rate=new_rate WHERE p_no=sno;
p_error := sno; /*LIMIT FOR CURSOR PURCHASE*/
s_error := error_row; /*LIMIT FOR CURSOR SALES*/
temp:=1;
ELSE RAISE wrong_code;
END IF;
OPEN sales;
LOOP
FETCH sales INTO s1;
EXIT WHEN sales%NOTFOUND;
IF
temp = 0 THEN ls_qty:=s1.s_qty;
ELSE
ls_qty:=before_qty;
END IF;
ls_rate:=s1.s_rate;
lvalue:=s1.s_value;
lcost_price:=s1.cost_price;
OPEN purchase;
LOOP
FETCH purchase INTO p1;
IF
purchase%NOTFOUND THEN
RAISE cannot_sell;
ELSE
lp_qty:=p1.p_qty;
lp_rate:=p1.p_rate;
lqty_sold:=p1.qty_sold;
IF
ls_qty > (lp_qty-lqty_sold) THEN
lcost_price:=lcost_price+(lp_qty-lqty_sold)*lp_rate;
lprofit:=lvalue-lcost_price;
UPDATE p_shares SET qty_sold=lp_qty WHERE p_no=p1.p_no AND p_code=p1.p_code;
UPDATE s_shares SET cost_price=lcost_price,profit=lprofit WHERE s_no=s1.s_no AND s_code=s1.s_code;
ls_qty:=ls_qty-(lp_qty-lqty_sold);
ELSE
lqty_sold:=lqty_sold+ls_qty;
lcost_price:=lcost_price + (ls_qty*lp_rate);
lprofit:=lvalue-lcost_price;
UPDATE p_shares SET qty_sold=lqty_sold WHERE p_no=p1.p_no AND p_code=p1.p_code;
UPDATE s_shares SET cost_price=lcost_price ,profit=lprofit WHERE s_no=s1.s_no AND s_code=s1.s_code;
ls_qty:=0;
temp:=0;
END IF;
IF
ls_qty=0
THEN
CLOSE purchase;
EXIT;
END IF;
END IF;
END LOOP;
END LOOP;
CLOSE sales;
EXCEPTION
WHEN cannot_sell THEN RAISE_APPLICATION_ERROR(-20001,'CANNOT SELL SHARE FOR NOT PURCHASED');
WHEN wrong_code THEN RAISE_APPLICATION_ERROR(-20002,'ENTER P OR S');
END;
Thanks in Advance
Sasidhar.
Regards
Sasidhar
I have two tables
1.purchase
2.sold
i have written pl/sql code to restart the fifo-first in first out match where i found a mistake in the existing data.here operator has enterd a wrong data.i.e.,it can be rate or quantity in any of the two tables.so can this code be tuned and reduce the number of cursors.
purchase table
SNO P_SCODE DOP PQTY RATE VALUEQTY SOLD
1 ATL 01-SEP-04 100 15.75 1575
2 BPL 02-SEP-04 800 20.00 16000
3 ATL 04-SEP-04 500 17.00 8500
4 ATL 06-SEP-04 750 20.00 15000
5 BPL 07-SEP-04 250 15.00 3750
6 ATL 07-SEP-04 100 15.00 1500
7 ATL 08-SEP-04 250 16.00 4000
8 BPL 09-SEP-04 300 17.00 5100
SOLD TABLE
SNO S_SCODE DOS S_QTY RATE VALUE COSTPROFIT
1 ATL 02-SEP-04 50 16.00 800
2 ATL 06-SEP-04 500 15.00 7500
3 ATL 08-SEP-04 300 20.00 6000
4 BPL 07-SEP-04 300 25.00 7500
5 ATL 10-SEP-04 100 15.00 1500
6 ATL 08-SEP-04 250 16.00 4000
7 BPL 10-SEP-04 1000 18.00 18000
8 ATL 11-SEP-04 400 20.00 8000
CREATE OR REPLACE PROCEDURE my_shares
( new_code IN VARCHAR2,
type IN VARCHAR2,
sno IN NUMBER,
new_qty IN NUMBER,
new_rate IN NUMBER)
IS
ls_qty NUMBER:=0;
ls_rate NUMBER:=0;
lcost_price NUMBER:=0;
lp_qty NUMBER:=0;
lqty_sold NUMBER:=0;
lp_rate NUMBER:=0;
lprofit NUMBER:=0;
lvalue NUMBER:=0;
sum_pur NUMBER:=0;
sum_sale NUMBER:=0;
error_row NUMBER:=0;
before_qty NUMBER:=0;
s_error NUMBER:=0;
p_error NUMBER:=0;
temp NUMBER:=0;
before_cp NUMBER:=0;
new_svalue NUMBER:=0;
old_rate NUMBER:=0;
cannot_sell EXCEPTION;
wrong_code EXCEPTION;
/*FETCHES SALES RECORD FROM THE EFFECTED SALE ROW*/
CURSOR sales IS
SELECT * FROM s_shares WHERE s_no>=s_error AND s_code=new_code ORDER BY s_date;
s1 sales%ROWTYPE;
/*FETCHES PURCHASE RECORD FROM THE EFFECTED PURCHASE ROW*/
CURSOR purchase IS
SELECT * FROM p_shares
WHERE p_code=s1.s_code AND p_qty-qty_sold> 0 AND p_no>=p_error ORDER BY p_date;
p1 purchase%ROWTYPE;
/*FETCHES ALL RECORDS ORDER BY SHARECODE*/
CURSOR sales_rec IS
SELECT * FROM s_shares WHERE s_code = new_code ORDER BY s_code, s_date;
s2 sales%ROWTYPE;
/*FETCHES PURCHASE RECORDS OF SAME SHARECODE FETCHED BY SALES_REC*/
CURSOR purchase_rec IS
SELECT * FROM p_shares WHERE p_code = new_code ORDER BY p_code, p_date;
p2 purchase%ROWTYPE;
BEGIN
/* IF ERRORTABLE IS SALE THEN THIS LOOP EXECUTES*/
IF
type='S' THEN
/*GIVES SUM OF SALE QTY BEFORE ERROR ROW*/
SELECT SUM(s_qty) INTO sum_sale FROM s_shares WHERE s_no < sno AND s_code = new_code;
UPDATE s_shares SET cost_price = 0,profit=0 WHERE s_no >= sno AND s_code = new_code;
OPEN purchase_rec;
LOOP
FETCH purchase_rec INTO p2;
EXIT WHEN purchase_rec%NOTFOUND;
sum_pur := sum_pur + p2.p_qty; /*SUM OF PUR RECORDS BEFORE ERROR ROW*/
before_qty := sum_pur-sum_sale;
IF
before_qty < 0
THEN
error_row := p2.p_no+1; /*EFFECTED PURCHASE ROW FOR SALE UPDATE*/
lqty_sold := sum_sale - sum_pur;/*MATCHED SOLD QTY*/
ELSE
UPDATE p_shares SET qty_sold=0 WHERE p_no=p2.p_no;
END IF;
END LOOP;
CLOSE purchase_rec;
new_svalue:=new_qty*new_rate;
UPDATE s_shares SET s_qty=new_qty , s_rate=new_rate ,s_value=new_svalue WHERE s_no=sno;
UPDATE p_shares SET qty_sold=lqty_sold WHERE p_no=error_row;
s_error := sno; /*LIMIT FOR CURSOR SALES*/
p_error := error_row; /*LIMIT FOR CURSOR PURCHASE*/
/* IF ERRORTABLE IS PURCHASE THEN THIS LOOP EXECUTES*/
ELSIF
type='P' THEN
/*SUM OF PURCHASE QTY OF ALL ROWS ABOVE ERROR ROW*/
SELECT SUM(p_qty) INTO sum_pur FROM p_shares WHERE p_no < sno AND p_code = new_code;
UPDATE p_shares SET qty_sold = 0 WHERE p_no >= sno AND P_code = new_code;
UPDATE p_shares SET p_value = new_qty*new_rate WHERE p_no = sno;
SELECT p_rate INTO old_rate FROM p_shares WHERE p_no=sno;
OPEN sales_rec;
LOOP
FETCH sales_rec INTO S2;
sum_sale := sum_sale + s2.s_qty;
before_qty := sum_sale - sum_pur; /*BEFORE SALE QTY*/
error_row := s2.s_no; /*EFFECTED SALE ROW FOR PURCHASE UPDATE*/
EXIT WHEN before_qty > 0 ; /*EXITS FROM LOOP WHEN EFFECTED ROW FOUND*/
END LOOP;
before_cp:=s2.cost_price - (before_qty*old_rate);
CLOSE sales_rec;
UPDATE s_shares SET cost_price = 0,profit=0 WHERE s_no > sno AND s_code=new_code;
UPDATE s_shares SET cost_price = before_cp WHERE s_no=error_row;
UPDATE p_shares SET p_qty=new_qty,p_rate=new_rate WHERE p_no=sno;
p_error := sno; /*LIMIT FOR CURSOR PURCHASE*/
s_error := error_row; /*LIMIT FOR CURSOR SALES*/
temp:=1;
ELSE RAISE wrong_code;
END IF;
OPEN sales;
LOOP
FETCH sales INTO s1;
EXIT WHEN sales%NOTFOUND;
IF
temp = 0 THEN ls_qty:=s1.s_qty;
ELSE
ls_qty:=before_qty;
END IF;
ls_rate:=s1.s_rate;
lvalue:=s1.s_value;
lcost_price:=s1.cost_price;
OPEN purchase;
LOOP
FETCH purchase INTO p1;
IF
purchase%NOTFOUND THEN
RAISE cannot_sell;
ELSE
lp_qty:=p1.p_qty;
lp_rate:=p1.p_rate;
lqty_sold:=p1.qty_sold;
IF
ls_qty > (lp_qty-lqty_sold) THEN
lcost_price:=lcost_price+(lp_qty-lqty_sold)*lp_rate;
lprofit:=lvalue-lcost_price;
UPDATE p_shares SET qty_sold=lp_qty WHERE p_no=p1.p_no AND p_code=p1.p_code;
UPDATE s_shares SET cost_price=lcost_price,profit=lprofit WHERE s_no=s1.s_no AND s_code=s1.s_code;
ls_qty:=ls_qty-(lp_qty-lqty_sold);
ELSE
lqty_sold:=lqty_sold+ls_qty;
lcost_price:=lcost_price + (ls_qty*lp_rate);
lprofit:=lvalue-lcost_price;
UPDATE p_shares SET qty_sold=lqty_sold WHERE p_no=p1.p_no AND p_code=p1.p_code;
UPDATE s_shares SET cost_price=lcost_price ,profit=lprofit WHERE s_no=s1.s_no AND s_code=s1.s_code;
ls_qty:=0;
temp:=0;
END IF;
IF
ls_qty=0
THEN
CLOSE purchase;
EXIT;
END IF;
END IF;
END LOOP;
END LOOP;
CLOSE sales;
EXCEPTION
WHEN cannot_sell THEN RAISE_APPLICATION_ERROR(-20001,'CANNOT SELL SHARE FOR NOT PURCHASED');
WHEN wrong_code THEN RAISE_APPLICATION_ERROR(-20002,'ENTER P OR S');
END;
Thanks in Advance
Sasidhar.
Regards
Sasidhar