0

我在第二个 SQL Server 实例中有一个生产数据库和一个存档数据库。

当我在生产数据库中插入或更新(NOT DELETE)数据时,我需要在存档数据库中插入或更新相同的数据。

这样做的好方法是什么?

谢谢

4

3 回答 3

1

如果它们在同一个数据库实例中,假设它不是很多表,那么触发器将是微不足道的。

如果它的大小增加,您可能需要研究 SQL Server 复制。微软花了很多时间和金钱来做正确的事。

于 2012-04-05T19:16:43.773 回答
0

复制也将复制您的删除。但是,不从存档数据库中删除删除可能会导致唯一索引出现问题,其中一个值在生产数据库中有效,但在存档数据库中无效,因为这些值已经存在于那里。如果您的设计意味着这不是问题,那么生产表中的一个简单触发器将为您执行此操作:

CREATE TRIGGER TR_MyTable_ToArchive ON MyTable FOR INSERT, UPDATE AS
BEGIN
    SET ROW_COUNT OFF
    -- First inserts
    SET IDENTITY_INSERT ArchiveDB..MyTable ON -- Only if identity column is used
    INSERT INTO ArchiveDB..MyTable(MyTableKey, Col1, Col2, Col3, ...)
    SELECT MyTableKey, Col1, Col2, Col3, ...
    FROM inserted i LEFT JOIN deleted d ON i.MyTableKey = d.MyTableKey
    WHERE d.MyTableKey IS NULL
    SET IDENTITY_INSERT ArchiveDB..MyTable OFF -- Only if identity column is used

    -- then updates
    UPDATE t SET Col1 = i.col1, col2 = i.col2, col3 = i.col3, ...
    FROM ArchiveDB..MyTable t INNER JOIN inserted i ON t.MyTableKey = i.MyTableKey
        INNER JOIN deleted d ON i.MyTableKey = d.MyTableKey
END

这假定您的存档数据库与生产数据库位于同一台服务器上。如果不是这种情况,您需要创建一个链接服务器条目,然后替换ArchiveDB..MyTableArchiveServer.ArchiveDB..MyTable,其中ArchiveServer是链接服务器的名称。

但是,如果您的生产数据库已经有很多负载,请记住,这会使负载加倍。为了避免这种情况,您可以在每个表中添加一个更新标志字段,并在数据库负载最低的时候(例如凌晨 1 点)运行计划任务。然后,您的触发器将在生产数据库中将该字段设置I为插入或U更新,计划任务将根据该字段的值在存档数据库中执行然后更新或插入,然后将该字段重置为NULL一次它已经完成了。

于 2012-04-07T07:56:10.083 回答
0

如果您正在考虑为此使用触发器,那么您可能需要考虑生产数据库的负载大小。如果它是非常密集的数据库,请考虑使用一些高可用性解决方案,例如复制或镜像或日志传送。根据您的需求,任何一种解决方案都可以为您服务。同时,您应该考虑您的“冷”恢复解决方案,这些解决方案需要根据您实施的内容进行更改。

于 2012-04-05T20:50:03.190 回答