Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server sqlserver中的递归循环_Sql Server_Recursion_Business Intelligence - Fatal编程技术网

Sql server sqlserver中的递归循环

Sql server sqlserver中的递归循环,sql-server,recursion,business-intelligence,Sql Server,Recursion,Business Intelligence,我有一张叫做WarehouseStore.dws6.BeScheduleItem的桌子。 下面是WarehouseStore.dws6.BeScheduleItem中的数据截图。 我的要求是根据以下条件从WarehouseStore.dws6.BeScheduleItem表中查找缺少的节点 将所有isMissing设置为0 如果子字段具有IcpUid字段,则字段不为NULL,并且 父项的IcpUid字段为空 然后将子父项IsMissing设置为1 如果子字段具有IcpUid字段NULL,则 父

我有一张叫做WarehouseStore.dws6.BeScheduleItem的桌子。 下面是WarehouseStore.dws6.BeScheduleItem中的数据截图。

我的要求是根据以下条件从WarehouseStore.dws6.BeScheduleItem表中查找缺少的节点

  • 将所有isMissing设置为0

  • 如果子字段具有IcpUid字段,则字段不为NULL,并且 父项的IcpUid字段为空 然后将子父项IsMissing设置为1

  • 如果子字段具有IcpUid字段NULL,则 父项的IcpUid字段为NULL,父项的子项的IsMissing等于1 然后将子父项IsMissing设置为1

  • 重复步骤3,直到没有更多要更新的内容

  • 我能够在我的SQL代码中满足步骤1到3,但不能满足步骤4,因为我需要执行for循环来检查是否没有更多的更新。 下面是我的SQL代码

    你能不能给我一个主意,如何从上面的代码构建一个递归循环。 请注意:需要循环第3步,当前数据可能不需要循环,但我们正在为所有情况编码,而不仅仅是当前数据


    光标时使用
    。光标示例:

    DECLARE@code VARCHAR(50)
    声明的db_游标
    选择
    密码
    来自WarehouseStore.dws6.BeScheduleItem
    其中IsDeleted=0

    opendb\u光标
    从db_光标提取下一个到@code

    
    而@@FETCH\u STATUS=0
    开始

    更新。。。
    内部连接。。。P对P.Code=@Code
    其中C.IcpUid不为NULL
    P.IcpUid为空

    FETCH NEXT FROM db_cursor to@name
    结束
    关闭db\u光标
    取消分配db_光标

    这就是我要找的代码

    DECLARE@TMP表
    (
    代码varchar(40),
    名称varchar(120),
    级别int,
    父代码varchar(40),
    IcpUid varchar(32),
    IsMIssing钻头
    );
    声明@NumCount INT=0;
    插入@TMP
    选择
    密码
    名称
    数量
    父代码,
    IcpUid,
    伊斯米辛
    来自WarehouseStore.dws6.BeScheduleItem
    其中isdeleted=0
    名称与“%DELETED%”不同;
    --步骤2
    使用合并到@TMP TGT(
    选择不同的
    P.代码,
    IsMissing=1
    来自@TMP C
    内部连接@TMP ON P.Code=C.ParentCode
    其中C.IcpUid不为NULL
    P.IcpUid为空
    )SRC
    关于TGT.Code=SRC.Code
    匹配后,更新集TGT.IsMissing=SRC.IsMissing;
    --步骤3
    SET@NumCount=(选择计数(不同的P.Code)
    来自@TMP C
    内部连接@TMP on P.Code=C.ParentCode
    其中C.IcpUid为空
    P.IcpUid为空
    C.IsMIssing=1
    和C.IsMissing P.IsMissing);
    而(@NumCount>0)
    开始
    --环路
    使用合并到@TMP TGT(
    选择不同的
    P.代码,
    IsMissing=1
    来自@TMP C
    内部连接@TMP ON P.Code=C.ParentCode
    其中C.IcpUid为空
    P.IcpUid为空
    C.IsMIssing=1
    和C.IsMissing P.IsMissing
    )SRC
    关于TGT.Code=SRC.Code
    匹配后,更新集TGT.IsMissing=SRC.IsMissing;
    SET@NumCount=(选择计数(不同的P.Code)
    来自@TMP C
    内部连接@TMP on P.Code=C.ParentCode
    其中C.IcpUid为空
    P.IcpUid为空
    C.IsMIssing=1
    和C.IsMissing P.IsMissing);
    结束-结束循环
    挑选*
    来自@TMP C
    其中IsMissing=1
    逐级排序;
    
    DECLARE @TEMP TABLE (
    Code NVARCHAR(MAX) NOT NULL,
    Name NVARCHAR(MAX) NULL,
    Level INT NULL,
    IsMissing BIT NULL,
    ParentCode NVARCHAR(MAX) NULL,
    IcpUid NVARCHAR(MAX) NULL
    );
    
    INSERT INTO @TEMP(
    Code,
    Name,
    Level,
    IsMissing ,
    ParentCode ,
    IcpUid 
    )
    SELECT 
    Code,
    Name,
    Level,
    IsMissing = 0,
    ParentCode, 
    IcpUid
    FROM WarehouseStore.dws6.BeScheduleItem 
    WHERE IsDeleted = 0
    ;
    
    UPDATE P SET IsMissing = 1
    FROM @TEMP C
    INNER JOIN @TEMP P ON P.Code = C.ParentCode
    WHERE C.IcpUid IS NOT NULL 
    AND P.IcpUid IS NULL
    ;
    SELECT 
    P.Code,
    P.Name,
    P.Level,
    C.IsMissing ,
    C.ParentCode ,
    P.IcpUid 
    FROM @TEMP P
    INNER JOIN @TEMP C ON P.Code = C.ParentCode
    WHERE C.IsMissing = 1
    AND C.IcpUid IS NULL 
    AND P.IcpUid IS NULL
    ORDER BY LEVEL
    
    DECLARE @TMP TABLE
    (
    Code varchar(40),
    Name varchar(120),
    level int,
    ParentCode varchar(40),
    IcpUid varchar(32),
    IsMIssing bit
    );
    DECLARE @NumCount INT = 0;
    INSERT INTO @TMP
    SELECT
        Code,
        Name,
        level,
        ParentCode,
        IcpUid,
        IsMissing
    FROM WarehouseStore.dws6.BeScheduleItem
    WHERE isdeleted = 0
    AND name not like '%DELETED%';
    --Step 2
    MERGE INTO @TMP TGT USING (
    SELECT DISTINCT 
       P.Code,
       IsMissing = 1
    FROM @TMP C
    INNER JOIN @TMP P ON P.Code = C.ParentCode
    WHERE C.IcpUid IS NOT NULL
    AND P.IcpUid IS NULL
    ) SRC
    ON TGT.Code = SRC.Code
    WHEN MATCHED THEN UPDATE SET TGT.IsMissing = SRC.IsMissing;
    --Step 3
    SET @NumCount = (SELECT COUNT(DISTINCT P.Code)
    FROM @TMP C
    INNER JOIN @TMP P on P.Code = C.ParentCode
    WHERE C.IcpUid IS NULL 
    AND P.IcpUid IS NULL 
    AND C.IsMIssing = 1
      AND C.IsMissing <> P.IsMissing);
    WHILE (@NumCount > 0)
    BEGIN
    --loop
    MERGE INTO @TMP TGT USING (
    SELECT DISTINCT 
    P.Code,
    IsMissing = 1
    FROM @TMP C
    INNER JOIN @TMP P ON P.Code = C.ParentCode
    WHERE C.IcpUid IS NULL 
    AND P.IcpUid IS NULL 
    AND C.IsMIssing = 1
    AND C.IsMissing <> P.IsMissing
    ) SRC
    ON TGT.Code = SRC.Code
    WHEN MATCHED THEN UPDATE SET TGT.IsMissing = SRC.IsMissing;
    SET @NumCount = (SELECT COUNT(DISTINCT P.Code)
    FROM @TMP C
    INNER JOIN @TMP P on P.Code = C.ParentCode
    WHERE C.IcpUid IS NULL 
    AND P.IcpUid IS NULL 
    AND C.IsMIssing = 1 
      AND C.IsMissing <> P.IsMissing );
    END --end loop
    
    SELECT *
    FROM @TMP C
    WHERE IsMissing = 1
    ORDER BY Level;