Database 如何打印出非素数?PL/SQL

Database 如何打印出非素数?PL/SQL,database,oracle,plsql,Database,Oracle,Plsql,此代码用于打印1到30之间的非素数。它是如何工作的,错误在哪里 BEGIN <<outer>> FOR i in 1..30 <<inner>> for k in 2..i-1 loop if (mod(i, k) = 0) THEN DBMS_OUTPUT.PUT_LINE(i); exit inner

此代码用于打印1到30之间的非素数。它是如何工作的,错误在哪里

BEGIN  
    <<outer>>
    FOR i in 1..30
        <<inner>> 
        for k in 2..i-1 loop 
            if (mod(i, k) = 0) THEN 
                DBMS_OUTPUT.PUT_LINE(i);
                exit inner when (mod(i, k)= 0);
            end if;
        end loop inner
    end loop outer 
end;

我喝了杯咖啡休息一下,下面是一个纯SQL实现

with data as ( select level as n# from dual 
               connect by level <= 30 )
select distinct d1.n#
from data d1 cross join data d2
where d1.n# > d2.n#
and d2.n# != 1
and mod(d1.n#, d2.n#) = 0
order by d1.n#
虚伪?见鬼,是的


这种解决方案也有同样的低效性。这就是为什么它需要明确的定义。可能这可以通过仅在11gR2中可用的递归CTE进行优化。

该代码通过测试所有可能的候选者来工作,这意味着所有大于1且小于正在检查的数字的正整数。如果一个候选者将测试的数字除掉而没有余数,则该数字是复合的,并将被打印出来。将跳过对帽子编号的任何进一步测试。

这是一个如何工作的答案

外部循环句柄通过数字1-30


内部循环执行实际的非素数处理。因为1,2,3是素数,所以它只有在i=4之后才开始运行。对于大多数非素数,循环将在k之后结束,而显然它不起作用。当i=1时,k in 2..i-1解析为k in 2..0。还有其他的bug,但这有点代码高尔夫的味道,所以它脱离了主题。@APC:令人惊讶的是,这看起来确实有效。修复语法错误后,输出是正确的。第五步:请纠正语法仔细看你的两行,你会发现不同。那就记住,;这不仅仅是装饰。有些地方需要它们。@APC情况i=1有效,因为plsql要求第一个界限低于第二个界限才能进入循环。反转迭代顺序需要修饰符反转,如反转lo..hi LOOP…END LOOP中的k。错误在于它不打印1,根据一般的理解,1不是质数,因此应该打印。@FrankSchmitt-我要对你使用的一般理解提出质疑。我猜大多数不懂数学的人仍然认为1是素数。我同意现代数学认为这不再是事实。虚伪?既然可以用SQL来做事情,为什么还要用PL/SQL来做呢?@Colin'tHart-我同意。但我称之为伪善,因为我已经暗示这是一个代码高尔夫,而不是一个恰当的问题。愚蠢的一致性是小头脑的妖精。哦,伟大的思想家,把伪善化吧-