2016-05-26 8 views
-1

Ist es mit einem Auslöser möglich, die Abfrage oder primäre ID der Abfrage zu erhalten, die sie ausgelöst hat?Suche nach einer Abfrage, die einen Auslöser ausgelöst hat

Derzeit etwa haben wir:

Delete from Table1 where id = 1 

(id die primäre ID der Tabelle ist, 1 ist nur ein Beispiel Datensatz)

Ich möchte ist, um die Abfrage oder die id der Zeile anmelden gelöscht (weil jemand Datensätze falsch löscht (nicht bösartig)). Dies schien, als wäre es ein einfacher Prozess mit einem trigger und BEFORE DELETE ON, aber ich kann nicht herausfinden, wie die übergeordnete Abfrage, die die trigger auslösen ausgelöst hat.

ich geplant haben:

DELIMITER $$ 
    CREATE TRIGGER Table1_Row_Being_Deleted 
     BEFORE DELETE ON Table1 
      INSERT INTO deleted_Table1 (deleting_date, tableid) values(now(), ?); 
    END$$ 
DELIMITER; 

Aber ich weiß nicht, was für die ? zu setzen. Alle anderen Threads und Dokumente, die ich gesehen habe, hatten statische Werte oder betrafen jede Zeile in der Tabelle.

+0

Die ID, die gelöscht wird, ist 'old.id'. Der Tabellenname ist 'Table1' (ein Trigger gehört immer zu einer bestimmten Tabelle, daher kennen Sie den Tabellennamen, wenn Sie den Trigger erstellen). Sie sollten 'FÜR JEDE ZEILE 'verwenden, sonst protokollieren Sie nicht mehrere Löschungen. Und Sie können nicht wissen, welche Anweisung versucht, die Zeile zu löschen. Und Sie werden auch dann protokollieren, wenn das Löschen später fehlschlägt (z. B. wegen eines Fremdschlüssels). Sie können 'nach dem Löschen 'verwenden, um nur erfolgreiche Löschungen zu protokollieren. – Solarflare

+0

'Sie können nicht wissen, welche Anweisung versucht, die Zeile zu löschen 'Das ist genau das, was ich wissen muss. Es gibt kein Ereignis auf Systemebene, von dem aus es zurückverfolgt werden kann?Wenn ich 'after delete' benutze ist die Aufnahme nicht schon weg oder ist sie temporär im Speicher gespeichert und trotzdem erreichbar? Es werden nie zwei gelöschte Datensätze in einer Abfrage vorhanden sein, so dass ich mir keine Gedanken über mehrere Löschungen in einer Abfrage machen muss. – chris85

+1

'alt' ist eine spezielle Zeile, die den Wert auch nach dem Löschen enthält. Um Ihre Anfrage zu verfolgen, sollten Sie 'performance_schema.events_statements' und/oder' performance_schema.events_statements_history' auschecken (Sie müssen eine Option für den letzten festlegen), sie enthalten aktive und vergangene Querys. Sie sind nicht direkt mit Ihrem Triggerereignis verknüpft, aber Sie können sie irgendwie verlinken (zB durch einen Zeitstempel oder durch Überprüfung, ob der Tabellenname in der Zeichenkette ist, obwohl es natürlich möglich ist, eine Zeile indirekt zu löschen, so der Tabellenname) nicht im Querytext sein, oder mehrere Queries speichern und später prüfen) – Solarflare

Antwort

1

Es gibt keine direkte Verbindung zwischen dem Auslöser und der Abfrage, die den Auslöser ausgelöst hat. Sie können aber die verwenden, um alle aktiven Abfragen zu suchen und sie zu protokollieren. Einer von ihnen sollte die Abfrage des Anrufers sein.

Dies wird jede aktive Abfrage protokollieren, und daher eine Menge Lärm, weil die richtige Abfrage nicht bekannt ist. Da es sich um eine indirekte Abfrage handeln kann (z. B. von einer Prozedur), enthält die richtige Abfrage nicht immer einen unterscheidbaren Teil wie "delete from table1". Suchen Sie nach häufigen Abfragen, die bei jedem Auftreten des Problems in der Protokolltabelle erscheinen.

ich verwendet, um einen after delete Trigger hier, so wird es nur anmelden, wenn delete gelang es Sie vielleicht einen before delete Trigger verwenden möchten auch anmelden, wenn die delete später fehl (zum Beispiel wegen der Fremdschlüssel).

old.id (und die ganze Zeile old) enthält die Werte, die die Zeile hatte, bevor es gelöscht wurde (damit Sie es hier noch verwenden können, um den Eintrag zu protokollieren).

Die und die events_statements_current -log sind normalerweise standardmäßig aktiviert. Überprüfen Sie das Ergebnis von

select * from performance_schema.events_statements_current; 

Es sollte mindestens eine Zeile mit diesem select -query selbst enthalten (da, dass eine aktive Abfrage war zu dieser Zeit). Wenn es leer ist (oder Sie keine Berechtigung haben, es zu verwenden oder es nicht existiert), sollten Sie prüfen, ob show variables like 'performance_schema';ON anzeigt. Möglicherweise müssen Sie Berechtigungen oder Protokollierungsoptionen festlegen, siehe Query Profiling Using Performance Schema.