sql - 查询以查明外键是否在数据库中的其他位置被引用

标签 sql sql-server sql-server-2008 foreign-keys

我有餐 table 动物。

我想返回该表中的所有内容+一列,该列表示记录是否在其他任何地方作为外键引用。

即:

Animal_Id    Name  
    1        Cat
    2        Dog
    3        Parrot

我想返回:

AnimalId    Name     Referenced 
    1        Cat         true
    2        Dog         false
    3        Parrot      true

“引用”是指数据库中任何其他表中是否引用了特定的 Animal_Id 作为外键。我想我首先可以查询information_schema并找出哪些表包含这个外键,然后使用循环和动态sql来执行
从 AnimalID = 1 的每个表中选择 count(*)

有人有关于如何做到这一点的代码片段吗?

最佳答案

这应该可以做到:

SELECT OO.Animal_ID, OO.Name, CASE WHEN XX.REFERENCED IS NULL THEN 'false' ELSE 'true' END Referenced
FROM   Animal OO
       OUTER APPLY (SELECT SUM(1) REFERENCED
                    FROM   (SELECT FkAnimal_ID FROM AnimalRef1 RR WHERE RR.FkAnimal_ID = OO.Animal_ID UNION ALL
                            SELECT FkAnimal_ID FROM AnimalRef2 RR WHERE RR.FkAnimal_ID = OO.Animal_ID UNION ALL
                            SELECT FkAnimal_ID FROM AnimalRef3 RR WHERE RR.FkAnimal_ID = OO.Animal_ID) II) XX

如果您不知道所有 FK 表,您可以使用系统元数据表将 UNION ALL 查询的集合生成到一个表中,然后您可以将其复制并粘贴到您的查询中:

WITH AKT AS ( SELECT f.name AS ForeignKey
                    ,OBJECT_NAME(f.parent_object_id) AS TableName
                    ,COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName
                    ,OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName
                    ,COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName
              FROM   sys.foreign_keys AS f
                     INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id
              WHERE  f.referenced_object_id = object_id('Animal'))
SELECT 'SELECT ' + ColumnName + ' FROM ' + TableName + ' WHERE  RR.' + ColumnName + ' = OO.' + ReferenceColumnName + ' UNION ALL'
FROM   AKT

对于使用递归 CTE 的单个查询中的整个事情:

DECLARE @QUERY NVARCHAR(MAX)

WITH AKT AS ( SELECT ROW_NUMBER() OVER (ORDER BY f.name) RN, f.name AS ForeignKey
                    ,OBJECT_NAME(f.parent_object_id) AS TableName
                    ,COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName
                    ,SCHEMA_NAME(oo.schema_id) SchemaName
                    ,OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName
                    ,COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName
              FROM   sys.foreign_keys AS f
                     INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id
                     INNER JOIN sys.objects oo ON oo.object_id = fc.referenced_object_id
              WHERE  f.referenced_object_id = object_id('Animal'))

    ,bs AS (SELECT AKT.RN
                  ,'SELECT ' + ColumnName + ' FROM ' + SchemaName + '.' + TableName + ' WHERE ' + ColumnName + ' = OO.' + ReferenceColumnName  SubQuery
            FROM   AKT)
    ,re AS (SELECT bs.RN, CAST(RTRIM(bs.SubQuery) AS VARCHAR(MAX)) Joined
            FROM   bs
            WHERE  bs.RN = 1
            UNION  ALL
            SELECT bs2.RN, CAST(re.Joined + ' UNION ALL ' + ISNULL(RTRIM(bs2.SubQuery), '') AS VARCHAR(MAX)) Joined
            FROM   re, bs bs2 
            WHERE  re.RN = bs2.RN - 1 )
    ,fi AS (SELECT ROW_NUMBER() OVER (ORDER BY RN DESC) RNK, Joined
            FROM   re)
SELECT @QUERY  = 'SELECT OO.Animal_ID, OO.Name, CASE WHEN XX.REFERENCED IS NULL THEN ''No'' ELSE ''Yes'' END Referenced
FROM   Animal OO
       OUTER APPLY (SELECT SUM(1) REFERENCED
                    FROM   (' + Joined + ') II) XX'
FROM   fi
WHERE  RNK = 1

EXEC (@QUERY)

关于sql - 查询以查明外键是否在数据库中的其他位置被引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9626892/

相关文章:

mysql - JOINing 后旋转表不正确?

sql - ORA-00911 : invalid character - When running SQL dump

mysql - 将mysql插入语句转换为sql server插入语句?

c# - MultipleActiveResultSets=True 或多个连接?

sql-server - SQL Server 自定义计数器存储过程创建欺骗

sql - MySQL - 连接表,仅检索最大 ID

mysql - 加入两个表而不丢失相关值

SQL Server 2008 日期参数

sql - EXISTS 与 JOIN 以及 EXISTS 子句的使用

vb.net - 使用 .MDF 文件(sql server 2008)+ ClickOnce 部署 VB.net 应用程序