sql >> データベース >  >> RDS >> Sqlserver

データベース内のすべての外部キーを走査してパスを生成する

    一般に、CTE の再帰部分では集計関数を使用できないため、列連結部分を別の CTE に移動する必要があります。次のものが得られます:

        ;
    
    WITH CTE_FKCols
    AS (
        SELECT FK.NAME
            ,'[' + STUFF((
                    SELECT ','
                        ,object_name(Col.object_id) + '.' + col.NAME
                    FROM sys.foreign_key_columns C
                    INNER JOIN sys.columns Col ON Col.object_id = c.referenced_object_id
                        AND col.column_id = c.referenced_column_id
                    WHERE C.constraint_object_id = FK.object_id
                    FOR XML PATH('')
                    ), 1, 1, '') + ']' Cols
        FROM sys.foreign_keys FK
        )
        ,CTE
    AS (
        SELECT fk.create_date
            ,fk.modify_date
            ,fkc.constraint_object_id AS ConstraintId
            ,OBJECT_NAME(fkc.constraint_object_id) AS ConstraintName
            --, fkc.referenced_object_id AS PrimaryKeyTableId
            ,OBJECT_NAME(fkc.referenced_object_id) AS PrimaryKeyTableName
            --, fkc.referenced_column_id AS PrimaryKeyColumnId
            ,OBJECT_NAME(fk.parent_object_id) AS ForeignKeyTableName
        FROM sys.foreign_key_columns fkc
        INNER JOIN sys.foreign_keys fk ON fk.OBJECT_ID = fkc.constraint_object_id
        )
        ,cte2 (
        create_date
        ,modify_date
        ,ConstraintName
        ,PrimaryKeyTableName
        ,ForeignKeyTableName
        ,Hops
        ,path
        )
    AS (
        SELECT create_date
            ,modify_date
            ,ConstraintName
            ,PrimaryKeyTableName
            ,ForeignKeyTableName
            ,1
            ,CAST((
                    SELECT F.Cols
                    FROM CTE_FKCols F
                    WHERE F.NAME = cte.ConstraintName
                    ) AS NVARCHAR(4000))
        FROM cte
    
        UNION ALL
    
        SELECT cte.create_date
            ,cte.modify_date
            ,cte.ConstraintName
            ,cte.PrimaryKeyTableName
            ,cte.ForeignKeyTableName
            ,cte2.Hops + 1
            ,CAST((
                    cte2.path + CAST('-> ' AS NVARCHAR(4000)) + (
                        SELECT F.Cols
                        FROM CTE_FKCols F
                        WHERE F.NAME = cte.ConstraintName
                        )
                    ) AS NVARCHAR(4000))
        FROM cte2
        INNER JOIN cte ON cte2.ForeignKeyTableName = cte.PrimaryKeyTableName
            AND cte2.PrimaryKeyTableName != cte.PrimaryKeyTableName --Remove self-reference
        )
    SELECT *
    FROM cte2
      


    1. 重複した検出IDで重複行を更新します

    2. マイナス演算子はmysqlでエラーを私に与えます

    3. PostgreSQLで過去24時間からレコードを選択する方法

    4. Oracleデータベースからランダムにレコードを取得するにはどうすればよいですか?