PL/SQL Stored Procedure Cursor Tuning
Date: 20 Feb 2002 10:39:51 -0800
Message-ID: <c8d38a43.0202201039.7d295e4b_at_posting.google.com>
I've written a stored procedure (below) which will duplicate a large
amount of linked plan data. It is run only once per year from within
my Oracle development tool (Toad). When I run only a few plans (see
first cursor, cDental), it works fine. When I run a large number of
plans to duplicate, however, I get a rollback too old/segment too
small error (ORA-01555).
My question is if I'm using the cursors correctly. All the select
cursors should only grab a snapshot of the data as it was when the
stored procedure was first called (the cursor should not update based
on inserted data). I don't want to change the rollback segment size
since I'm working on a development copy of a client's database.
Any suggestions would be much appreciated!
Thanks in advance,
Heidi Huber
Internet Developer
CREATE OR REPLACE PROCEDURE duplicate_plans (
status OUT VARCHAR2)
IS
CURSOR cDental IS
SELECT PLANID,a,b,c,d,e,f,g,h,i,j FROM PLANS WHERE a IN (1,2,3,4,....); -- Number of plans can changeva NUMBER;
vb VARCHAR2(100);
vc NUMBER;
vd VARCHAR2(1024);
ve NUMBER; vf NUMBER; vg NUMBER; vh VARCHAR2(80);
vi VARCHAR2(300);
vj VARCHAR2(100);
vPlanYear VARCHAR2(20);
vOldPlanId NUMBER;
vNewPlanId NUMBER;
vOldPtoPIId NUMBER;
vNewPtoPIId NUMBER;
BEGIN
status := '0';
vPlanYear := '2002';
OPEN cDental;
LOOP
FETCH cDental INTO vOldPlanId,va,vb,vc,vd,ve,vf,vg,vh,vi,vj;
EXIT WHEN cDental%NOTFOUND;
INSERT INTO PLANS (a,b,c,d,e,f,g,h,i,j,PLANYEAR)
VALUES (va,vb,vc,vd,ve,vf,vg,vh,vi,vj,vPlanYear);
COMMIT;
SELECT SEQ_PLANID.CURRVAL INTO vNewPlanId FROM DUAL;
FOR cPCStoP1 IN (SELECT * FROM SETTINGS1 WHERE PLANID =
vOldPlanId) LOOP
INSERT INTO SETTINGS1 (a,PLANID)
VALUES (cPCStoP1.a,vNewPlanId);
COMMIT;
END LOOP;
FOR cPCStoP4 IN (SELECT * FROM SETTINGS4 WHERE PLANID =
vOldPlanId) LOOP
INSERT INTO SETTINGS4 (a,PLANID)
VALUES (cPCStoP4.a,vNewPlanId);
COMMIT;
END LOOP;
FOR cHtoP IN (SELECT * FROM HTOPLAN WHERE PLANID = vOldPlanId)
LOOP
INSERT INTO HTOPLAN (a,PLANID)
VALUES (cHtoP.a,vNewPlanId);
COMMIT;
END LOOP;
FOR cPtoPI IN (SELECT * FROM PLANITEMS WHERE PLANID =
vOldPlanId) LOOP
vOldPtoPIId := cPtoPI.PTOPI;
INSERT INTO PLANITEMS (PLANID,a)
VALUES (vNewPlanId,cPtoPI.a);
COMMIT;
SELECT SEQ_DP_TO_PI.CURRVAL INTO vNewPtoPIId FROM DUAL;
FOR cPtoPItoF IN (SELECT * FROM FOOTNOTES WHERE PTOPI =
vOldPtoPIId) LOOP
INSERT INTO FOOTNOTES (PTOPI,a)
VALUES (vNewPtoPIId,cPtoPItoF.a);
COMMIT;
END LOOP;
FOR cSettings IN (SELECT * FROM SETTINGS WHERE PTOPI =
vOldPtoPIId) LOOP
INSERT INTO SETTINGS (PTOPI,a,b)
VALUES (vNewPtoPIId,cSettings.a,cSettings.b);
COMMIT;
END LOOP;
END LOOP;
END LOOP; CLOSE cDental;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Other Exception : sqlcode ' || sqlcode
|| ' sqlerrm ' || sqlerrm);
status := '-100';
RETURN;
END;
/ Received on Wed Feb 20 2002 - 19:39:51 CET
