PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Löschen oder erstellen Sie eine Datenbank aus einer gespeicherten Prozedur in PostgreSQL

Die Fehlermeldung ist genauso eindeutig wie das Handbuch dazu:

Eine plgpsql-Funktion wird automatisch von einem Transaktionsblock umgeben. Kurz und knapp:Das geht nicht – direkt. Gibt es einen bestimmten Grund, warum Sie den DDL-Befehl nicht einfach aufrufen können?

DROP database $mydb;

Sie können umgehen Sie diese Einschränkungen mit dem Zusatzmodul dblink als @Igor empfohlen. Sie müssen es einmal pro Datenbank installieren - diejenige, in der Sie dblink-Funktionen aufrufen, nicht die (andere), in der Sie Befehle ausführen.
Erlaubt Ihnen, eine Funktion mit dblink_exec() so:

CREATE OR REPLACE FUNCTION f_drop_db(text)
  RETURNS text LANGUAGE sql AS
$func$
SELECT dblink_exec('port=5432 dbname=postgres'
                  ,'DROP DATABASE ' || quote_ident($1))
$func$;

quote_ident() verhindert mögliche SQL-Injection.

Aufruf:

SELECT f_drop_db('mydb');

Bei Erfolg sehen Sie:

Die Verbindungszeichenfolge könnte sogar auf dieselbe Datenbank verweisen, in der Ihre Sitzung ausgeführt wird. Der Befehl wird außerhalb eines Transaktionsblocks ausgeführt, was zwei Konsequenzen hat:

  • Es kann nicht zurückgesetzt werden.
  • Es erlaubt Ihnen, DROP DATABASE aufzurufen "über einen Proxy" innerhalb einer Funktion.

Sie könnten einen FOREIGN DATA WRAPPER erstellen und ein FOREIGN SERVER um eine Verbindung zu speichern und den Anruf zu vereinfachen:

CREATE FOREIGN DATA WRAPPER postgresql VALIDATOR postgresql_fdw_validator;

CREATE SERVER your_fdw_name_here FOREIGN DATA WRAPPER postgresql
OPTIONS (hostaddr '12.34.56.78', port '5432', dbname 'postgres');

Verwenden der standardmäßigen Wartungsdatenbank postgres , was eine naheliegende Wahl wäre. Aber jede db ist möglich.

Vereinfachte Funktion, die davon Gebrauch macht:

CREATE OR REPLACE FUNCTION f_drop_db(text)
  RETURNS text LANGUAGE sql AS
$func$
SELECT dblink_exec('your_fdw_name_here', 'DROP DATABASE ' || quote_ident($1))
$func$;