2

我的一个新客户有一个 2002 年编写的小型 VB/Access 数据库应用程序,他希望对其进行重写以使其更新并支持他一直想要的新功能。因此,我将把它转换为在本地计算机上使用 C#.NET 2008 和 SQL Server Express 2008,并能够扩展到在远程服务器上使用 WCF 和 SQL Server 2008。

他感兴趣的新功能之一是维护和报告一段时间内数据更改的完整历史记录。过去,我通过使用触发器和存储过程来做到这一点,这对@!#$ 来说很痛苦。

我最近很想弄乱 SQL Server 2008 的变更数据捕获功能。在我最初使用它的一个小时内,我意识到它在 SQL 代理中创建了一个默认情况下每 5 秒运行一次的作业。当我需要更改捕获表的架构时,这似乎也有点痛苦。除此之外,它似乎比我原来的方法更容易实现。所以,这些是我的问题:

  1. 对于最终可能会或可能不会迁移到远程服务器的小型桌面应用程序来说,这是否有点矫枉过正?
  2. 在性能方面我应该期待什么?随着他的数据库大小增加,我是否会接到更多来自他的电话,说他的计算机运行缓慢?
  3. 我应该从目前在生产中使用它的任何人那里了解 CDC 的任何其他问题吗?
  4. 有没有人有任何链接指向他们最喜欢的随时间跟踪变化的方式,这可能更适合小型桌面应用程序?

谢谢,

马克

4

3 回答 3

2

CDC 仅在 SQL Server 企业版中可用。所以如果你有快递,你就不能使用它,你必须继续使用触发器。

于 2009-01-22T17:09:29.743 回答
1

虽然触发器在很多方面都很难使用,但您可以通过编写实际自动生成触发器和历史表的脚本,在透明的数据审计历史机制上使用它们,而不会对主代码库产生任何影响。这是一项相当多的工作,我不知道有谁做过这样的事情并将其开源,但这可能是一个有趣的项目。至少这样,您可以编写一个生成器过程,然后不必再与单个触发器混为一谈。

于 2009-01-22T17:18:14.840 回答
1

我使用我自己的更改数据跟踪系统,在我的更改表中使用 XML 列,使其更加灵活。也使触发器相当通用。

假设您已经有触发器来创建审计行,并且您的源表有一个名为“Version”的 ROWVERSION 类型的列:

INSERT INTO [Changes].Sites
(
    SiteID,
    Operation,
    Version,
    ModifiedOn,
    DataChange
)
SELECT
    IsNull( I.SiteID, D.SiteID ),
    CASE
        WHEN D.[Version] IS NULL      AND I.[Version] IS NOT NULL  THEN 'I'
        WHEN D.[Version] IS NOT NULL  AND I.[Version] IS NOT NULL  THEN 'U'
        WHEN D.[Version] IS NOT NULL  AND I.[Version] IS NULL      THEN 'D'
        ELSE '?'
    END,
    IsNull( I.Version, D.Version ),
    SysDateTimeOffset(),
    (
        SELECT
            [Deleted] = ( SELECT * FROM deleted D1 WHERE D1.SiteID = D.SiteID FOR XML PATH(''), TYPE ),
            [Inserted] = ( SELECT * FROM inserted I1 WHERE I1.SiteID = I.SiteID FOR XML PATH(''), TYPE )
        FOR XML PATH('Changes')
    )
FROM deleted D
FULL JOIN inserted I
    ON D.SiteID = I.SiteID

该查询中唯一特定于我的表的是主键。生成模板来创建这些查询将相当简单(甚至可以使用 sys.tables 等在 SQL 中完成)。

于 2009-09-11T03:41:14.053 回答