Aleksej有一个很好的答案使用隐式游标尽可能 - 隐式游标自动关闭,简洁易读。对于您的示例,隐式游标是推荐的方法。
我会在这里添加一些额外的例子,符合etsa的回答 只是为您的原始文章中使用显式光标的替代品。
如果你想停止循环,你需要在你的LOOP
退出条件。 明确您可以在您的计数器达到特定值时退出,或者CURSOR已被取消或您喜欢的任何其他条件退出。
实施例1与显式游标 - 退出循环当光标运行的数据:
创建测试表:
CREATE TABLE MY_TABLE(MY_TABLE_DATA NUMBER);
并加载:
INSERT INTO MY_TABLE SELECT ROWNUM FROM ALL_OBJECTS WHERE ROWNUM < 100;
然后创建你的程序:
CREATE OR REPLACE PROCEDURE TEST_PROD IS
QUERY_STR VARCHAR2(200);
I INTEGER := 0;
TYPE CUR IS REF CURSOR;
V_MY_TABLE_DATA MY_TABLE%ROWTYPE;
MY_CUR CUR;
BEGIN
QUERY_STR := 'SELECT * FROM MY_TABLE WHERE ROWNUM<=5';
OPEN MY_CUR FOR QUERY_STR;
DBMS_OUTPUT.PUT_LINE('START');
LOOP
FETCH MY_CUR INTO V_MY_TABLE_DATA;
EXIT WHEN MY_CUR%NOTFOUND;
I := I + 1;
DBMS_OUTPUT.PUT_LINE('I: ' || I);
DBMS_OUTPUT.PUT_LINE('MY-TABLE-DATA: ' || V_MY_TABLE_DATA.MY_TABLE_DATA);
END LOOP;
DBMS_OUTPUT.PUT_LINE('COUNT: ' || I);
CLOSE MY_CUR;
END;
/
和尝试:
BEGIN
TEST_PROD();
END;
/
START
I: 1
MY-TABLE-DATA: 1
I: 2
MY-TABLE-DATA: 2
I: 3
MY-TABLE-DATA: 3
I: 4
MY-TABLE-DATA: 4
I: 5
MY-TABLE-DATA: 5
COUNT: 5
或者,你可以停止循环基于I
:
CREATE OR REPLACE PROCEDURE TEST_PROD IS
QUERY_STR VARCHAR2(200);
I INTEGER := 0;
TYPE CUR IS REF CURSOR;
V_MY_TABLE_DATA MY_TABLE%ROWTYPE;
MY_CUR CUR;
BEGIN
QUERY_STR := 'SELECT * FROM MY_TABLE WHERE ROWNUM<=10';
OPEN MY_CUR FOR QUERY_STR;
DBMS_OUTPUT.PUT_LINE('START');
LOOP
IF I >= 3 THEN
EXIT;
END IF;
FETCH MY_CUR INTO V_MY_TABLE_DATA;
I := I + 1;
DBMS_OUTPUT.PUT_LINE('I: ' || I);
DBMS_OUTPUT.PUT_LINE('MY-TABLE-DATA: ' || V_MY_TABLE_DATA.MY_TABLE_DATA);
END LOOP;
DBMS_OUTPUT.PUT_LINE('COUNT: ' || I);
CLOSE MY_CUR;
END;
/
BEGIN
TEST_PROD();
END;
/
START
I: 1
MY-TABLE-DATA: 661
I: 2
MY-TABLE-DATA: 662
I: 3
MY-TABLE-DATA: 663
COUNT: 3
你的循环没有结束条件。我无法想象它是如何停在3014。我猜测你想用光标做点什么。这通常就是为什么设立这样一个循环。 –
btw你不需要'TYPE cur IS REF CURSOR;'因为Oracle已经提供'sys_refcursor'。 –