Bestimmte einträge in allen Tabellen suchen und löschen
pazan777
- datenbank
Hallo @ alle,
ich bin neu bei MySQL und hab ein Problem:
es gibt ein MySQL Datenbank auf dem Linux Server. PHP ist nicht installiert und darf auch nicht installiert werden.
Datenbank hat über 50 Tabellen. Fast alle Tabellen haben "UserID"-Spalte.
Es sollen alle Einträge in allen Tabellen gelösct werden, die ein UserID="1006798" haben.
Gibt es eine Schnellere methode als löschen in allen Tabellen per Hand? Ich habe über SQL scripte gehört aber habe keine Ahnung was das ist.
Danke,
Dimitrij
Hello Dimitrij,
es gibt ein MySQL Datenbank auf dem Linux Server. PHP ist nicht installiert und darf auch nicht installiert werden.
Mit welchem Benutzerinterface kannst Du auf die Datenbank zugreifen?
Datenbank hat über 50 Tabellen. Fast alle Tabellen haben "UserID"-Spalte.
----
???
Es sollen alle Einträge in allen Tabellen gelösct werden, die ein UserID="1006798" haben.
Schreib Dir eine Stored Procedure
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Hallo Tom,
danke für schnelle Antwort.
Was meinst du mit welchem Interface ich auf DB zugreife?
Ich verbinde mich mit dem Server über Putty (das ist ein SSH Client).
Sobald ich auf dem Server bin starte ich MySQL mit:
/usr/local/mysql/bin/mysql ....
dann wird mein DB geöffnet und ich kann nur mit Hilfe von SQL-Befehlen arbeiten. Alles sieht wie normale Konsole aus.
Und es wirklich so dass nicht alle Tabellen UserID-Spalte haben, aber die meisten.
Was ist ein Stored Procedure weiss ich auch nicht.
Gruss
Dimitrij
Hello,
danke für schnelle Antwort.
bitte, das mache ich gerne, wenn ich glaube, helfen zu können.
Was meinst du mit welchem Interface ich auf DB zugreife?
Ich verbinde mich mit dem Server über Putty (das ist ein SSH Client).
Sobald ich auf dem Server bin starte ich MySQL mit:
/usr/local/mysql/bin/mysql ....
OK. Du benutzt also die "MySQL-Shell über Remote-Konsole"
Das hatte ich irgendwie erwartet.
Was ist ein Stored Procedure weiss ich auch nicht.
Du müsstest mal verschiedene Dinge feststellen:
Welche Version hat das DBMS --> select version();
Welche Rechte hast Du? --> show grants for <username>;
Danach kann man mehr Tipps geben (oder auch nicht).
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Danke nochmals,
ich bin positiv schockiert :-),dass es solche Leute wie Du gibt, die so schnell hilfsbereit sind.
Also:
root@localhost [ser]> select version();
+---------------------------+
| version() |
+---------------------------+
| 5.0.24-br9921-cluster-log |
+---------------------------+
1 row in set (0.00 sec)
und ich bin root.
root@localhost [ser]> select version();
+---------------------------+
| version() |
+---------------------------+
| 5.0.24-br9921-cluster-log |
+---------------------------+
1 row in set (0.00 sec)
Du solltest problemlos ein DELETE mit einer WHERE-Klausel über alle Tabellen der Datenbank machen können.
Siechfred
Hello,
Du solltest problemlos ein DELETE mit einer WHERE-Klausel über alle Tabellen der Datenbank machen können.
*hups*
Wie müsste denn so ein Statement aussehen, wenn man es nicht beliebig in Subselects verklausulieren wollte?
Da bin ich jetzt wirklich gespannt.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Hallo,
ich bin sehr dankbar für die schnelle Antworten, aber Ihr redet für mich zu kompliziert.
Also ist es mit WHERE-Klausel nicht möglich, oder was?
ich kann nätürlich 50 mal schreiben:
DELETE * FROM tabellenname WHERE UserID="1006798";
Aber 10 UserIDs die überall gelöscht werden sollen.
das ist dann 10 x 50 = 500 Befehle!!!
gibt es schnellere Methoden?
Danke,
Dimitrtij
Hello,
gibt es schnellere Methoden?
Beim ersten Mal da tut's noch weh ist ein alter Spruch, der aber meistens stimmt.
Das bedeutet, dass Du schneller sein wirst, alle 500 Befehle (mittels Copy & Paste) zu erzeugen, als die Prozeduren und Funktionen zu schreiben.
Wenn das Problem aber öfter vorkommt, lohnt es sich, ein Werkzeug zu bauen.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Hello,
DELETE * FROM (tabellenname1, tabellenname2, tabellenname3) WHERE UserID in (1006798,1000815,2003791,0000007,9999999);
Schleifen kannst Du meines Wissens nach in der mysql-shell nicht definieren.
Das Problem ist, dass Du keine Liste der Tabellenamen hast und nicht weißt, in welchen Tabellen die Spalte UserID vorhanden ist. Das musst Du eben durch Prigrammlogic oder durch Fleiß ermitteln.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Hallo
DELETE * FROM tabellenname WHERE UserID="1006798";
Aber 10 UserIDs die überall gelöscht werden sollen.
das ist dann 10 x 50 = 500 Befehle!!!
nein, einer - wie Siechfred bereits schrieb.
DELETE -- kein * in MySQL (bereits verlinkt)
FROM
tabelle1,
tabelle2,
...,
tabelle50
WHERE
UserID [link:http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_in@title=IN] (ersteid, zweiteid, ..., zehnteid)
Freundliche Grüße
Vinzenz
Hello,
nein, einer - wie Siechfred bereits schrieb.
Wie geht das, wenn man doch nicht nachgeschaut hat, ob die Spalte UserID in der Tabelle vorhanden ist.
Bei der ersten Tabelle, bei der das nicht der Fall ist, gibt es doch einen Abbruch, oder?
Das Statement hatte ich schon verzapft in https://forum.selfhtml.org/?t=162719&m=1059208, aber leider den Stern stehenlassen. Du siehst also, ohne Deine Kontrolle geht es noch nicht. Ich brauch Dich eben :-))
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Danke für Antwort,
aber leider ich musste trotztdem alle tabellen per hand duchgehen.
Weil:
DELETE FROM tabelle1, tabelle2 WHERE UserID IN (12386,23744,94493);
hat nicht funkt:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where uid in (12386,23744,94493);' at line 1
es hat NUR so funk:
DELETE FROM tabelle1 WHERE UserID IN (12386,23744,94493);
deshalb musste ich alle tabellen durchlaufen.
Gruss,
Dimitrij
Hallo
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where uid in (12386,23744,94493);' at line 1
ja, Du müsstest die WHERE-Klausel gewaltig ergänzen - nämlich mit einer
ODER-Verknüpfung und qualifizierten Tabellennamen. Das hatte ich in der
Tat übersehen.
Diese Aufgabe scheint eine typische Aufgabe für Foreign-Key-Constraints
mit ON DELETE CASCADE-Klausel zu sein. Bei MySQL ist die Verwendung der
InnoDB-Engine bei beteiligten Tabellen Voraussetzung.
Freundliche Grüße
Vinzenz
Da bin ich jetzt wirklich gespannt.
Es gibt SHOW TABLES, das Ergebnis kann man ohne Not in das DELETE-Statement einsetzen. Zwar erfordert das etwas Tipparbeit, das ist für einen Anfänger m.E. allemal schneller, als sich in Stored Procedures usw. einzuarbeiten.
Siechfred
Hello,
Es gibt SHOW TABLES, das Ergebnis kann man ohne Not in das DELETE-Statement einsetzen. Zwar erfordert das etwas Tipparbeit, das ist für einen Anfänger m.E. allemal schneller, als sich in Stored Procedures usw. einzuarbeiten.
Hab ich auch nicht bezweifelt. Aber es fehlt dann immer noch die Info, ob die jeweilige Tabelle denn überhaupt eine Spalte UserID hat.
Ich habe noch kein "Show Tables" in ein Delete-Statement eingebaut. Wie muss das Statement lauten?
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Hab ich auch nicht bezweifelt. Aber es fehlt dann immer noch die Info, ob die jeweilige Tabelle denn überhaupt eine Spalte UserID hat.
Ich ging davon aus, dass alle Tabellen diese Spalte haben, wenn nicht, macht es das natürlich komplizierter.
Ich habe noch kein "Show Tables" in ein Delete-Statement eingebaut. Wie muss das Statement lauten?
Nee, ich meinte nicht, dass Du SHOW TABLES in das DELETE-Statement einbauen sollst, sondern nacheinander aufrufen und dann abtippen. Wie gesagt, ich halte das für einen *Anfänger* (wie ich auch einer bin) für den besten Weg. Wer kein Anfänger mehr ist oder keiner mehr sein will, sollte sich aber dann doch an den Vorschlägen von Dir, Vinzenz und "db3" orientieren.
Siechfred
Hello,
Nee, ich meinte nicht, dass Du SHOW TABLES in das DELETE-Statement einbauen sollst, sondern nacheinander aufrufen und dann abtippen.
Das hat Dimitrij dann wohl auch gemacht. Es lohnt sich für einmal Anwenden auch nicht wirklich, sowas zu bauen. Ich habe mir da zwar nochmal als Übungsuafgabe vorgenommen gestern, aber es ist nicht so trivial. Vinzenz wird es vielleicht sogar in einem Statement unterbringen, aber da bin ich eben auch Anfänger... Ich brauche mindestens drei ode vier dafür.
Wie gesagt, ich halte das für einen *Anfänger* (wie ich auch einer bin) für den besten Weg. Wer kein Anfänger mehr ist oder keiner mehr sein will, sollte sich aber dann doch an den Vorschlägen von Dir, Vinzenz und "db3" orientieren.
Solche Fragestellungen sind aber guter Trainingsstoff.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Hello,
Danke nochmals,
ich bin positiv schockiert :-),dass es solche Leute wie Du gibt, die so schnell hilfsbereit sind.
Wart's ab wenn erst die Wächter kommen, die aufpassen, dass ich nichts verkehrtes erzähle...
Die sind dann zwar schnell genervt, aber sie passen wenigstens auf :-))
root@localhost [ser]> select version();
+---------------------------+
| version() |
+---------------------------+
| 5.0.24-br9921-cluster-log |
+---------------------------+
1 row in set (0.00 sec)
Das könnte problematisch werden. Da muss ich selber erstmal nachlesen, ob meine Ideen schon funktionieren können oder rufen nach den anderen Geistern (dedlfix, Vinzenz)...
Jedenfalls könntest Du Die eine Auszugstabelle erstellen, welche Tabellen es gibt.
Dann könntest du deren Strukturen einsammeln unter Nutzung der Auzugstabelle und dann diese Tabelle filtern nach "id_user" und ein update darauf aufbauen.
Das müsste sogar mit wenigen Befehlen auf der Konsole gehen. Habe ich aber selber noch nie gemacht. Wird langsam Zeit, auch mal sowas praktisch zu versuchen...
und ich bin root.
Das solltest Du schnell ändern, wenn es keinen weiteren Zugang mit diesen Rechten mehr gibt.
Es könnte etwas schiefgehen und Du wärst ausgesperrt.
Grant all on *.* to 'superuser'@'%' with grant options;
Und dann möglichst diesem "superuser" sie Rechte auf das Objekt "root" entziehen, aber das geht wohl noch nicht in MySQL, zumindest weiß ich noch nicht, wie es geht.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
test
welche die Spalte UserId
besitzen.SELECT CONCAT('DELETE FROM test
.', table\_name, '
WHERE UserId=1006798;')
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema = 'test' AND column_name = 'UserId'
INTO OUTFILE '/tmp/delete.sql';
in /tmp/delete.sql stehen dann die einzelnen Kommandos für jede Tabelle, dieses kannst du dann von der Konsole mit mysql ausführen lassen
$ mysql < /tmp/delete.sql