【问题标题】:SQL server find dependencies between tables that are not declaredSQL Server 查找未声明的表之间的依赖关系
【发布时间】:2013-09-20 07:28:50
【问题描述】:

我正在使用SQL Server 2008 R2

最近我得到了一个包含 Web 应用程序实时数据的数据库。

通过查看它,我发现有许多表具有依赖关系,即已经隐含但未声明。

例如:

TableA 有列[Id], [Name], [Address]。这里[Id]primary key
TableB 有列[Id], [TableAId], [Salary]。这里[Id]primary key,而列[TableAId] 只包含[TableA].[Id] 的值(除了TableA 的Id 之外没有任何值),但它没有声明为外键。

通过查看代码,我发现两个表的记录都插入到同一个事件中。所以[TableB].[TableAId] 列将只有[TableA].[Id] 包含的值。

现在,我想找到与它们类似的其他依赖项。

是否可以使用 SQL 服务器查询、工具或任何第三方软件?

【问题讨论】:

  • 你可以考虑一些数据挖掘工具

标签: sql sql-server sql-server-2008 sql-server-2008-r2


【解决方案1】:

在一般情况下,我认为您不能指望 TableA.Id 来暗示对 TableA 的外键引用。它可能指的是一个不同的表,该表存储表A中的id号。我知道你已经查看了这个特定案例中的代码,但您正在寻找不需要审查代码的解决方案。

无论如何。 . .

您可以在表达式上连接表格。此查询(PostgreSQL 语法)将列名的一部分连接到表名。在 PostgreSQL 中,函数调用 left(t1.column_name, -2) 返回除了 t1.column_name 的最后两个字符之外的所有字符; left(t1.column_name, -3) 返回除最后三个之外的所有内容。这旨在匹配“TableAid”和“TableA_id”等名称。

select t1.table_catalog, t1.table_schema, t1.table_name, 
       t1.column_name, left(t1.column_name, -2), 
       t2.table_catalog, t2.table_schema, t2.table_name
from information_schema.columns t1
inner join information_schema.tables t2
        on left(t1.column_name, -2) = t2.table_name or 
           left(t1.column_name, -3) = t2.table_name
where t1.column_name like '%id';

我相信这个查询会返回相同的行。它使用的是 SQL Server 语法,但我没有在 SQL Server 中测试过。

select t1.table_catalog, t1.table_schema, t1.table_name, 
       t1.column_name, left(t1.column_name, length(t1.column_name) - 2), 
       t2.table_catalog, t2.table_schema, t2.table_name
from information_schema.columns t1
inner join information_schema.tables t2
        on left(t1.column_name, length(t1.column_name) - 2) = t2.table_name or 
           left(t1.column_name, length(t1.column_name) - 3) = t2.table_name
where t1.column_name like '%id';

这两种方法都可能错误地返回行,主要是因为连接可能至少需要考虑“table_catalog”列。我争论是否将其包括在内。我终于决定不放了。我认为,如果我站在你的立场上,我希望这个查询有最大的机会返回一些令人惊讶的行。

【讨论】:

    【解决方案2】:

    尝试一些依赖检查。

    --- Get the source objects, columns and dependent objects using the data.
    select so.name as sourceObj
         , so.type as sourceType
         , c.name  as colname
         , st.name as coltype
         , u.name  as DependentObj
         , d.selall   as is_select_all
         , d.resultobj as is_updated
         , d.readobj   as is_read
         --, d.*
      from sys.columns c 
         ----- object that owns the column
     inner join sys.objects so on so.object_id = c.object_id
     inner join sys.types st on c.system_type_id = st.system_type_id
         ----- holds dependencies
         inner join sysdepends d   on d.id = c.object_id
     ----- object that uses the column
     inner join sys.objects u on u.object_id = d.depid
    

    您可以列出所有表/视图/过程等。真正适合您的用例的位是:

         , d.sellall   as is_select_all
         , d.resultobj as is_updated
         , d.readobj   as is_read
    

    如果这些字段中的任何一个为 1,则它们要么被选择、更新或直接检索。

    我希望这可能会有所帮助。 享受

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多