在线Oracle SQL Worksheet中如何获取匿名PL/SQL块的输出?
解决在线Oracle SQL Worksheet中PL/SQL输出问题及代码错误
一、先处理"Unsupported Command Statement processed"报错
在线Oracle SQL Worksheet(比如Oracle Cloud的SQL Developer Web、APEX SQL Workshop这类工具)不支持SQL*Plus专属的SET命令,你开头加的SET SERVEROUTPUT ON;会被识别为不兼容语句,直接触发报错。可以用两种方式开启DBMS输出:
方式1:在PL/SQL块内启用输出
把DBMS_OUTPUT.ENABLE();放在匿名块的BEGIN语句后,替代原来的SET命令:
declare i number:=2; j number:=0; counter number:=0; flag number; begin DBMS_OUTPUT.ENABLE(); -- 启用服务器输出 loop if (i=2) then counter:=counter+1; dbms_output.put(i ||' '); else j:=2; flag:=0; loop if(mod(i, j)=0) then flag:=1; end if; j := j + 1; -- 必须递增j,否则内层循环会无限执行 exit when (j > sqrt(i)) or flag=1; -- 优化退出条件,无需循环到i本身 end loop; if(flag=0) then counter:=counter+1; dbms_output.put(i ||' '); -- 原代码输出j是错误的,应该输出当前质数i end if; end if; i:=i+1; exit when counter=10; end loop; end; /
方式2:通过工具界面开启输出
如果用的是Oracle SQL Developer Web,执行代码前找到右侧的"DBMS Output"面板,点击"Enable"按钮开启输出,再运行PL/SQL块即可。
二、修复原代码的逻辑错误
原代码有两个关键问题,会导致程序无法正常运行或输出错误结果:
- 内层循环未递增j:只初始化了
j:=2但没有j := j + 1的语句,会触发无限循环,程序直接卡死或超时。 - 质数输出对象错误:判断i为质数后,原代码输出的是除数j,实际应该输出当前被判断的质数i。
另外我优化了内层循环的退出条件:exit when (j > sqrt(i)) or flag=1——因为如果一个数n存在大于sqrt(n)的因数,必然对应一个小于sqrt(n)的因数,循环到sqrt(n)就足够判断是否为质数,能大幅提升效率。
三、验证执行
按上述方法修改后,执行代码会输出前10个质数:2 3 5 7 11 13 17 19 23 29 。
内容的提问来源于stack exchange,提问作者Vaishnavi Killekar




