使用SQL检查数据库一致性

时间:2012-03-01 12:11:34

标签: sql sql-server database validation stored-procedures

我有下一个问题:

系统中的数据库具有非规范化表,并且几乎在数据库中的每个表上都有“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参数的相等性。

2 个答案:

答案 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