I wrote a simple cursor in SQL like below.Here i am expecting that it will fetch all the rows from test and as per the row count,hard coded values will be added in test2 table.
DECLARE
CURSOR customers is
SELECT * FROM test;
BEGIN
OPEN customers;
LOOP
insert into test2 values (2, 3, 3);
END LOOP;
CLOSE customers;
END;
/
When I am executing it in sql prompt,it's running indefinitely. What am I doing wrong here?
答案 0 :(得分:3)
You can use FOR LOOP
:
DECLARE
CURSOR customers IS
SELECT * FROM test;
BEGIN
FOR i IN customers
LOOP
insert into test2 values (2, 3, 3);
END LOOP;
END;
/
or you need to add EXIT CONDITION
becuase your loop is (indefinite):
DECLARE
CURSOR customers is
SELECT * FROM test;
l_customer customers%ROWTYPE;
BEGIN
OPEN customers;
LOOP
FETCH customers INTO l_customer;
EXIT WHEN customers%NOTFOUND;
insert into test2 values (2, 3, 3);
END LOOP;
CLOSE customers;
END;
/
EDIT:
As Lalit Kumar B mentioned in the comment, you can use:
BEGIN
FOR i IN (SELECT * FROM test)
LOOP
insert into test2 values (2, 3, 3);
END LOOP;
END;
For more info read Working with Cursors by Steven Feuerstein
答案 1 :(得分:3)
I would rather avoid using an explicit cursor and use a cursor for loop.
BEGIN
FOR i IN
(SELECT * FROM test
)
LOOP
<do something>
INSERT INTO test2 VALUES ...;
END LOOP;
END;
/
Remember, a loop would do the insert row-by-row a.k.a. slow-by-slow.
As @Boneist mentioned, there is a reason why the cursor for loop
is better over the explicit cursor. In the recent Oracle versions, it is optimized in a better way by doing a bulk collect limit 100
internally.
But, it's not just about bulk collecting, we are dealing with the operations we would subsequently do on the array that we have fetched incrementally. We could further improve the performance by using FORALL statement along with BULK COLLECT.
IMO, the best would be do it in pure SQL using INSERT INTO table SELECT..
. There are lot of other factors, but it wouldn't be in the scope of OP's question.
答案 2 :(得分:2)
I think the way your using cursors is not correct. In below i have edited your code.. And you need to add exit condition for terminating loop.
DECLARE
CURSOR customers is
SELECT * FROM test;
cus2 customers%rowtype;
BEGIN
OPEN customers;
LOOP
FETCH customers INTO cus2;
EXIT WHEN customers%NOTFOUND;
insert into test2 values (2, 3, 3);
END LOOP;
CLOSE customers;
END;
/
Modify the above block based on your requirement.