sql - 如何在我的应用程序中实现 CHANGE_TRACKING_IS_COLUMN_IN_MASK?
问题描述
在 SQL Server 中使用更改跟踪时,您应该使用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 列已更改的信息?
解决方案
事实证明,它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);
}
推荐阅读
- c++ - 是否可以将 GLM 与非基本类型一起使用?
- html - 页脚位于视点高度,而不是位于页面内容下方
- python - 根据用户输入更新“列表”仅更新一次
- python - 向熊猫数据框添加一个新列,其中包含另一列的隐藏值?
- azure - Azure Devops 管道构建参数
- python - Plotly:创建具有分类 x 轴抖动和多级轴的 Scatter
- javascript - 如何将网络摄像头实时存储在服务器上?
- python - 用于从嵌套列表中删除子列表的 python 函数
- batch-file - 为什么我的“REM PrintBoxAt 1 1 25 80 2”代码不能正常工作?
- linux - 无法在生产环境中使用 Docker 在 Symfony 4.4 上安装 LiipImagineBundle 2.3