如何在我的应用程序中实现更改\u跟踪\u is \u列\u in \u mask?

7fyelxc5  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(394)

在SQLServer中处理更改跟踪时,应该使用 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_COLUMNS0x000000000B000000 .

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

djp7away

djp7away1#

结果是 SYS_CHANGE_COLUMNS 由一个字节数组组成,可以分成4个字节的组。更改的列越多,字节数组越长,因此可以创建的组越多。每个组的第一个字节表示已更改列的id。在我所有的测试中,每组的其他3个字节都是空的(0)。我假设当列id大于255时将使用这些字节。列的更改顺序似乎决定了它们在字节数组中的显示顺序。而且,第一组4字节总是空的(0),我不知道为什么。
要在应用程序代码中使用它,只需为每个列名及其各自的列id获取Map 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);
}

相关问题