SQL笔记--游标/游标嵌套

注意点:
1. While..Bgein之间不可以写要执行的代码,否则会一直执行等待。要放在Begin..End内部。
2. IF ( @@error > 0 )事务执行错误判断放在Begin…End语句块中,因为Begin是Begin Transition,在外部提交或回滚事务检查不到事务。
3. 游标嵌套,内部游标完成处理后要Close和DEALLOCATE

DECLARE @o_bmb03 NVARCHAR(40) ,
    @ima01 NVARCHAR(40) ,
    @o_bmb02 INT ,
    @o_sortOrder INT ,
    @tempCnt INT ,
    @newBmb02 INT ,
    @newid CHAR(32) ,
    @tempbmb02 INT ,
    @tempsortorder INT ,
    @newima01 CHAR(32) ,
    @newbmb03 CHAR(32) ,
    @o_maxbmb02 INT ,
    @o_maxsortorder INT;

SET @ima01 = '904026947';

DECLARE newBmb03 CURSOR
FOR
    SELECT  new.ID ,
            new.LX_IMA01 ,
            new.LX_BMB02 ,
            new.bmb03
    FROM    ( SELECT    b.ID ,
                        a.LX_IMA01 ,
                        b.LX_BMB02 ,
                        b.SORT_ORDER ,
                        c.LX_IMA01 bmb03
              FROM      innovator.PART a
                        JOIN innovator.PART_BOM b ON b.SOURCE_ID = a.ID
                        JOIN innovator.PART c ON c.ID = b.RELATED_ID
              WHERE     a.LX_IMA01 = @ima01
                        AND a.IS_CURRENT = 1
            ) AS new
            LEFT JOIN ( SELECT  b.ID ,
                                a.LX_IMA01 ,
                                b.LX_BMB02 ,
                                b.SORT_ORDER ,
                                c.LX_IMA01 bmb03
                        FROM    innovator.PART a
                                JOIN innovator.PART_BOM b ON b.SOURCE_ID = a.ID
                                JOIN innovator.PART c ON c.ID = b.RELATED_ID
                        WHERE   a.LX_IMA01 = @ima01
                                AND a.GENERATION = ( SELECT MAX(GENERATION)
                                                     FROM   innovator.PART
                                                     WHERE  PART.LX_IMA01 = @ima01
                                                            AND PART.STATE = 'Released'
                                                   )
                      ) AS old ON new.LX_IMA01 = old.LX_IMA01
                                  AND new.bmb03 = old.bmb03
    WHERE   old.bmb03 IS NULL;
SELECT  @tempbmb02 = MAX(y.LX_BMB02)
FROM    innovator.PART x
        JOIN innovator.PART_BOM y ON y.SOURCE_ID = x.ID
        JOIN innovator.PART z ON z.ID = y.RELATED_ID
WHERE   x.LX_IMA01 = @ima01
        AND x.IS_CURRENT = 1;
SELECT  @tempsortorder = MAX(y.SORT_ORDER)
FROM    innovator.PART x
        JOIN innovator.PART_BOM y ON y.SOURCE_ID = x.ID
        JOIN innovator.PART z ON z.ID = y.RELATED_ID
WHERE   x.LX_IMA01 = @ima01
        AND x.IS_CURRENT = 1;
SELECT  @o_maxbmb02 = MAX(y.LX_BMB02)
FROM    innovator.PART x
        JOIN innovator.PART_BOM y ON y.SOURCE_ID = x.ID
        JOIN innovator.PART z ON z.ID = y.RELATED_ID
WHERE   x.LX_IMA01 = @ima01
        AND x.GENERATION = ( SELECT MAX(GENERATION)
                             FROM   innovator.PART
                             WHERE  PART.LX_IMA01 = @ima01
                                    AND PART.STATE = 'Released'
                           );
SELECT  @o_maxsortorder = MAX(y.SORT_ORDER)
FROM    innovator.PART x
        JOIN innovator.PART_BOM y ON y.SOURCE_ID = x.ID
        JOIN innovator.PART z ON z.ID = y.RELATED_ID
WHERE   x.LX_IMA01 = @ima01
        AND x.GENERATION = ( SELECT MAX(GENERATION)
                             FROM   innovator.PART
                             WHERE  PART.LX_IMA01 = @ima01
                                    AND PART.STATE = 'Released'
                           );

SELECT  @tempbmb02 ,
        @tempsortorder;
OPEN newBmb03;
FETCH NEXT FROM newBmb03 INTO @newid, @newima01, @newBmb02, @newbmb03;
WHILE @@FETCH_STATUS = 0
    BEGIN 
        IF @newBmb02 <= @o_maxbmb02 --新增的下阶料项次应该>上一版本
            BEGIN
                SET @tempbmb02 = @tempbmb02 + 10;
                SET @tempsortorder = @tempsortorder + 10;
                UPDATE  innovator.PART_BOM
                SET     LX_BMB02 = @tempbmb02 ,
                        SORT_ORDER = @tempsortorder
                WHERE   ID = @newid;
                /*SELECT  @newima01 ,
                        @newbmb03 ,
                        @tempbmb02 ,
                        @tempsortorder ,
                        @newBmb02 ,
                        LX_BMB02 ,
                        SORT_ORDER
                FROM    innovator.PART_BOM
                WHERE   ID = @newid;*/
                IF ( @@error > 0 )
                    BEGIN
                        ROLLBACK TRANSACTION;
                        PRINT 0;
                        RETURN;
                    END;
                ELSE
                    BEGIN
                        COMMIT TRANSACTION;
                        PRINT 1;
                        RETURN;
                    END;
            END; 
        FETCH NEXT FROM newBmb03 INTO @newid, @newima01, @newBmb02, @newbmb03;;
    END;
CLOSE newBmb03;
DEALLOCATE newBmb03;
--相同下阶料处理
DECLARE myCusor CURSOR
FOR
    SELECT  c.LX_IMA01 ,
            b.LX_BMB02 ,
            b.SORT_ORDER
    FROM    innovator.PART a
            JOIN innovator.PART_BOM b ON b.SOURCE_ID = a.ID
            JOIN innovator.PART c ON c.ID = b.RELATED_ID
    WHERE   a.LX_IMA01 = @ima01
            --AND a.IS_CURRENT = 1 --a.id='5A7EC9E0C9C84F27BCF7987BFC4ED2F8'
            AND a.GENERATION = ( SELECT MAX(GENERATION)
                                 FROM   innovator.PART
                                 WHERE  PART.LX_IMA01 = @ima01
                                        AND PART.STATE = 'Released'
                               )
    ORDER BY b.SORT_ORDER;
OPEN myCusor;
FETCH NEXT FROM myCusor INTO @o_bmb03, @o_bmb02, @o_sortOrder;
WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @tempCnt = 0;
        SELECT  @tempCnt = COUNT(1)
        FROM    innovator.PART a
                JOIN innovator.PART_BOM b ON b.SOURCE_ID = a.ID
                JOIN innovator.PART c ON c.ID = b.RELATED_ID
        WHERE   a.LX_IMA01 = @ima01  --'4664EA0EA2744D5F909F6927C6AF7BA0'
                AND a.IS_CURRENT = 1    --a.GENERATION = (SELECT MAX(GENERATION) FROM innovator.PART WHERE part.LX_IMA01=@ima01 AND part.STATE='Released')
                AND c.LX_IMA01 = @o_bmb03
                AND ( b.LX_BMB02 <> @o_bmb02
                      OR b.SORT_ORDER <> @o_sortOrder
                    );
        IF @tempCnt > 0 --下阶料相同,项次/排序不同时,纠正为上一版本的项次/排序
            BEGIN
                PRINT @tempCnt;
                /*SELECT  @tempCnt ,
                        c.LX_IMA01 ,
                        b.LX_BMB02 ,
                        @o_bmb02 ,
                        b.SORT_ORDER ,
                        @o_sortOrder
                FROM    innovator.PART_BOM b
                        JOIN innovator.PART a ON b.SOURCE_ID = a.ID
                        JOIN innovator.PART c ON c.ID = b.RELATED_ID
                WHERE   a.LX_IMA01 = @ima01  --'4664EA0EA2744D5F909F6927C6AF7BA0'
                        AND a.IS_CURRENT = 1
                        AND c.LX_IMA01 = @o_bmb03;*/

                UPDATE  b
                SET     b.LX_BMB02 = @o_bmb02 ,
                        b.SORT_ORDER = @o_sortOrder
                FROM    innovator.PART_BOM b
                        JOIN innovator.PART a ON b.SOURCE_ID = a.ID
                        JOIN innovator.PART c ON c.ID = b.RELATED_ID
                WHERE   a.LX_IMA01 = @ima01  --'4664EA0EA2744D5F909F6927C6AF7BA0'
                        AND a.IS_CURRENT = 1
                        AND c.LX_IMA01 = @o_bmb03;
                IF ( @@error > 0 )
                    BEGIN
                        ROLLBACK TRANSACTION;
                        PRINT 0;
                        RETURN;
                    END;
                ELSE
                    BEGIN
                        COMMIT TRANSACTION;
                        PRINT 1;
                        RETURN;
                    END;
            END;
        FETCH NEXT FROM myCusor INTO @o_bmb03, @o_bmb02, @o_sortOrder;
    END;
CLOSE myCusor;
DEALLOCATE myCusor;

BEGIN TRAN;
UPDATE  innovator.PART
SET     SORT_ORDER_MAX = ( SELECT   MAX(y.SORT_ORDER)
                           FROM     innovator.PART x
                                    JOIN innovator.PART_BOM y ON y.SOURCE_ID = x.ID
                                    JOIN innovator.PART z ON z.ID = y.RELATED_ID
                           WHERE    x.LX_IMA01 = '904026947'
                                    AND x.IS_CURRENT = 1
                         ) ,
        LX_BMB02_MAX = ( SELECT MAX(y.LX_BMB02)
                         FROM   innovator.PART x
                                JOIN innovator.PART_BOM y ON y.SOURCE_ID = x.ID
                                JOIN innovator.PART z ON z.ID = y.RELATED_ID
                         WHERE  x.LX_IMA01 = '904026947'
                                AND x.IS_CURRENT = 1
                       )
WHERE   PART.LX_IMA01 = '904026947'
        AND PART.IS_CURRENT = 1;
IF ( @@error > 0 )
    BEGIN
        ROLLBACK TRANSACTION;
        PRINT 0;
        RETURN;
    END;
ELSE
    BEGIN
        COMMIT TRANSACTION;
        PRINT 1;
        RETURN;
    END;

猜你喜欢

转载自blog.csdn.net/wanglui1990/article/details/79622636
今日推荐