如何根据某些条件在 MSSQL 游标中跳过一行(迭代)?

Posted

技术标签:

【中文标题】如何根据某些条件在 MSSQL 游标中跳过一行(迭代)?【英文标题】:How Can I Skip a row(an iteration) in MSSQL Cursor based on some condition? 【发布时间】:2014-03-10 07:14:58 【问题描述】:

如何根据某些条件跳过 MSSQL 游标中的一行(迭代),我有一个迁移数千条记录的 DTS,并且根据某些条件,某些记录不需要迁移,因为它们是重复的并且想要跳过这些记录。

知道如何在 MSSQL 游标中完成此操作吗?

【问题讨论】:

【参考方案1】:

我想最简单的方法是在游标内写 IF 语句。如果条件为假,您将跳过记录。

 DECLARE @ID INT
 DECLARE Curs CURSOR FAST_FORWARD
 DECLARE @Cnt INT

 CREATE TABLE ##Duplicates (ID INT, CarColor VARCHAR (50) )

 FOR
        SELECT DISTINCT  CarID
        FROM    dbo.CarPark
        WHERE   CarColour <> 'red'
        ORDER BY CarID

    OPEN Curs

        FETCH NEXT FROM Curs INTO @ID

        WHILE @@FETCH_STATUS = 0

    BEGIN

             INSERT INTO  ##Duplicates
             SELECT CarID, CarColor
             FROM  dbo.CarPark          
             WHERE ID = @ID;

             SET @Cnt = (SELECT Count(*) FROM ##Duplicates WHERE ID = @ID) ;

             IF @Cnt < 2 
             THEN /* Migrate */
             ELSE PRINT 'Duplicate'
             END

        FETCH NEXT FROM Curs INTO @ID 

        END

    CLOSE Curs
    DEALLOCATE Curs;

【讨论】:

【参考方案2】:

我在这里做了一些假设,但您可以使用以下内容作为指导:

    -- create some test data        
    SELECT '                                  ' [Word] INTO #MyTempDataset;
    INSERT INTO #MyTempDataset SELECT 'This';
    INSERT INTO #MyTempDataset SELECT 'is';
    INSERT INTO #MyTempDataset SELECT 'a';
    INSERT INTO #MyTempDataset SELECT 'basic';
    INSERT INTO #MyTempDataset SELECT 'basic';
    INSERT INTO #MyTempDataset SELECT 'test';

    DECLARE @counter INT
    DECLARE @word VARCHAR(50)
    DECLARE myCursor CURSOR
        FOR SELECT  *
            FROM    #MyTempDataset;
        OPEN myCursor
        FETCH NEXT FROM myCursor INTO @word
        WHILE @@FETCH_STATUS = 0
        BEGIN               
            -- check for condition
            SELECT  @counter = Count(*) 
            FROM    #MyTempDataset
            WHERE   word = @word

            IF @counter =1
            BEGIN
                -- process the unique records
                PRINT @word     
            END     

            FETCH NEXT FROM myCursor INTO @word
        END
        CLOSE myCursor;
        DEALLOCATE myCursor;

    DROP TABLE #MyTempDataset;

【讨论】:

@Almazini 抱歉,我在发布我的代码后才看到您的代码。 感谢您在 IF 后添加“BEGIN”和“END” :)【参考方案3】:

我知道现在回答这个问题为时已晚,但对于未来的求职者来说。我相信处理这个问题的正确方法在MSDN中描述

您的代码正在使用 WHILE 循环 (WHILE @@FETCH_STATUS = 0)

要正确退出 while 循环,请使用 BREAK 关键字

要跳过循环中的迭代,请使用 CONTINUE 关键字

来自 MSDN:

休息 导致从最里面的 WHILE 循环退出。出现在 END 关键字之后的任何语句,标记循环的结束,都会被执行。

继续 导致 WHILE 循环重新启动,忽略 CONTINUE 关键字之后的任何语句。

示例: -- 声明并打开游标后...

FETCH NEXT FROM Curs INTO @ID    
WHILE @@FETCH_STATUS = 0    
BEGIN 
-- do something
IF [condition to skip record] 
CONTINUE            

FETCH NEXT FROM Curs INTO @ID 
  END

【讨论】:

迄今为止最好的答案!【参考方案4】:

我知道现在回答这个问题为时已晚。但是为了其他用户寻求更好的答案。您可以通过调用FETCH NEXT 来跳过记录。

WHILE @@FETCH_STATUS = 0

IF @ParameterName = '@RETURN_VALUE' 
    FETCH NEXT FROM @procSchema INTO @ParameterName, @Type;

   .... Rest of the logic goes here

使用这种方法,您不必将整个逻辑包装在 If 语句中,而是会跳过当前记录移动到下一条记录。

【讨论】:

以上是关于如何根据某些条件在 MSSQL 游标中跳过一行(迭代)?的主要内容,如果未能解决你的问题,请参考以下文章

在 Q Promises 中跳过 then 函数的正确方法

如何从sql中跳过一行?

在 Fortran90 中从文本文件中跳过一行

Python 3.2 在 csv.DictReader 中跳过一行

在 keycloak 中跳过 kerberos sso 身份验证

在 Maven 中跳过某些模块中的测试