Hallå!
Fråga: Vilket SQL-kommando kan jag använda för att ta bort alla tabeller med ett visst prefix?
Bakgrund:
På mitt webhotell har jag ett antal Drupal-installationer, och det är dags att ta bort ett par av dem. Tidigare har jag använt phpMyAdmin för att ta bort tabeller, och eftersom jag angett olika tabellprefix för varje installation har det gått finfint att identifiera rätt tabeller och radera dem. Detta har jag tidigare gjort genom klicka-klicka-klicka-metoden, och jag börjar bli trött på den.
Det måste ju finnas ett sätt att köra typ "DROP DR5_*" i mySQL. Efter att ha letat runt på nätet hittar jag inget så snabbt och enkelt (utan bara php-skript för samma ändamål), och jag tänkte att jag skulle slippa lära mig hela SQL-syntaxen för denna specifika uppgift.
Min gissning är att det är en barnlek för någon som kan SQL, så jag frågar här.
Må väl!
//Johan, Uppsala

Comments
STORED PROCEDURES
Om du använder dig av MySQL version >=5.0 så kan du använda dig av stored procedures. Efter ha läst på lite här så kan du skapa en procedur, typ:
CREATE PROCEDURE remove_drupal_installation (prefix VARCHAR(40))BEGIN
DROP CONCAT(prefix, '_action');
DROP CONCAT(prefix, '_access');
DROP CONCAT(prefix, '_actions');
DROP CONCAT(prefix, '_actions_aid');
DROP CONCAT(prefix, '_authmap');
DROP CONCAT(prefix, '_batch');
DROP CONCAT(prefix, '_blocks');
DROP CONCAT(prefix, '_blocks_roles');
DROP CONCAT(prefix, '_boxes');
DROP CONCAT(prefix, '_cache');
DROP CONCAT(prefix, '_cache_block');
DROP CONCAT(prefix, '_cache_filter');
DROP CONCAT(prefix, '_cache_form');
DROP CONCAT(prefix, '_cache_menu');
DROP CONCAT(prefix, '_cache_page');
DROP CONCAT(prefix, '_cache_update');
DROP CONCAT(prefix, '_comments');
DROP CONCAT(prefix, '_contact');
DROP CONCAT(prefix, '_devel_queries');
DROP CONCAT(prefix, '_devel_times');
DROP CONCAT(prefix, '_faq_expert');
DROP CONCAT(prefix, '_faq_questions');
DROP CONCAT(prefix, '_faq_weights');
DROP CONCAT(prefix, '_files');
DROP CONCAT(prefix, '_filter_formats');
DROP CONCAT(prefix, '_filters');
DROP CONCAT(prefix, '_flood');
DROP CONCAT(prefix, '_forum');
DROP CONCAT(prefix, '_history');
DROP CONCAT(prefix, '_i18n_blocks');
DROP CONCAT(prefix, '_i18n_strings');
DROP CONCAT(prefix, '_i18n_variable');
DROP CONCAT(prefix, '_languages');
DROP CONCAT(prefix, '_locales_source');
DROP CONCAT(prefix, '_locales_target');
DROP CONCAT(prefix, '_menu_custom');
DROP CONCAT(prefix, '_menu_links');
DROP CONCAT(prefix, '_menu_router');
DROP CONCAT(prefix, '_node');
DROP CONCAT(prefix, '_node_access');
DROP CONCAT(prefix, '_node_comment_statistics');
DROP CONCAT(prefix, '_node_counter');
DROP CONCAT(prefix, '_node_revisions');
DROP CONCAT(prefix, '_node_type');
DROP CONCAT(prefix, '_permission');
DROP CONCAT(prefix, '_poll');
DROP CONCAT(prefix, '_poll_choices');
DROP CONCAT(prefix, '_poll_votes');
DROP CONCAT(prefix, '_profile_fields');
DROP CONCAT(prefix, '_profile_values');
DROP CONCAT(prefix, '_role');
DROP CONCAT(prefix, '_search_dataset');
DROP CONCAT(prefix, '_search_index');
DROP CONCAT(prefix, '_search_node_links');
DROP CONCAT(prefix, '_search_total');
DROP CONCAT(prefix, '_sessions');
DROP CONCAT(prefix, '_system');
DROP CONCAT(prefix, '_term_data');
DROP CONCAT(prefix, '_term_hierarchy');
DROP CONCAT(prefix, '_term_node');
DROP CONCAT(prefix, '_term_relation');
DROP CONCAT(prefix, '_term_synonym');
DROP CONCAT(prefix, '_trigger_assignments');
DROP CONCAT(prefix, '_upload');
DROP CONCAT(prefix, '_url_alias');
DROP CONCAT(prefix, '_users');
DROP CONCAT(prefix, '_users_roles');
DROP CONCAT(prefix, '_variable');
DROP CONCAT(prefix, '_vocabulary');
DROP CONCAT(prefix, '_vocabulary_node_types');
DROP CONCAT(prefix, '_watchdog');
END
Du plockar sedan bort en standardinstallation med:
CALL remove_drupal_installation ('mitt_prefix');Notera att ovanstående PROCEDURE är gjord för Drupal 6.0-standardinstallation och att den inte funkar för extra tabeller som har skapats av extramoduler. Vill man kunna ta bort alla tabeller med ett visst prefix så går det att skriva som en procedure också (genom SELECTs från mysql-tabellen) men det finns vissa säkerhetsfördelar med att ha tabellnamnen hårdkodade - t.ex. så hade i så fall
CALL remove_drupal_installation ('');råkat ta bort alla tabeller i databasen, eftersom alla har noll-prefixet. Mindre bra.
Justja, jag har inte testat ovanstående kod, så den kan behöva lite tweaking. :-)
mvh
Jens
...och nej, den här idéen
...och nej, den här idéen kanske inte var den barnleken du letade efter :-P
DROP _TABLE_
Ooops, varje rad i proceduren skulle såklart vara
[...]DROP TABLE CONCAT(prefix, '_tabellnamn');
[...]
/J
Funkar det inte att köra
Funkar det inte att köra markera alla -> töm för en databas i phpMyAdmin annars? Tror inte man skall behöva klicka varje enskild tabell.
Tackar
Tackar för idéer och förslag!
Att skriva en stored procedure passar tyvärr dåligt, eftersom det orsakar mig minst lika mycket jobb som att klicka i varje enskild tabell och sedan radera. Hade alla mina installationer sett lika dana ut hade det varit en vinst i längden, men eftersom jag har lite olika moduler (och därmed tabeller) i olika installationer är det inte så mycket vunnet.
Att markera alla -> radera är en möjlighet, men bara om jag vill rensa bort alla installationer på en gång. Däremot fick det mig att komma på en smidig lösning, som jag nu testat och verifierat. Den går ut på att
(1) markera alla -> radera
(2) INTE trycka ok, utan kopiera tabellnamnen jag vill radera (i mitt fall
test_access...test_xmlsitemap_node)(3) gå till SQL-fliken och skriva in DROP TABLE och klistra in alla tabellnamnen.
Det funkar snabbt och smidigt, även om det inte riktigt är den "drop table prefix_*"-lösningen jag var ute efter.
Tjoho!
//Johan Falk, Uppsala
PS: Jag ändrar status på detta inlägg till "Så gör man", men säg gärna till om fler förslag på lösningar dyker upp.
En annan mer generell
En annan mer generell lösning vore ju att skriva ett phpscript där du anger vilket prefix alla tabeller du vill ta bort har och sedan använder
SHOW TABLES för att se alla tabeller, och därefter gå igenom alla rader du får tillbaka och lägga alla de som har prefixet som angetts i en array och därefter köra drop på tabellerna i arrayen.
I sådana fall skulle ju alla tabeller komma med, Det enda man bör tänka på är säkerheten förstås. Bästa varianten vore väl att i scriptet bara definiera vilket prefix som ska tas bort och sedan ladda upp scriptet bara när du ska använda det och sedan ta bort det.
Jag skulle gärna skrivit ett sådant script men just nu har jag inte riktigt tid ;)
//Fabian Sörqvist
Ahh, ok.. Så de ligger i
Ahh, ok.. Så de ligger i samma databas fast med olika prefix? I så fall förstår jag att markera alla lösningen inte är den bästa. :)
Att markera listan i
Att markera listan i phpMyAdmin var en smidig lösning. Annars hittade jag precis det här PHP-scriptet som kanske kunde vara till nån glädje.
EDIT: Scriptet gör i princip det fabian-sorgqvist skrev om.
Jag ramlade över denna fina
Jag ramlade över denna fina lilla terminallösning när jag sökte efter en liknande grej:
mysqldump -u[USERNAME] -p[PASSWORD] --add-drop-table --no-data [DATABASE] | grep ^DROP | mysql -u[USERNAME] -p[PASSWORD] [DATABASE]Du kan lätt anpassa den för ditt behov genom att ändra
grep-biten. Tänk på vad du gör bara och ta backup först!/ Hannes Lilljequist – SthlmConnection