Estamos utilizando CDC para capturar los cambios realizados en una tabla de producción. Las filas modificadas se exportan a un almacén de datos (informática). Sé que la columna __ $ update_mask almacena qué columnas se actualizaron en forma varbinary. También sé que puedo usar una variedad de funciones CDC para descubrir de esa máscara cuáles eran esas columnas.
Mi pregunta es esta ¿Alguien puede definir para mí la lógica detrás de esa máscara para que podamos identificar las columnas que se cambiaron en el almacén? Como estamos procesando fuera del servidor, no tenemos fácil acceso a esas funciones MSSQL CDC. Prefiero romper la máscara yo mismo en código. El rendimiento de las funciones de CDC en el extremo SQL es problemático para esta solución.
En resumen, me gustaría identificar las columnas modificadas a mano desde el campo __ $ update_mask.
Actualizar:
Como alternativa, el envío de una lista legible por humanos de columnas cambiadas al almacén también era aceptable. Descubrimos que esto podría realizarse con un rendimiento mucho mayor que nuestro enfoque original.
La respuesta CLR a esta pregunta a continuación cumple con esta alternativa e incluye detalles de interpretación de la máscara para futuros visitantes. Sin embargo, la respuesta aceptada utilizando XML PATH es la más rápida hasta el momento para el mismo resultado final.
fuente
Respuestas:
Y la moraleja de la historia es ... probar, probar otras cosas, pensar en grande, luego en pequeño, siempre asumir que hay una mejor manera.
Tan científicamente interesante como fue mi última respuesta. Decidí probar otro enfoque. Recordé que podía hacer concat con el truco XML PATH (''). Como sabía cómo obtener el ordinal de cada columna modificada de la lista capture_column de la respuesta anterior, pensé que valdría la pena probar si la función de bit MS funcionaría mejor de esa manera para lo que necesitábamos.
Es mucho más limpio que (aunque no tan divertido como) todo ese CLR, devuelve el enfoque solo al código SQL nativo. Y, redoble de tambor ... devuelve los mismos resultados en menos de un segundo . Dado que los datos de producción son 100 veces mayores, cada segundo cuenta.
Dejo la otra respuesta con fines científicos, pero por ahora, esta es nuestra respuesta correcta.
fuente
Entonces, después de algunas investigaciones, decidimos seguir haciendo esto en el lado de SQL antes de entregarlo al almacén de datos. Pero estamos adoptando este enfoque mejorado (basado en nuestras necesidades y una nueva comprensión de cómo funciona la máscara).
Obtenemos una lista de los nombres de columna y sus posiciones ordinales con esta consulta. El retorno vuelve en un formato XML para que podamos pasar a SQL CLR.
Luego pasamos ese bloque XML como variable y el campo de máscara a una función CLR que devuelve una cadena delimitada por comas de las columnas que cambió según el campo binario _ $ update_mask. Esta función clr interroga el campo de máscara para el bit de cambio para cada columna en la lista xml y luego devuelve su nombre desde el ordinal relacionado.
El código c # clr se ve así: (compilado en un ensamblaje llamado CDCUtilities)
Y la función para el CLR es la siguiente:
Luego agregamos esta lista de columnas al conjunto de filas y la pasamos al almacén de datos para su análisis. Al usar la consulta y el clr, evitamos tener que usar dos llamadas de función por fila por cambio. Podemos pasar directamente a la carne con resultados personalizados para nuestra instancia de captura de cambios.
Gracias a esta publicación de stackoverflow sugerida por Jon Seigel por la manera de interpretar la máscara.
En nuestra experiencia con este enfoque, podemos obtener una lista de todas las columnas modificadas de 10k filas de cdc en menos de 3 segundos.
fuente