Estamos usando o CDC para capturar alterações feitas em uma tabela de produção. As linhas alteradas estão sendo exportadas para um armazém de dados (informatica). Eu sei que a coluna __ $ update_mask armazena quais colunas foram atualizadas em um formulário varbinário. Sei também que posso usar uma variedade de funções do CDC para descobrir a partir dessa máscara quais eram essas colunas.
Minha pergunta é essa. Alguém pode definir para mim a lógica por trás dessa máscara para que possamos identificar as colunas que foram alteradas no armazém? Como estamos processando fora do servidor, não temos acesso fácil a essas funções do MSSQL CDC. Prefiro apenas quebrar a máscara em código. O desempenho das funções cdc na extremidade SQL é problemático para esta solução.
Em resumo, gostaria de identificar manualmente as colunas alteradas no campo __ $ update_mask.
Atualizar:
Como alternativa, o envio de uma lista legível por humanos de colunas alteradas para o armazém também era aceitável. Descobrimos que isso poderia ser realizado com desempenho muito superior à nossa abordagem original.
A resposta do CLR a esta pergunta abaixo atende a essa alternativa e inclui detalhes de interpretação da máscara para futuros visitantes. No entanto, a resposta aceita usando XML PATH é a mais rápida ainda para o mesmo resultado final.
fonte
Respostas:
E a moral da história é ... teste, tente outras coisas, pense grande, depois pequeno, sempre assuma que existe um caminho melhor.
Tão cientificamente interessante quanto minha última resposta foi. Eu decidi tentar outra abordagem. Lembrei-me de que podia concatenar com o truque XML PATH (''). Desde que eu soube como obter o ordinal de cada coluna alterada da lista capture_column da resposta anterior, pensei que valeria a pena testar se a função de bit MS funcionaria melhor dessa maneira para o que precisávamos.
É muito mais limpo do que (embora não seja tão divertido quanto) todo esse CLR, retorna a abordagem apenas ao código SQL nativo. E, drum roll .... retorna os mesmos resultados em menos de um segundo . Como os dados de produção são 100 vezes maiores a cada segundo conta.
Estou deixando a outra resposta para fins científicos - mas, por enquanto, esta é a nossa resposta correta.
fonte
Portanto, após algumas pesquisas, decidimos ainda fazer isso no lado SQL antes de passar para o data warehouse. Mas estamos adotando essa abordagem muito melhorada (com base em nossas necessidades e nova compreensão de como a máscara funciona).
Nós obtemos uma lista dos nomes das colunas e suas posições ordinais com esta consulta. O retorno volta em um formato XML para que possamos passar para o SQL CLR.
Em seguida, passamos esse bloco XML como uma variável e o campo de máscara para uma função CLR que retorna uma string delimitada por vírgula das colunas que foram alteradas pelo campo binário _ $ update_mask. Essa função clr interroga o campo de máscara para obter o bit de alteração de cada coluna na lista xml e, em seguida, retorna o nome do ordinal relacionado.
O código c # clr tem a seguinte aparência: (compilado em um assembly chamado CDCUtilities)
E a função para o CLR assim:
Em seguida, anexamos esta lista de colunas ao conjunto de linhas e passamos para o data warehouse para análise. Ao usar a consulta e o clr, evitamos ter que usar duas chamadas de função por linha por alteração. Podemos pular direto para a carne com resultados personalizados para nossa instância de captura de alterações.
Graças a este post de stackoverflow sugerido por Jon Seigel pela maneira de interpretar a máscara.
Em nossa experiência com essa abordagem, podemos obter uma lista de todas as colunas alteradas de 10k linhas de cdc em menos de 3 segundos.
fonte