【问题标题】:How to implement CHANGE_TRACKING_IS_COLUMN_IN_MASK in my application?如何在我的应用程序中实现 CHANGE_TRACKING_IS_COLUMN_IN_MASK?
【发布时间】:2020-08-01 09:43:08
【问题描述】:

在 SQL Server 中使用Change Tracking 时,您应该使用CHANGE_TRACKING_IS_COLUMN_IN_MASK 来确定在处理更新时更改了哪一列。比如像这样:

DECLARE @last_synchronization_version bigint = ...;
DECLARE @column_id int = ...;

-- The statement below returns 1 if the specified column (@column_id) was changed, otherwise 0.

SELECT CHANGE_TRACKING_IS_COLUMN_IN_MASK(@column_id, SYS_CHANGE_COLUMNS)
FROM CHANGETABLE(CHANGES dbo.MyTable, @last_synchronization_version) AS CT

我想知道,有没有办法自己实现CHANGE_TRACKING_IS_COLUMN_IN_MASK,这样我就可以在我的应用程序中使用SYS_CHANGE_COLUMNS 的值,而不必在执行查询时事先知道我的应用程序对哪些列感兴趣?

例如,当我只更改ID为11的列的值时,SYS_CHANGE_COLUMNS的值是0x000000000B000000

如何以编程方式确定此掩码是否包含第 11 列已更改的信息?

【问题讨论】:

标签: sql sql-server bitmask change-tracking


【解决方案1】:

原来SYS_CHANGE_COLUMNS 由一个字节数组组成,可以分组为 4 个字节的组。更改的列越多,字节数组就越长,因此您可以创建的组越多。每个组的第一个字节表示已更改列的 ID。在我所有的测试中,每组的其他 3 个字节为空 (0)。我假设当您的列 ID 大于 255 时将使用这些字节。似乎更改列的顺序决定了它们在字节数组中出现的顺序。另外,第一组 4 个字节总是空的(0),我不知道为什么。

要在应用程序代码中使用它,您需要做的就是为每个列名及其各自的列 ID 获取一个映射。上一段应该解释了如何使用SYS_CHANGE_COLUMNS来确定字节数组中出现的列ID。

C# 示例:

public static IEnumerable<int> GetColumnIdsInMask(byte[] columns)
{
    // TODO: deal with column IDs larger than 255
    for (var i = 4; i < columns.Length; i += 4)
    {
        yield return columns[i];
    }
}

public static bool IsColumnInMask(int columnId, byte[] columns)
{
    return GetColumnIdsInMask.Any(x => x == columnId);
}

【讨论】:

    猜你喜欢
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-05
    • 2010-09-07
    • 1970-01-01
    • 2023-04-07
    • 2021-11-17
    相关资源
    最近更新 更多