HOW TO:解释T SQL CDC“__ $ update_mask”字段

时间:2013-01-30 15:17:12

标签: sql-server cdc

由于我很难解决如何使用“$ update_mask”字段(出于性能原因我不想调用fn_cdc_is_bit_set),这里是C#代码:

  • updateMask 是来自CDC“fn_cdc_get_all_changes_ [table]”查询的“__ $ update_mask”字段的内容
  • colOrdinal 是您要从中获取更改标记的列的序号#(使用“n_cdc_get_column_ordinal”来检索此值)

结果是“ hasChanged ”标志。如果更新中的字段已更改,则设置为true。

请注意,这适用于SQL Server 2008和2012,但可能不适用于将来的版本。

byte[] updateMask = this.UpdateMask;
        unchecked
        {
            byte relevantByte = updateMask[(updateMask.Length - 1) - ((colOrdinal - 1) / 8)];
            int bitMask = 1 << ((colOrdinal - 1) % 8);
            var hasChanged = (relevantByte & bitMask) != 0;

            return hasChanged;
        }

3 个答案:

答案 0 :(得分:1)

只需使用BitArray即可获取已更改列的序号索引。反转掩码并将其添加到BitArray,设置为true的所有数组值都是相应索引处的已更改列。

byte[] updateMask = this.UpdateMask;  
Array.Reverse(updateMask);
BitArray columnBits = new BitArray(bitmask);

// To match your code sample, you can just check if the column bit is set at the ordinal.
bool hasChanged = columnBits[colOrdinal];

// You could loop and get the column indexes like this as well.
for (int i = 0; i < columnBits.Length; i++)
{
  // If the bit is set to true then the column at the same index was modified.
  if (columnBits[i])
  {
    // Do something with modified column at index 'i'.
  }      
}

我试图让代码示例尽可能简单易读。记得首先检查数组索引是否存在等等。

答案 1 :(得分:0)

我对此并不是100%肯定,但$update_mask中的值很可能是COLUMNS_UPDATED()在触发器内返回的值。您可以在此处获取有关如何解释该值的详细信息:http://msdn.microsoft.com/en-us/library/ms186329.aspx

答案 2 :(得分:0)

我遇到了同样的问题。我有多次调用函数sys.fn_cdc_is_bit_set的程序,甚至编译该程序花了几分钟,执行也很慢。当我用手动掩码解析函数sys.fn_cdc_is_bit_set替换它时,它的工作速度要快得多。 substring([ $ update_mask],len([ $ update_mask]) - (([ColumnOrder] -1)/ 8),1)&amp; power(2,([ColumnOrder] -1)%8)&gt; 0然后1其他0结束