Pregunta

¿Cómo puedo monitorear una base de datos de SQL Server para detectar cambios en una tabla sin usar activadores ni modificar la estructura de la base de datos de ninguna manera?Mi entorno de programación preferido es .NETO y C#.

Me gustaría poder apoyar a cualquier Servidor SQL 2000 SP4 o más reciente.Mi aplicación es una visualización de datos complementaria para el producto de otra empresa.Nuestra base de clientes es de miles, por lo que no quiero tener que exigir que modifiquemos la tabla del proveedor externo en cada instalación.

Por "cambios en una mesa" Me refiero a cambios en los datos de la tabla, no a cambios en la estructura de la tabla.

En última instancia, me gustaría que el cambio desencadenara un evento en mi aplicación, en lugar de tener que verificar los cambios en un intervalo.


El mejor curso de acción dados mis requisitos (sin activadores ni modificación de esquema, SQL Server 2000 y 2005) parece ser utilizar el BINARY_CHECKSUM funcionar en T-SQL.La forma en que planeo implementar es esta:

Cada X segundos ejecuta la siguiente consulta:

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
FROM sample_table
WITH (NOLOCK);

Y compárelo con el valor almacenado.Si el valor ha cambiado, revise la tabla fila por fila usando la consulta:

SELECT row_id, BINARY_CHECKSUM(*)
FROM sample_table
WITH (NOLOCK);

Y compare las sumas de verificación devueltas con los valores almacenados.

¿Fue útil?

Solución

Eche un vistazo al comando CHECKSUM:

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM sample_table WITH (NOLOCK);

Eso devolverá el mismo número cada vez que se ejecute, siempre que el contenido de la tabla no haya cambiado.Vea mi publicación sobre esto para más información:

SUMA DE VERIFICACIÓN

Así es como lo usé para reconstruir las dependencias de la caché cuando las tablas cambiaron:
Dependencia de caché de base de datos ASP.NET 1.1 (sin desencadenadores)

Otros consejos

Desafortunadamente CHECKSUM no siempre funciona correctamente para detectar cambios..

Es sólo una suma de verificación primitiva y ningún cálculo de verificación de redundancia cíclica (CRC).

Por lo tanto, no puede usarlo para detectar todos los cambios, p.gramo.¡Los cambios simétricos dan como resultado la misma SUMA DE VERIFICACIÓN!

MI.gramo.la solución con CHECKSUM_AGG(BINARY_CHECKSUM(*)) siempre entregará 0 para las 3 tablas con contenido diferente:


SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM 
(
  SELECT 1 as numA, 1 as numB
  UNION ALL
  SELECT 1 as numA, 1 as numB
)  q
-- delivers 0!

Seleccione checkSum_agg (binary_checksum (*)) de (seleccione 1 como NUMA, 2 como unión NUMB Todo Seleccione 1 como NUMA, 2 como NUMB) Q - ¡ENCONTRA 0!

Seleccione checkSum_agg (binary_checksum (*)) de (seleccione 0 como NUMA, 0 como unión NUMB Todo Seleccione 0 como NUMA, 0 AS NUMB) Q - ¡ENCONTRA 0!

¿Por qué no quieres utilizar desencadenantes?Son algo bueno si los usas correctamente.Si los usa como una forma de hacer cumplir la integridad referencial, es cuando pasan de bueno a malo.Pero si los usas para monitorear, en realidad no se consideran tabú.

¿Con qué frecuencia necesita verificar los cambios y qué tamaño (en términos de tamaño de fila) tienen las tablas en la base de datos?Si usas el CHECKSUM_AGG(BINARY_CHECKSUM(*)) método sugerido por John, escaneará cada fila de la tabla especificada.El NOLOCK La sugerencia ayuda, pero en una base de datos grande, todavía estás accediendo a cada fila.También deberá almacenar la suma de verificación de cada fila para saber que una ha cambiado.

¿Has considerado abordar esto desde un ángulo diferente?Si no desea modificar el esquema para agregar activadores (lo cual tiene sentido, no es su base de datos), ¿ha considerado trabajar con el proveedor de la aplicación que crea la base de datos?

Podrían implementar una API que proporcione un mecanismo para notificar a las aplicaciones accesorias que los datos han cambiado.Podría ser tan simple como escribir en una tabla de notificaciones que enumere qué tabla y qué fila se modificaron.Esto podría implementarse mediante activadores o código de aplicación.Por su parte, no importaría, su única preocupación sería escanear la tabla de notificaciones periódicamente.El impacto en el rendimiento de la base de datos sería mucho menor que escanear cada fila en busca de cambios.

La parte difícil sería convencer al proveedor de la aplicación para que implemente esta función.Dado que esto se puede manejar completamente a través de SQL mediante activadores, usted podría hacer la mayor parte del trabajo por ellos escribiendo y probando los activadores y luego llevando el código al proveedor de la aplicación.Al hacer que el proveedor admita los activadores, se evita la situación en la que agregar un activador reemplaza inadvertidamente un activador proporcionado por el proveedor.

Desafortunadamente, no creo que exista una manera limpia de hacer esto en SQL2000.Si limita sus requisitos a SQL Server 2005 (y posteriores), entonces ya está en el negocio.Puedes usar el SQLDependency clase en System.Data.SqlClient.Ver Notificaciones de consultas en SQL Server (ADO.NET).

Tener un trabajo DTS (o un trabajo iniciado por un servicio de Windows) que se ejecute en un intervalo determinado.Cada vez que se ejecuta, obtiene información sobre la tabla dada utilizando el sistema. INFORMACIÓN_ESQUEMA tablas y registra estos datos en el repositorio de datos.Compare los datos devueltos con respecto a la estructura de la tabla con los datos devueltos la vez anterior.Si es diferente, entonces sabes que la estructura ha cambiado.

Consulta de ejemplo para devolver información sobre todas las columnas de la tabla ABC (lo ideal es enumerar solo las columnas de la tabla INFORMACIÓN_SCHEMA que desea, en lugar de usar *select ** como hago aquí):

select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'ABC'

Supervisaría diferentes columnas y vistas INFORMACIÓN_SCHEMA dependiendo de cómo defina exactamente los "cambios en una tabla".

Suposición salvaje aquí:Si no desea modificar las tablas de terceros, ¿puede crear una vista y luego activar un activador en esa vista?

Verifique la última fecha de confirmación.Cada base de datos tiene un historial de cuándo se realiza cada confirmación.Creo que es un estándar de cumplimiento de ACID.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top