2017-03-07 3 views
0

Ich habe eine Datenbank mit ca. 500 Tabellen und es gibt viele Fremdschlüsselbeziehungen zwischen diesen Tabellen.MS SQL Server - Tabelle Abhängigkeitshierarchie Gruppe

Ich muss die Gruppen zusammengehöriger Tabellen zusammen bilden, d. H. Eine Gruppe ist nicht mit einer anderen Gruppe verbunden, alle zugehörigen Tabellen sollten in einer Gruppe enthalten sein.

Für zB: - Es gibt vier Tabellen T1, T2, T3 und T4.

T1 und T2 haben eine Beziehung und T3 und T4 haben eine Beziehung. Also kann ich T1 und T2 in eine Gruppe und T3 und T4 in eine andere Gruppe einfügen.

+0

Sie müssen ein Netzwerkproblem lösen, um dies zu erreichen, und ich denke, es ist alles andere als trivial. –

Antwort

0

Welchen SQL Server benutzen Sie?

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

Hier ist eine hierarchische Abfrage auf sys.foreign_keys, die Sie ziemlich nah an was Sie suchen.

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 

Sie werden feststellen, dass ich zwei Order by Klauseln enthalten. Jeder hat seine Verwendung. Angenommen, Sie haben die folgenden getrennten Diagramme von Fremdschlüsseln: (a → b → c), (d → e → f). Wenn Sie die Klausel "order by order" verwenden, werden Zeilen in der folgenden Reihenfolge zurückgegeben: a, d, b, e, c, f. Das heißt, alle Elemente der obersten Ebene zuerst, gefolgt von den Elementen der Ebene zwei usw. Die Klausel zweiter Ordnung by gibt sie in der Reihenfolge a, b, c, d, e, f (oder vielleicht d, e zurück , f, a, b, c, abhängig von den Objekt-IDs für a und d). Die Idee hier ist, dass Sie einen getrennten Graphen vollständig erschöpfen, bevor Sie zum nächsten gehen.

Eine Anmerkung ist, dass ich ziemlich sicher bin, dass das oben genannte nicht selbstreferenzielle Fremdschlüssel berücksichtigt. Wenn das für Sie wichtig ist, würde ich diese als separate Aktion behandeln (d. H. Füllen Sie diese zuerst vollständig aus und suchen Sie dann die nicht-selbstreferenziellen Beziehungen mit dem oben genannten).

Ich habe auch ein oder zwei Kommentare da drin, um eine Hierarchie-Lösung funktionieren zu lassen. Verwenden Sie in der hier cte das Casting von h zu hierarchyid statt h und verwenden Sie dann die order by-Klauseln, die davon profitieren. Nichts davon ist notwendig, aber könnte eine gute erste Exposition gegenüber der Hierarchie sein.