在T-SQL中标识联结表的业务规则?

时间:2017-07-27 08:42:57

标签: database tsql

早上好stackoverflow用户,

我正在寻找草图一些通用业务规则,以便创建查询以查找模式中包含的所有联结表(查询sys对象)。

你能给出一些规则来实现吗?

其实我已经发布了:

  • 连接表必须具有多个约束键。
  • 连接表必须有一个未被任何一个指向的主键(???)。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

没有明确的联结表定义。如果您只想使用您提到的规则,请尝试以下查询:

SELECT t.name FROM sys.tables t
WHERE NOT EXISTS (SELECT * FROM sys.foreign_keys fk WHERE fk.referenced_object_id=t.object_id)
AND (SELECT COUNT(*) FROM sys.foreign_keys fk WHERE fk.parent_object_id=t.object_id)>1

如果您想使用更复杂的定义,还要根据您的特定编码约定,您可以尝试这样的事情:

SELECT SCHEMA_NAME(t.schema_id), t.name FROM sys.tables t
WHERE NOT EXISTS (SELECT * FROM sys.foreign_keys fk WHERE fk.referenced_object_id=t.object_id)
AND (
    SELECT COUNT(*) FROM sys.foreign_keys fk WHERE fk.parent_object_id=t.object_id
    /* AND fk.name NOT LIKE '%CreateEmployeeID'AND fk.name NOT LIKE '%ModifyEmployeeID'*/
)=2
AND NOT EXISTS (
    SELECT * FROM sys.columns c WHERE c.object_id=t.object_id
    AND NOT EXISTS (
        SELECT * FROM sys.foreign_key_columns fkc
        WHERE fkc.parent_object_id=c.object_id AND fkc.parent_column_id=c.column_id
    ) AND c.column_id NOT IN (
        SELECT MIN(ic.index_column_id) FROM sys.indexes i
        INNER JOIN sys.index_columns ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id
        WHERE i.object_id=c.object_id AND i.is_unique=1 GROUP BY i.index_id HAVING COUNT(*)=1
    ) /*AND c.name NOT IN ('CreateDate','CreateEmployeeID','ModifyDate','ModifyEmployeeID','rowversion')*/
)
/*AND EXISTS (
    SELECT * FROM sys.indexes i
    INNER JOIN sys.index_columns ic ON ic.object_id = i.object_id
    WHERE i.object_id=t.object_id AND i.is_unique=1
    AND EXISTS (
        SELECT * FROM sys.foreign_key_columns fkc
        WHERE fkc.parent_object_id=ic.object_id AND fkc.parent_column_id=ic.column_id
    )
)*/

此查询搜索满足以下条件的表:

  • 没有其他表引用此表
  • 该表包含两个外键
  • 除了涉及外键和唯一键列的那些列之外,该表不包含其他列(实际上,它不包括属于单个列上任何唯一索引的所有列)

或者,您还可以检查外键中涉及的列是否为唯一索引的一部分,并且您可以根据编码约定添加一些例外。