我有下一个问题:
系统中的数据库具有非规范化表,并且几乎在数据库中的每个表上都有“CompanyID”字段。这是由于业务规则的目的而完成的,应该是这样的。有时数据不一致,因为使用CompanyID == 1的客户的订单包含CompanyID == 2.
我的建议是编写专门的存储过程,每隔一段时间就会触发一次,并分析一下该属性的一些基本“关系链”(意味着Cusomer带有一些公司ID应始终只有来自同一公司ID的订单,其中后者有相应公司ID的文章)
Quesqion:
SQL中是否有通用的方法来获取具有字段CompanyID的表,然后检查它们的一致性?解决这个问题的其他方法吗?
我使用此SQL获取具有给定列名的表:
select column_name, c.is_nullable, c.table_schema, c.table_name, t.table_type, t.table_catalog, *
from information_schema.columns c join information_schema.tables t
on c.table_schema = t.table_schema and c.table_name = t.table_name
where column_name = 'CompanyID'
and table_type not in ('VIEW')
and t.table_name not like 'MsMerge%'
order by ordinal_position
之后我想到通过外键遍历关系树以记录检查CompanyID参数的相等性。
答案 0 :(得分:1)
查询示例:
lets say these are our tables:
create table customer(
id int,
companyID int
)
create table orders (
orderId int,
customerid int,
companyID int --"wrong column"
)
你应该调整这样的查询:
update orders
set companyID=(select companyID from customer where id=customerid)
更正数据,但也消除了表格订单上列companyID的所有用法。
如果你有很多地方发生这种情况,并且你想创建一种运行上述查询的自动方式,你可以在表sys.columns
上查找列companyID,从中获取表名,构建一个循环来生成查询
编辑(基于您对评论的回答):
所以逻辑基本相同。 遍历sys.columns表以获取列出现的表格以及每个表格的运行:
select *
from orders o
where companyID != (select companyID from customer where id=customerid)
答案 1 :(得分:1)
我不会通过运行每个视图分钟的通用sql来做到这一点 - 这是大型数据库的性能死亡。
相反,您可以在每个受影响的表上使用插入/更新触发器,您可以像这样编写代码:
CREATE TRIGGER chk_tablename
ON T1 tablename
FOR INSERT,UPDATE
AS
BEGIN
// Your checks are here
// Log inconsistent data
END