2017-03-07 30 views
0

我有一個約500個表的數據庫,這些表之間有很多外鍵關係。MS SQL服務器 - 表依賴關係層次組

我需要一起形成相關表的組,即一個組與任何其他組都沒有關係,所有相關的表應該在一個組中。

例如: - 有四個表格T1,T2,T3和T4。

T1和T2有關係,T3和T4有關係。所以我可以在一個組中插入T1和T2,在另一個組中插入T3和T4。

+0

你必須解決一個網絡問題來實現這一點,我認爲這遠不是微不足道的。 –

回答

0

您正在使用哪個SQL服務器?

select O.name as [Object_Name], C.text as [Object_Definition] 
from sys.syscomments C 
inner join sys.all_objects O ON C.id = O.object_id 
--where C.text like '%table_name%' 
0

這是sys.foreign_keys上的一個分層查詢,它應該能讓你非常接近你正在尋找的東西。

WITH cte AS (
    -- find tables that are parents, but are not children themselves 

    SELECT [fk].[referenced_object_id] AS [child_id], 
     NULL AS [parent_id], 
     CAST(CONCAT('/', [fk].[referenced_object_id], '/') AS VARCHAR(MAX)) AS h, 
     1 AS l 
    FROM sys.[foreign_keys] AS [fk] 
    WHERE [fk].[referenced_object_id] NOT IN (
     SELECT [parent_object_id] 
     FROM sys.[foreign_keys] 
    ) 

    UNION ALL 

    SELECT child.[parent_object_id], 
     [child].[referenced_object_id] AS [parent_id], 
     CAST(CONCAT(parent.[h], child.[parent_object_id], '/') AS VARCHAR(MAX)) AS [h], 
     parent.l + 1 AS l 
    FROM cte AS [parent] 
    JOIN sys.[foreign_keys] AS [child] 
     ON [parent].[child_id] = child.[referenced_object_id] 
), 
hier AS (
    SELECT DISTINCT 
     OBJECT_NAME([cte].[child_id]) AS [child], 
     object_name([cte].[parent_id]) AS [parent], 
     h, 
     --CAST([cte].[h] AS HIERARCHYID) AS h 
     l 

    FROM cte 
) 
SELECT [hier].[child] , 
     [hier].[parent] , 
     [hier].[h]--.ToString() 
FROM [hier] 
ORDER BY 
    l, h -- breadth-first search 
    --h, l -- depth-first search 
    --h.GetLevel(), h -- breadth-first search; hierarchyid 
    --h, h.GetLevel() -- depth-first search; hierarchyid 

你會注意到,我包括兩個訂單子句。每個都有它們的用途。假設你有以下外鍵的斷開圖:(a→b→c),(d→e→f)。使用第一個order by子句將按以下順序返回行:a,d,b,e,c,f。也就是說,首先是所有的頂層元素,然後是第二層元素,等等。第二個order by子句將按照a,b,c,d,e,f的順序返回它們(或者可能是d,e ,f,a,b,c;取決於a和d)的對象id。這裏的想法是,在移動到下一個圖之前,你完全耗盡了一個斷開的圖。

有一點需要注意的是,我相當確信上述內容不會將自引用外鍵考慮在內。如果這對你很重要,我會將這些作爲一個單獨的動作來處理(即首先完全填充這些動作,然後使用上述方法找到非自引用關係)。

我還在那裏留下了一兩個評論,以使層次結構解決方案的工作。在hier cte中,使用h強制轉換爲hierarchyid而不是h,然後使用利用該順序的子句。沒有必要,但可能是第一次接觸到hierarchyid。