BEGIN sys.DBMS_OUTPUT.disable (); FOR rec IN (SELECT * FROM all_source) LOOP sys.DBMS_OUTPUT.put_line ('See you later!'); END LOOP; END; /and provided the following explanation: "A cursor FOR loop will never be an infinite loop, because a query can never return an infinite number of rows."
Ah, naive Steven! Ah, Steven of the limited understanding of SQL and all of its "tricks"!
Several players wrote to say that while the choice correctly identifies a query that will always return a finite number of rows, it is, in fact, possible to craft a query that returns an unlimited number of rows. They offered these examples:
BEGIN FOR c IN ( SELECT dummy FROM DUAL CONNECT BY LEVEL > 0) LOOP DBMS_LOCK (sleep (1)); END LOOP; END; / BEGIN FOR c IN (SELECT * FROM ( SELECT LEVEL FROM DUAL CONNECT BY LEVEL < LEVEL + 1)) LOOP DBMS_LOCK (sleep (1)); END LOOP; END; /Thanks for bringing this to my attention. I will change the answer text to reflect this "nuance" of SQL.
SQL "tricks" aren't the only way to create cursors that return an infinite number of rows; referencing a pipelined table function that never terminates could also produce this undesirable result.
ReplyDeleteJust curious:
ReplyDeleteThe following line of both the examples provided in this post is invalid right?
DBMS_LOCK (sleep (1));
Did they mean
DBMS_LOCK.sleep (1);
?
Or is there a new feature of calling packaged procs enclosed in () instead of . ?