¿Buscar cambios en una tabla de SQL Server?

votos
122

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

Me gustaría ser compatible con cualquier SQL Server 2000 SP4 o posterior. Mi aplicación es una visualización de datos atornillada para el producto de otra compañía. Nuestra base de clientes es de miles, por lo que no quiero tener que establecer requisitos para modificar la tabla del proveedor de terceros en cada instalación.

Por cambios en una tabla me refiero a los cambios en los datos de la tabla, no a los cambios en la estructura de la tabla.

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


El mejor curso de acción dado mis requisitos (sin disparadores o modificación de esquema, SQL Server 2000 y 2005) parece ser utilizar la BINARY_CHECKSUMfunción 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 compare eso con el valor almacenado. Si el valor ha cambiado, recorra la tabla fila por fila usando la consulta:

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

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

Publicado el 01/08/2008 a las 13:35
fuente por usuario
En otros idiomas...                            


8 respuestas

votos
90

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 y cuando los contenidos de la tabla no hayan cambiado. Ver mi publicación en esto para más información:

CHECKSUM

Así es como lo usé para reconstruir las dependencias de caché cuando cambian las tablas:
dependencia de caché de base de datos ASP.NET 1.1 (sin desencadenantes)

Respondida el 02/08/2008 a las 06:20
fuente por usuario

votos
30

Desafortunadamente suma de comprobación no siempre funciona correctamente para detectar cambios . Es solamente una suma de verificación primitiva y sin cálculo CRC. Por lo tanto no se puede utilizar para detectar todos los cambios, por ejemplo, cambios simétricos resultan en la misma SUMA DE CONTROL!

P.ej. la solución con CHECKSUM_AGG(BINARY_CHECKSUM(*))entrega siempre 0 para todas las 3 mesas 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!

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

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

Respondida el 30/03/2011 a las 13:07
fuente por usuario

votos
25

¿Por qué no quieres usar disparadores? Son algo bueno si los usa correctamente. Si los usa como una forma de reforzar la integridad referencial, es cuando pasan de buenos a malos. Pero si los usa para monitorear, en realidad no son considerados tabú.

Respondida el 01/08/2008 a las 14:07
fuente por usuario

votos
19

¿Con qué frecuencia necesita verificar los cambios y qué tan grande (en términos de tamaño de fila) son las tablas en la base de datos? Si usa el CHECKSUM_AGG(BINARY_CHECKSUM(*))método sugerido por John, escaneará cada fila de la tabla especificada. La NOLOCKsugerencia ayuda, pero en una base de datos grande, todavía está golpeando cada fila. También necesitará almacenar la suma de verificación para cada fila para que diga que una ha cambiado.

¿Has considerado ir a 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 hace la base de datos?

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

La parte difícil sería convencer al vendedor de la aplicación para que implemente esta característica. Dado que esto puede manejarse completamente a través de SQL a través de desencadenantes, usted podría hacer la mayor parte del trabajo escribiendo y probando los desencadenantes y luego llevando el código al proveedor de la aplicación. Al hacer que el proveedor admita los desencadenantes, evita que la situación en la que agrega un activador inadvertidamente reemplace un desencadenador suministrado por el proveedor.

Respondida el 03/08/2008 a las 14:59
fuente por usuario

votos
18

Tener un trabajo DTS (o un trabajo que se inicia con un servicio de Windows) que se ejecuta en un intervalo determinado. Cada vez que se ejecuta, obtiene información sobre la tabla dada utilizando las tablas INFORMATION_SCHEMA del sistema y registra estos datos en el depósito 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.

Ejemplo de consulta para devolver información con respecto a todas las columnas en la tabla ABC (idealmente enumerar solo las columnas de la tabla INFORMATION_SCHEMA que desee, en lugar de usar * select ** como hago aquí):

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

Debería supervisar diferentes columnas y vistas de INFORMATION_SCHEMA según cómo defina exactamente "cambios en una tabla".

Respondida el 01/08/2008 a las 15:06
fuente por usuario

votos
17

Lamentablemente, no creo que haya una forma clara de hacerlo en SQL2000. Si reduce sus requisitos a SQL Server 2005 (y posterior), entonces está en el negocio. Puedes usar la SQLDependencyclase en System.Data.SqlClient. Consulte Notificaciones de consultas en SQL Server (ADO.NET) .

Respondida el 06/08/2008 a las 02:54
fuente por usuario

votos
13

Supongo aquí: si no quieres modificar las tablas de un tercero, ¿puedes crear una vista y luego poner un activador en esa vista?

Respondida el 05/08/2008 a las 02:12
fuente por usuario

votos
7

Comprobar la última fecha de comprometerse. Cada base de datos tiene un historial de cada confirmación cuando se hace. Creo que es una norma de cumplimiento de ACID.

Respondida el 24/07/2014 a las 05:58
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more