使用SQL Server中的存储过程打印准备输入n的素数

时间:2019-01-11 15:34:03

标签: sql sql-server

DROP PROCEDURE test
GO

CREATE PROCEDURE test
    @Number INTEGER
AS
BEGIN
    SET NOCOUNT ON

    DECLARE @i INT = 1;
    DECLARE @K INT = 1;
    DECLARE @j INT = 0;
    DECLARE @Result NVARCHAR(MAX)

    WHILE(@i <= @Number)
    BEGIN
        WHILE(@K <= @i)
        BEGIN
            IF (@K % @i = 0)
            BEGIN
                SET @j = @j + 1
            END

            SET @k = @k + 1
        END 

        SET @K = 1
        PRINT CONVERT(VARCHAR(10), @i) + 'value has j' + CONVERT(VARCHAR(10), @j)

        IF (@j = 2)
        BEGIN
            SET @Result = '' + CONVERT(VARCHAR(10), @i) + ' & ';
            SELECT @Result 
        END

        SET @j = 0;
        SET @i = @i + 1;
    END

    SET NOCOUNT OFF
END
GO      


EXEC test 15

我不明白这段代码有什么问题。输出应类似于

2&3&5&7&11&13

2 个答案:

答案 0 :(得分:2)

尝试切换此条件:

From: IF(@K % @i = 0)

To:  IF(@i % @k = 0)

更新:这将更正结果的字符串

Declare   @Number INTEGER = 90

     DECLARE @i int =1;
     DECLARE @K int =1;
     DECLARE @j int =0;
     DECLARE @Result NVARCHAR(MAX) = ''
     WHILE(@i <= @Number)
     BEGIN

           WHILE(@K <= @i)
           BEGIN
                if(@i % @k = 0)
                BEGIN
                     SET @j =@j + 1
                END
                SET @k = @k + 1
           END 
       SET @K=1
       print CONVERT(VARCHAR(10),@i)+'value has j'+CONVERT(VARCHAR(10),@j)
       if(@j = 2)
          BEGIN
               SET @Result= @Result + ''+CONVERT(VARCHAR(10),@i) + ' & ';
          END
       SET @j = 0;
       SET @i=@i+1;

     END

SELECT Left(@Result, Len(@Result)-1) As Result   

2 & 3 & 5 & 7 & 11 & 13 & 17 & 19 & 23 & 29 & 31 & 37 & 41 & 43 & 47 & 53 & 59 & 61 & 67 & 71 & 73 & 79 & 83 & 89 

答案 1 :(得分:0)

我知道这已经有了一个可以接受的答案,但是对于较大的值,嵌套循环方法将非常缓慢。另外我真的很讨厌循环。这是使用计数表和交叉联接的另一种方法。

我在系统上保留一个理货表格作为视图。

create View [dbo].[cteTally] as

WITH
    E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
    E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
    cteTally(N) AS 
    (
        SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
    )
select N from cteTally
GO

现在将其用于查找素数。不可否认,在将@NUMBER设置为200或更高之前,这并没有太大不同。实际上,对于较小的电视机,这(非常)有点慢。可以通过减小cteTally的大小来改善这一点。但是两个人甚至在200岁时就死定了,然后理货表方法真正开始将嵌套的循环吹走。仅500倍的速度几乎快一倍。对于更大的集(我尝试使用30,000倍),嵌套循环实际上在我的测试盒上用尽了内存,但计数表产生的结果虽然很慢。

Declare @Number INTEGER = 500

select t.N
from cteTally t
cross join cteTally t2
where t.N <= @Number
    and t2.N <= @Number
    and t.N <> t2.N
    and t.N % t2.N = 0
group by t.N
having count(*) = 1
order by t.N