Sql server sqlserver中的递归循环
我有一张叫做WarehouseStore.dws6.BeScheduleItem的桌子。 下面是WarehouseStore.dws6.BeScheduleItem中的数据截图。 我的要求是根据以下条件从WarehouseStore.dws6.BeScheduleItem表中查找缺少的节点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,则 父
在
或光标时使用。光标示例:
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;