首页 >数据库 >mysql教程 >如何在SQL Server复制中高效地只检索更新的字段?

如何在SQL Server复制中高效地只检索更新的字段?

Linda Hamilton
Linda Hamilton原创
2025-01-03 12:52:39963浏览

How to Efficiently Retrieve Only Updated Fields in SQL Server Replication?

获取 SQL Server 中复制的更新字段

简介

在 SQL Server 数据库之间复制数据时,有必要识别已修改的字段。默认机制 COLUMNS_UPDATED 提供更新字段的按位表示。但是,本文提供了另一种方法来检索仅包含更新的列值的 XML 代码段。

自定义更新触发器函数

要实现此目的,请创建一个自定义更新触发函数如下:

CREATE TRIGGER DBCustomers_Insert
ON DBCustomers
AFTER UPDATE
AS
BEGIN
    DECLARE @sql as NVARCHAR(1024);
    SET @sql = 'SELECT ';

    WITH UpdatedColumns AS (
        SELECT c.name AS ColumnName
        FROM sys.columns AS c
        JOIN inserted AS i ON c.object_id = i.object_id
        WHERE c.is_identity = 0
            AND i.Original_value <> i.value
    )
    SELECT @sql = @sql + ',' + ColumnName
    FROM UpdatedColumns

    SET @sql = $sql + ' FROM inserted FOR XML RAW';

    DECLARE @x as XML;
    SET @x = CAST(EXEC(@sql) AS XML);

    .. use @x

END

替代解决方案,无需COLUMNS_UPDATED

代替 COLUMNS_UPDATED,另一种方法包括取消透视插入和删除的表、连接它们以及过滤任何更改:

CREATE TRIGGER TriggerName ON dbo.Sample_Table FOR DELETE, INSERT, UPDATE AS
BEGIN
    SET NOCOUNT ON;

    WITH deleted_unpvt AS (
        SELECT ContactID, FieldName, FieldValue
        FROM 
           (SELECT ContactID
                , cast(Forename as sql_variant) Forename
                , cast(Surname as sql_variant) Surname
                , cast(Extn as sql_variant) Extn
                , cast(Email as sql_variant) Email
                , cast(Age as sql_variant) Age
           FROM deleted) p
        UNPIVOT
           (FieldValue FOR FieldName IN 
              (Forename, Surname, Extn, Email, Age)
        ) AS deleted_unpvt
    ),
    inserted_unpvt AS (
        SELECT ContactID, FieldName, FieldValue
        FROM 
           (SELECT ContactID
                , cast(Forename as sql_variant) Forename
                , cast(Surname as sql_variant) Surname
                , cast(Extn as sql_variant) Extn
                , cast(Email as sql_variant) Email
                , cast(Age as sql_variant) Age
           FROM inserted) p
        UNPIVOT
           (FieldValue FOR FieldName IN 
              (Forename, Surname, Extn, Email, Age)
        ) AS inserted_unpvt
    )

    INSERT INTO Sample_Table_Changes (ContactID, FieldName, FieldValueWas, FieldValueIs)
    SELECT Coalesce (D.ContactID, I.ContactID) ContactID
        , Coalesce (D.FieldName, I.FieldName) FieldName
        , D.FieldValue as FieldValueWas
        , I.FieldValue AS FieldValueIs 
    FROM 
        deleted_unpvt d

            FULL OUTER JOIN 
        inserted_unpvt i
            on      D.ContactID = I.ContactID 
                AND D.FieldName = I.FieldName
    WHERE
         D.FieldValue <> I.FieldValue --Changes
        OR (D.FieldValue IS NOT NULL AND I.FieldValue IS NULL) -- Deletions
        OR (D.FieldValue IS NULL AND I.FieldValue IS NOT NULL) -- Insertions
END

以上是如何在SQL Server复制中高效地只检索更新的字段?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn