我正在对数据库实施审核日志,因此所有内容都包含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
    
    许可以下: CC-BY-SA归因
    不隶属于 StackOverflow
    scroll top