Chybová zpráva je jasná jako příručka na tomto:
Funkce plgpsql je automaticky obklopena blokem transakce. Dlouhé a krátké:nemůžete to udělat - přímo. Existuje nějaký konkrétní důvod, proč nemůžete jednoduše zavolat příkaz DDL?
DROP database $mydb;
můžete obejít tato omezení pomocí dodatečného modulu dblink
jako @Igor navrhl. Musíte ji nainstalovat jednou pro každou databázi – tu, kde voláte funkce dblink, ne tu (jinou), ve které spouštíte příkazy.
Umožňuje vám napsat funkci pomocí dblink_exec()
takhle:
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()
zabrání možnému vložení SQL.
Volejte:
SELECT f_drop_db('mydb');
Na úspěchu vidíte:
Připojovací řetězec může dokonce ukazovat na stejnou databázi, ve které běží vaše relace. Příkaz běží mimo transakční blok, což má dva důsledky:
- Nelze jej vrátit zpět.
- Umožňuje vám volat
DROP DATABASE
„prostřednictvím proxy“ z funkce.
Můžete vytvořit FOREIGN DATA WRAPPER
a FOREIGN SERVER
pro uložení spojení a zjednodušení hovoru:
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');
Použití výchozí údržby db postgres
, což by byla jasná volba. Ale jakákoli db je možná.
Zjednodušená funkce využívající toho:
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$;