DISABILITARE ADBLOCK

ADBlock sta bloccando alcuni contenuti del sito

ADBlock errore
risultati trovati: 

DOMANDA

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

Mi piacerebbe poter supportare qualsiasi SQL Server 2000 SP4 o versioni successive . La mia applicazione è una visualizzazione di dati imbullonati per il prodotto di un'altra azienda. La nostra base di clienti è a migliaia, quindi non voglio inserire requisiti che modifichino la tabella del fornitore di terze parti ad ogni installazione.

Per " 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 controllare le modifiche a intervalli.


Il miglior modo di agire dato i miei requisiti (nessun trigger o modifica dello schema, SQL Server 2000 e 2005) sembra essere quello di usare la funzione BINARY_CHECKSUM in T-SQL . Il modo in cui intendo implementare è questo:

Ogni X secondi esegue la seguente query:

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

E confrontalo con il valore memorizzato. Se il valore è stato modificato, scorrere 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.

SOLUZIONE

Dai un'occhiata al comando CHECKSUM:

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

Questo restituirà lo stesso numero ogni volta che viene eseguito, purché il contenuto della tabella non sia cambiato. Vedi il mio post su questo per ulteriori informazioni:

CHECKSUM

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)

Se ti va lasciaci una tua opinione

L'articolo ti è stato utile ed è tradotto correttamente?

ALTRI SUGGERIMENTI

Purtroppo CHECKSUM non sempre funziona correttamente per rilevare le modifiche .

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

Pertanto non è possibile utilizzarlo per rilevare tutte le modifiche, e. g. cambiamenti simmetrici producono lo stesso CHECKSUM!

E. g. la soluzione con CHECKSUM_AGG (BINARY_CHECKSUM (*)) fornirà sempre 0 per tutte e 3 le tabelle con contenuto diverso:


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!

Perché non vuoi usare i trigger? Sono una buona cosa se li usi correttamente. Se li usi come un modo per imporre l'integrità referenziale, cioè quando vanno di bene in male. Ma se li usi per il monitoraggio, non sono davvero considerati tabù.

Con quale frequenza è necessario verificare la presenza di modifiche e quanto sono grandi (in termini di dimensioni delle righe) le tabelle nel database? Se usi il metodo CHECKSUM_AGG (BINARY_CHECKSUM (*)) suggerito da John, eseguirà la scansione di ogni riga della tabella specificata. Il suggerimento NOLOCK aiuta, ma su un database di grandi dimensioni, stai ancora colpendo ogni riga. Dovrai anche archiviare il checksum per ogni riga in modo da dire che uno è cambiato.

Hai pensato di andare da questo punto di vista? Se non si desidera modificare lo schema per aggiungere trigger (il che ha senso, non è il database), hai preso in considerazione l'idea di lavorare con il fornitore dell'applicazione che crea il database?

Potrebbero implementare un'API che fornisce un meccanismo per notificare alle app accessorie che i dati sono cambiati. 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 ti importerebbe, la tua unica preoccupazione sarebbe la scansione della tabella di notifica su base periodica. Il miglioramento delle prestazioni nel database sarebbe molto inferiore alla scansione di ogni riga alla ricerca di modifiche.

La parte difficile sarebbe convincere il fornitore dell'applicazione a implementare questa funzione. Poiché questo può essere gestito interamente tramite SQL tramite trigger, è possibile eseguire gran parte del lavoro scrivendo e testando i trigger e quindi portando il codice al fornitore dell'applicazione. Avendo il fornitore che supporta i trigger, impedisce la situazione in cui l'aggiunta di un trigger sostituisce inavvertitamente un trigger fornito dal fornitore.

Sfortunatamente, non penso che ci sia un modo pulito per farlo in SQL2000. Se restringi i tuoi requisiti a SQL Server 2005 (e versioni successive), sei in affari. È possibile utilizzare la classe SQLDependency in System.Data.SqlClient . Vedi Notifiche di query in SQL Server (ADO.NET) .

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

Esempio di query per restituire informazioni su tutte le colonne della tabella ABC (elencando idealmente solo le colonne della tabella INFORMATION_SCHEMA che desideri, invece di utilizzare * seleziona ** come faccio qui):

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

Monitoreresti colonne e viste INFORMATION_SCHEMA diverse a seconda di come esattamente definisci " modifiche a una tabella " ;.

Indovina selvaggia qui: se non si desidera modificare le tabelle di terze parti, è possibile creare una vista e quindi attivare un trigger su quella vista?

Controlla l'ultima data di commit. Ogni database ha una cronologia di quando viene eseguito ogni commit. Credo che sia uno standard di conformità ACID.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow