Мы используем CDC для записи изменений, внесенных в рабочую таблицу. Измененные строки экспортируются в хранилище данных (informatica). Я знаю, что в столбце __ $ update_mask хранятся столбцы, которые были обновлены в форме varbinary. Я также знаю, что могу использовать различные функции CDC, чтобы узнать из этой маски, что это были за столбцы.
У меня вопрос такой. Может ли кто-нибудь определить для меня логику этой маски, чтобы мы могли идентифицировать столбцы, которые были изменены на складе? Поскольку мы выполняем обработку вне сервера, у нас нет простого доступа к этим функциям MSSQL CDC. Я бы предпочел просто разбить маску самостоятельно в коде. Производительность функций cdc на стороне SQL является проблематичной для этого решения.
Короче говоря, я хотел бы идентифицировать измененные столбцы вручную из поля __ $ update_mask.
Обновить:
В качестве альтернативы была также приемлема отправка удобочитаемого списка измененных столбцов на склад. Мы обнаружили, что это может быть выполнено с производительностью, намного превышающей наш первоначальный подход.
Ответ CLR на этот вопрос, приведенный ниже, соответствует этой альтернативе и включает в себя детали интерпретации маски для будущих посетителей. Однако принятый ответ с использованием XML PATH является самым быстрым, но для того же конечного результата.
Ответы:
И мораль этой истории заключается в том, чтобы ... тестировать, пробовать другие вещи, мыслить масштабно, а потом мало, всегда предполагать, что есть лучший способ.
Столь же научно интересным, каким был мой последний ответ. Я решил попробовать еще один подход. Я вспомнил, что могу сделать конкат с трюком XML PATH (''). Так как я знал, как получить порядковый номер каждого измененного столбца из списка captured_column из предыдущего ответа, я подумал, что стоит проверить, будет ли битовая функция MS работать лучше для того, что нам нужно.
Это намного чище, чем (хотя и не так весело, как) весь этот CLR, возвращает подход только к собственному SQL-коду. И, барабанная дробь .... возвращает те же результаты менее чем за секунду . Поскольку производственные данные в 100 раз больше, каждая секунда считается.
Я оставляю другой ответ в научных целях - но пока это наш правильный ответ.
источник
Итак, после некоторых исследований мы решили сделать это на стороне SQL, прежде чем передавать их в хранилище данных. Но мы используем этот значительно улучшенный подход (основанный на наших потребностях и новом понимании того, как работает маска).
С помощью этого запроса мы получаем список имен столбцов и их порядковых позиций. Возврат возвращается в формате XML, чтобы мы могли перейти к SQL CLR.
Затем мы передаем этот блок XML как переменную и поле маски в функцию CLR, которая возвращает строку с разделителями-запятыми столбцов, которые были изменены в двоичном поле _ $ update_mask. Эта функция clr запрашивает поле маски для бита изменения для каждого столбца в списке xml и затем возвращает его имя из связанного порядкового номера.
Код c # clr выглядит следующим образом: (скомпилирован в сборку под названием CDCUtilities)
И функция к CLR такая:
Затем мы добавляем этот список столбцов в набор строк и передаем в хранилище данных для анализа. Используя запрос и clr, мы избегаем необходимости использовать два вызова функции на строку на изменение. Мы можем перейти непосредственно к мясу с результатами, настроенными для нашего экземпляра захвата изменений.
Благодаря этому сообщению stackoverflow о переполнении стека, предложенному Джоном Зигелем за манеру интерпретации маски.
В нашем опыте с этим подходом мы можем получить список всех измененных столбцов из строк 10k CDC менее чем за 3 секунды.
источник