Domanda

Come posso monitorare un database SQL Server per le modifiche a una tabella senza utilizzare trigger o modificare in alcun modo la struttura del database?Il mio ambiente di programmazione preferito è .NETTO e C#.

Mi piacerebbe poter supportare qualcuno SQLServer2000 SP4 o successivo.La mia applicazione è una visualizzazione dati integrata per il prodotto di un'altra azienda.La nostra base di clienti è composta da migliaia di persone, quindi non voglio dover imporre la modifica della tabella dei fornitori di terze parti ad ogni installazione.

Di "modifiche a una tabella" Intendo modifiche ai dati della tabella, non modifiche alla struttura della tabella.

In definitiva, vorrei che la modifica attivasse un evento nella mia applicazione, invece di dover verificare le modifiche a intervalli.


La migliore linea d'azione date le mie esigenze (nessun trigger o modifica dello schema, SQL Server 2000 e 2005) sembra essere quella di utilizzare il BINARY_CHECKSUM funzione dentro T-SQL.Il modo in cui intendo implementarlo è questo:

Ogni X secondi esegui la seguente query:

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

E confrontalo con il valore memorizzato.Se il valore è cambiato, sfoglia la tabella riga per riga utilizzando la query:

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

E confronta i checksum restituiti con i valori memorizzati.

È stato utile?

Soluzione

Dai un'occhiata al comando CHECKSUM:

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

Ciò restituirà lo stesso numero ogni volta che verrà eseguito purché il contenuto della tabella non sia cambiato.Vedi il mio post su questo per maggiori informazioni:

VERIFICA

Ecco come l'ho usato per ricostruire le dipendenze della cache quando le tabelle sono cambiate:
Dipendenza dalla cache del database ASP.NET 1.1 (senza trigger)

Altri suggerimenti

Sfortunatamente CHECKSUM non funziona sempre correttamente per rilevare le modifiche.

Si tratta solo di un checksum primitivo e di nessun calcolo del controllo di ridondanza ciclico (CRC).

Pertanto non è possibile utilizzarlo per rilevare tutte le modifiche, ad es.G.i cambiamenti simmetrici danno come risultato lo stesso CHECKSUM!

E.G.la soluzione con CHECKSUM_AGG(BINARY_CHECKSUM(*)) fornirà sempre 0 per tutte e 3 le tabelle con contenuti diversi:


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!

Seleziona checksum_agg (binary_checksum (*)) da (Selezionare 1 come NUMA, 2 come unione Numb tutti selezionare 1 come NUMA, 2 come NUMB) Q - Fornisce 0!

Seleziona Checksum_AGG (binary_checksum (*)) da (selezionare 0 come NUMA, 0 come unione Numb All Select 0 come NUMA, 0 come Numb) Q - offre 0!

Perché non vuoi usare i trigger?Sono una buona cosa se li usi correttamente.Se li usi come un modo per rafforzare l'integrità referenziale, è allora che passano dal buono al cattivo.Ma se li usi per il monitoraggio, non sono realmente considerati tabù.

Con quale frequenza è necessario verificare le modifiche e quanto sono grandi (in termini di dimensione delle righe) le tabelle nel database?Se usi il CHECKSUM_AGG(BINARY_CHECKSUM(*)) metodo suggerito da John, analizzerà ogni riga della tabella specificata.IL NOLOCK il suggerimento aiuta, ma su un database di grandi dimensioni, stai ancora colpendo ogni riga.Dovrai anche memorizzare il checksum per ogni riga in modo da poter dire che una è cambiata.

Hai considerato di affrontare la cosa da una prospettiva diversa?Se non desideri modificare lo schema per aggiungere trigger (il che ha senso, non è il tuo database), hai considerato di collaborare con il fornitore dell'applicazione che crea il database?

Potrebbero implementare un'API che fornisca un meccanismo per notificare alle app accessorie la modifica dei dati.Potrebbe essere semplice come scrivere in una tabella di notifica che elenca quale tabella e quale riga sono state modificate.Ciò potrebbe essere implementato tramite trigger o codice dell'applicazione.Da parte tua, non avrebbe importanza, la tua unica preoccupazione sarebbe scansionare periodicamente la tabella delle notifiche.L'impatto sulle prestazioni del database sarebbe molto inferiore rispetto alla scansione di ogni riga per individuare eventuali modifiche.

La parte difficile sarebbe convincere il fornitore dell'applicazione a implementare questa funzionalità.Poiché questo può essere gestito interamente tramite SQL tramite trigger, potresti svolgere la maggior parte del lavoro scrivendo e testando i trigger e quindi portando il codice al fornitore dell'applicazione.Facendo in modo che il fornitore supporti i trigger, si evita la situazione in cui l'aggiunta di un trigger sostituisce inavvertitamente un trigger fornito dal fornitore.

Sfortunatamente, non penso che esista un modo pulito per farlo in SQL2000.Se restringi i tuoi requisiti a SQL Server 2005 (e versioni successive), allora sei a posto.Puoi usare il SQLDependency classe dentro System.Data.SqlClient.Vedere Notifiche di query in SQL Server (ADO.NET).

Avere un lavoro DTS (o un lavoro avviato da un servizio Windows) eseguito a un determinato intervallo.Ogni volta che viene eseguito, ottiene informazioni sulla tabella specificata utilizzando il sistema INFORMAZIONI_SCHEMA tabelle e registra questi dati nel repository dati.Confrontare i dati restituiti riguardanti la struttura della tabella con i dati restituiti la volta precedente.Se è diverso, allora sai che la struttura è cambiata.

Query di esempio per restituire informazioni relative a tutte le colonne nella tabella ABC (idealmente elencando solo le colonne della tabella INFORMATION_SCHEMA che desideri, invece di utilizzare *select ** come faccio qui):

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

Monitorerai diverse colonne e viste INFORMAZIONI_SCHEMA a seconda di come definisci esattamente le "modifiche a una tabella".

Ipotesi qui:Se non desideri modificare le tabelle di terze parti, puoi creare una vista e quindi attivare tale vista?

Controlla la data dell'ultimo impegno.Ogni database ha una cronologia di quando viene effettuato ciascun commit.Credo che sia uno standard di conformità ACID.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top