2013-02-05 15 views
6

Ho una tabella con 120 colonne. Ho bisogno di impostare audit trail che registrerebbe qualsiasi colonna se fosse stata modificata. Come è ora, mi sa che devo impostare un trigger con condizione di qualcosa di simile per ogni colonna:Trigger di aggiornamento MySQL: trova le colonne modificate?

IF(NEW.columnName != OLD.columnName) 
THEN //log the old value 

Ciò dovrebbe essere fatto 120 volte ... Mentre io avrei accettato questo approccio 20 anni fa, oggi mi rifiuto di credere che sia impossibile automatizzare una procedura così semplice trovando automaticamente le colonne modificate.

Questo è quello che ho scoperto finora:

  • né nuovo né vecchio è un tavolo, è una sorta di un costrutto del linguaggio, Perciò non si può fare o qualcosa di simile "SELECT NOW *.".
  • SQL dinamico non consentito nei trigger (questo potrebbe aver risolto il problema).
  • Le procedure che utilizzano SQL dinamico non sono consentite nei trigger (seriamente, Oracle, sembra che tu abbia lavorato davvero duramente per disabilitare questa funzione, non importa quale).

Stavo pensando di utilizzare i trigger BEFORE e AFTER in combinazione con tabelle e variabili temporanee che avrebbero probabilmente risolto il problema, tuttavia ancora una volta sarebbe richiesto un SQL dinamico. Mi sento come se avessi colpito un vicolo cieco.

C'è una soluzione a questo?

Una domanda a margine: sarebbe possibile in PostgreSQL?

UPDATE: Ho trovato 2 possibili soluzioni ma nessuno di loro sembrano abbastanza chiaro per me:

  • utilizzando EVENTI come una soluzione per utilizzare i trigger in combinazione con SQL dinamico workaround. Devo ammettere che non lo capisco, questo significa che l'EVENTO spara ogni secondo, non importa quale?
  • This article afferma che è possibile utilizzare SQL dinamico all'interno del trigger purché venga utilizzata una tabella temporanea. Questo è ancora utilizzando SQL dinamico, quindi non capisco.
+0

Hai controllato questo con [Session Information Functions in Postgres come per la tua ultima domanda] (http://stackoverflow.com/questions/8759595/within-a-trigger-function-how-to-get-which-fields-are-being-updated) – bonCodigo

+0

@bonCodigo Grazie, apparentemente PostgreSQL è più flessibile in questo caso. – Caballero

risposta

1

interessante, mi trovavo ad affrontare lo stesso problema un paio di anni fa con l'implementazione del registro di controllo dinamico basato su trigger. La soluzione che ho trovato era semplicemente generare il codice di trigger SQL che poi può essere (automaticamente) applicato per sostituire le vecchie definizioni di trigger. Se la memoria serve, ho creato alcuni modelli SQL che sono stati elaborati da uno script PHP che a sua volta stava emettendo definizioni di trigger complete basate su "SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE ..." Sì, il codice di attivazione era enorme, ma ha funzionato! Spero che questo aiuti un po '=)

+2

Grazie per la risposta, tuttavia l'unica ragione per cui ho scelto di utilizzare i trigger è che non avrei dovuto coinvolgere PHP - se avessi scelto di implementare questa funzionalità con PHP questa domanda non esisterebbe. Ho un enorme sistema già codificato in PHP e se dovessi andare lì e implementare audit nel codice sarebbe un suicidio. – Caballero

0

ho fatto questo per uno dei progetti creando un tavolo ombra.se non si tratta di milioni di aggiornamenti, questo potrebbe funzionare

  • quando l'utente accede a, SET @user_id = {utente collegato id}
  • creare un trigger sul tavolo prima di aggiornamento per copiare la fila da modificare in una tabella shadow con la stessa struttura (si noti che non è possibile avere una chiave primaria nella tabella shadow né chiavi univoche)
  • aggiungere ulteriori colonne alla tabella shadow (modified_by, modified_on)
  • creare un piccolo php script per mostrare la differenza tra le colonne - in questo modo non devi modificare il codice php esistente
  • se hai a che fare con molti aggiornamenti e vuoi mantenere la tabella shadow piccola, puoi scrivere un cron per analizzare la tabella shadow e identificare quale colonna è cambiata e memorizzare queste informazioni su un'altra tabella
Problemi correlati