So löschen Sie mehrere Tabellen in PostgreSQL mithilfe eines Platzhalters

84

Bei der Arbeit mit Partitionen müssen häufig alle Partitionen gleichzeitig gelöscht werden.

jedoch

DROP TABLE tablename*

Funktioniert nicht. (Der Platzhalter wird nicht beachtet).

Gibt es eine elegante (sprich: leicht zu merkende) Möglichkeit, mehrere Tabellen in einem Befehl mit einem Platzhalter abzulegen?

Tom Feiner
quelle

Antworten:

117

Verwenden Sie eine durch Kommas getrennte Liste:

DROP TABLE foo, bar, baz;

Wenn Sie wirklich eine Fußwaffe brauchen, erledigt diese ihre Aufgabe:

CREATE OR REPLACE FUNCTION footgun(IN _schema TEXT, IN _parttionbase TEXT) 
RETURNS void 
LANGUAGE plpgsql
AS
$$
DECLARE
    row     record;
BEGIN
    FOR row IN 
        SELECT
            table_schema,
            table_name
        FROM
            information_schema.tables
        WHERE
            table_type = 'BASE TABLE'
        AND
            table_schema = _schema
        AND
            table_name ILIKE (_parttionbase || '%')
    LOOP
        EXECUTE 'DROP TABLE ' || quote_ident(row.table_schema) || '.' || quote_ident(row.table_name);
        RAISE INFO 'Dropped table: %', quote_ident(row.table_schema) || '.' || quote_ident(row.table_name);
    END LOOP;
END;
$$;

SELECT footgun('public', 'tablename');
Frank Heikens
quelle
3
Danke für die Antwort! Eine durch Kommas getrennte Liste eignet sich hervorragend zum Löschen einer kleinen Liste von Tabellen. Es ist jedoch nicht praktisch, 20 Tische gleichzeitig (oder mehr) zu löschen. Ich werde die Frage neu ausrichten, um sie klarer zu machen.
Tom Feiner
2
Entschuldigung, dies ist die einzige Option, die Sie haben. Sie könnten eine gespeicherte Funktion dafür
erstellen
4
Funktion hinzugefügt, viel Spaß! Und seien Sie vorsichtig, dies könnte Ihre gesamte Datenbank zerstören.
Frank Heikens
fehlt nur ein || ' CASCADE ';und es ist perfekt
MFARID
28

Hier ist eine weitere hackige Antwort auf dieses Problem. Es funktioniert in ubuntuund vielleicht auch in einem anderen Betriebssystem . \dtFühren Sie eine In-Postgres-Eingabeaufforderung aus (die Eingabeaufforderung wurde genome-terminalin meinem Fall ausgeführt). Dann sehen Sie viele Tabellen im Terminal. Verwenden Sie nun die ctrl+click-dragFunktionalität von, um die genome-terminalNamen aller Tabellen zu kopieren. Geben Sie hier die Bildbeschreibung einÖffnen Sie Python, führen Sie eine Zeichenfolgenverarbeitung durch (ersetzen Sie '' durch '' und dann '\ n' durch ','), und Sie erhalten eine durch Kommas getrennte Liste aller Tabellen. Jetzt in psql Shell mache a drop table CTRL+SHIFT+Vund du bist fertig. Ich weiß, dass es zu spezifisch ist, dass ich es nur teilen wollte. :) :)

Zinken
quelle
Dies funktioniert hervorragend und ermöglicht es Ihnen, ganz einfach zu sagen, was Sie tun möchten.
Brad Koch
5
Was ich mache, ist ähnlich, ich schreibe: DROP TABLE whatever_und drücke dann die Tabulatortaste, kopiere alle Tabellen in die Zwischenablage, öffne sublime, suche / ersetze und ersetze sie mit regulären Ausdrücken \s+für ,und füge sie in das Terminal ein.
Alfonso Pérez
yup das ist es für 5 bis viele Tabellen. Führen Sie für eine lange Liste eine Abfrage nach Tabellennamen aus, starten Sie von psql mit Ihrem Editor \e, kopieren Sie sie in Ihre Liste und setzen Sie Kommas.
Merlin
Wenn Sie in pgadmin3 den Schemanamen auswählen und dann zur Registerkarte 'Abhängige' gehen, können Sie alle Tabellen auswählen (mit der Umschalttaste) und sie dann alle mit STRG + C kopieren. Verwenden Sie dann einen Texteditor, um eine DROP-TABELLE zu erstellen [ Name, ..] Abfrage.
Mate Šimović
18

Ich habe das benutzt.

echo "select 'drop table '||tablename||';' from pg_tables where tablename like 'name%'" | \
    psql -U postgres -d dbname -t | \
    psql -U postgres -d dbname

Ersetzen Sie in die entsprechenden Werte dbnameund name%.

isaaclw
quelle
13

Ich habe mich immer viel wohler gefühlt, wenn ich ein SQL-Skript erstellt habe, das ich überprüfen und testen kann, bevor ich es ausführe, als mich darauf zu verlassen, dass plpgsql genau richtig ist, damit meine Datenbank nicht zerstört wird. Etwas Einfaches in Bash, das die Tabellennamen aus dem Katalog auswählt und dann die Drop-Anweisungen für mich erstellt. Für 8.4.x erhalten Sie also diese grundlegende Abfrage:

SELECT 'drop table '||n.nspname ||'.'|| c.relname||';' as "Name" 
FROM pg_catalog.pg_class c
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('r','v','S','')
     AND n.nspname <> 'pg_catalog'
     AND n.nspname <> 'information_schema'
     AND n.nspname !~ '^pg_toast'
AND pg_catalog.pg_table_is_visible(c.oid);

Dem können Sie eine where-Klausel hinzufügen. ( where c.relname ilike 'bubba%')

Die Ausgabe sieht folgendermaßen aus:

         Name          
-----------------------
 drop table public.a1;
 drop table public.a2;

Speichern Sie das also in einer .sql-Datei und führen Sie es mit psql -f filename.sql aus

Scott Marlowe
quelle
Wenn Sie im Folgenden alle Tabellen, die gelöscht werden müssen, in dasselbe Schema einfügen, können Sie es mit der Kaskade löschen: drop schema abc cascade;
Scott Marlowe
Beachten Sie, dass diese Abfrage auch einen drop tableBefehl für alle gefundenen Sequenzen erzeugt ( relkind = 'S'). drop tableauf einer Sequenz wird fehlschlagen. Entfernen Sie stattdessen 'S'aus der relkind INKlausel. Wenn Sie Sequenzen select 'drop sequence'c.relkind = 'S'
löschen müssen, erstellen Sie
9

Offenlegung: Diese Antwort ist für Linux-Benutzer gedacht.

Ich würde dem, was @prongs sagte, einige spezifischere Anweisungen hinzufügen:

  • \dtkann Platzhalter unterstützen: So können Sie \dt myPrefix*beispielsweise ausführen , um nur die Tabellen auszuwählen, die Sie löschen möchten.
  • danach CTRL-SHIFT-DRAGauswählen, CTRL-SHIFT-Cum den Text zu kopieren;
  • in vim, gehe zu INSERT MODEund füge die Tabellen mit ein CTRL-SHIFT-V;
  • Drücken Sie ESCund führen Sie dann aus :%s/[ ]*\n/, /g, um es in eine durch Kommas getrennte Liste zu übersetzen. Anschließend können Sie es (ohne das letzte Komma) einfügen DROP TABLE % CASCADE.
Campa
quelle
3

Mit Linux-Befehlszeilentools können Sie dies folgendermaßen tun:

psql -d mydb -P tuples_only=1 -c '\dt' | cut -d '|' -f 2 | paste -sd "," | sed 's/ //g' | xargs -I{} echo psql -d mydb -c "drop table {};"

HINWEIS: Das letzte Echo ist vorhanden, da ich keine Möglichkeit gefunden habe, Anführungszeichen um den Befehl drop zu setzen. Sie müssen daher die Ausgabe kopieren und einfügen und die Anführungszeichen selbst hinzufügen.

Wenn jemand dieses kleine Problem beheben kann, wäre das eine großartige Sauce.

Jon
quelle
1

Also habe ich mich heute diesem Problem gestellt. Ich habe meine Server-Datenbank über pgadmin3 geladen und es so gemacht. Die Tabellen sind alphabetisch sortiert, sodass das Verschieben und Klicken gefolgt vom Löschen gut funktioniert.

Ben
quelle
Sie können dies tun, aber Sie müssen das Fenster 'Eigenschaften' verwenden
Matt