Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.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 2008 T-SQL递归选择循环依赖_Sql Server 2008_Tsql_Recursion - Fatal编程技术网

Sql server 2008 T-SQL递归选择循环依赖

Sql server 2008 T-SQL递归选择循环依赖,sql-server-2008,tsql,recursion,Sql Server 2008,Tsql,Recursion,我的数据库中有自相关的实体a,它们是从另一个实体b引用的,给定一个特定的b实体,我需要得到所有需要的a实体。这些是多对多映射,因此我有一个单独的映射表。我认为带CTE的递归选择是我最好的选择,但我遇到了一个问题: 这说明了我的问题。如果某个用户引入循环引用,我的递归select会突然停止。我一直在绞尽脑汁想办法解决这个问题。应该注意的是,虽然我在小提琴中引入了外键,但实际上我与DBA之间使用的系统并不尊重外键——我引入外键是为了使数据流更加清晰 递归查询,针对那些不想点击小提琴的人: WITH

我的数据库中有自相关的实体a,它们是从另一个实体b引用的,给定一个特定的b实体,我需要得到所有需要的a实体。这些是多对多映射,因此我有一个单独的映射表。我认为带CTE的递归选择是我最好的选择,但我遇到了一个问题:

这说明了我的问题。如果某个用户引入循环引用,我的递归select会突然停止。我一直在绞尽脑汁想办法解决这个问题。应该注意的是,虽然我在小提琴中引入了外键,但实际上我与DBA之间使用的系统并不尊重外键——我引入外键是为了使数据流更加清晰

递归查询,针对那些不想点击小提琴的人:

WITH recur(objID) AS (
    SELECT usesObjID
        FROM #otherObj
        WHERE otherObjID = 1
    UNION ALL
    SELECT slaveObjID
        FROM #objMap
            INNER JOIN recur
                on #objMap.masterObjID = recur.objID
)SELECT objID from recur
有什么想法吗?此设计未投入生产,因此我可以在某种程度上更改模式,但我不希望依赖于在插入时发现循环引用,除非它可以通过t-SQL完成。

可以设置CTE的值,这将防止无限循环,但是您仍然会得到奇怪的结果,因为查询将继续在循环中运行,直到达到最大递归

挑战在于循环涉及多个步骤,因此您不能只检查子循环的直接父循环以确定您是否处于循环中

处理此问题的一种方法是在CTE中添加一个附加列。。。这个新列tree跟踪到目前为止包含的所有ID,并在ID重复时停止

WITH recur(objID, Tree) AS (
    SELECT 
        usesObjID, 
        CAST(',' + CAST(usesObjID AS VARCHAR) + ',' AS VARCHAR) AS Tree
    FROM otherObj
    WHERE otherObjID = 1
    UNION ALL
    SELECT 
        slaveObjID, 
        CAST(recur.Tree + CAST(slaveObjID AS VARCHAR) + ',' AS VARCHAR) AS Tree
    FROM objMap
        INNER JOIN recur
            ON objMap.masterObjID = recur.objID
    WHERE recur.Tree NOT LIKE '%,' + CAST(slaveObjID AS VARCHAR) + ',%'  
)SELECT objID from recur

从未使用过此fxn,但您是否只会在objMap.masterObjID=recur.objID和recur.objID otherobj.usesObjID上说?还是超出了范围?太棒了!如果是从otherObj到Obj的多对多映射,您认为这也会起作用吗?需要另一个映射吗table@FrankieTheKneeMan我认为这也会起作用。基本上,您仍然只需跟踪到目前为止已加入的ID,并在看到重复的ID时停止@FrankieTheKneeMan我认为这取决于你如何使用数据。有时您可能只需要一个ID,其他时候,如果您使用树下的不同路径到达ID,您可能需要两次ID。。。如果你需要的是独特的,那么我就说用它…好吧。非常感谢!我希望我能不止一次地否决你的答案。