题
我正在对数据库实施审核日志,因此所有内容都包含CreatedAt和RemovedAt列。现在我希望能够列出对象图的所有修订版,但我能想到的最佳方法是使用联合。我需要获得每个独特的CreatedAt和RemovedAt id。
如果我得到一个有省份的国家名单,联盟看起来像这样:
SELECT c.CreatedAt AS RevisionId from Countries as c where localId=@Country
UNION
SELECT p.CreatedAt AS RevisionId from Provinces as p
INNER JOIN Countries as c ON p.CountryId=c.LocalId AND c.LocalId = @Country
UNION
SELECT c.RemovedAt AS RevisionId from Countries as c where localId=@Country
UNION
SELECT p.RemovedAt AS RevisionId from Provinces as p
INNER JOIN Countries as c ON p.CountryId=c.LocalId AND c.LocalId = @Country
对于更复杂的查询,这可能会变得非常复杂并且可能表现得非常差,所以我想看看是否有人能想到更好的方法。这是在MSSQL Server中。
我需要将它们全部放在一个列表中,因为这是在from子句中使用的,真正的数据来自加入。
解决方案
您很可能已经实施了解决方案,但要解决一些问题;我建议考虑Aleris的解决方案或其衍生物。结果
您的日志中包含的字段取决于您,但Aleris的解决方案是直接的。我可以创建一个操作表,并将字段类型从varchar更改为int,作为动作表的链接 - 强制开发人员执行一些标准化操作。
希望它有所帮助。
其他提示
另一种方法是创建一个可能如下所示的审核日志:
AuditLog table
EntityName varchar(2000),
Action varchar(255),
EntityId int,
OccuranceDate datetime
其中EntityName是表的名称(例如:Contries,Provinces),Action是审计操作(例如:Created,Removed等),EntityId是原始表中修改行的主键。 / p>
对于对表执行的每个操作,表都需要保持同步。有几种方法可以做到这一点:
1)在每个表上创建触发器,将行添加到AuditTable
2)每次对repectivetables进行更改时,从应用程序中添加AuditTable中的行
使用此解决方案可以非常简单地获取审计中的日志列表。
如果你需要从原始表中获取列也可以使用这样的连接:
select *
from
Contries C
join AuditLog L on C.Id = L.EntityId and EntityName = 'Contries'
您可以通过交叉连接和合并来实现,但从性能角度来看,联盟可能仍然更好。你可以尝试测试每一个。
SELECT
COALESCE(C.CreatedAt, P.CreatedAt)
FROM
dbo.Countries C
FULL OUTER JOIN dbo.Provinces P ON
1 = 0
WHERE
C.LocalID = @Country OR
P.LocalID = @Country