Как реализовать CHANGE_TRACKING_IS_COLUMN_IN_MASK в моем приложении? - PullRequest
0 голосов
/ 01 августа 2020

При работе с Отслеживание изменений на SQL сервере, вы должны использовать 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?

1 Ответ

0 голосов
/ 01 августа 2020

Получается, что SYS_CHANGE_COLUMNS состоит из массива байтов, который можно сгруппировать в группы по 4 байта. Чем больше столбцов было изменено, тем длиннее будет массив байтов и, следовательно, тем больше групп вы сможете создать. Первый байт каждой группы представляет собой идентификатор столбца, который был изменен. Во всех моих тестах остальные 3 байта каждой группы были пустыми (0). Я предполагаю, что эти байты будут использоваться, если у вас ID столбца больше 255. Кажется, порядок, в котором были изменены столбцы, определяет порядок, в котором они появляются в массиве байтов. Кроме того, первая группа из 4 байтов всегда будет пустой (0), я не уверен, почему.

Чтобы использовать это в коде приложения, все, что вам нужно сделать, это получить сопоставление для каждого имени столбца и это соответствующий идентификатор столбца. В предыдущем абзаце следует объяснить, как использовать SYS_CHANGE_COLUMNS для определения идентификатора столбца в массиве байтов.

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);
}
...