Pesan kesalahan ini hanya sejelas manual tentang ini:
Fungsi plgpsql dikelilingi oleh blok transaksi secara otomatis. Panjang dan pendeknya:Anda tidak bisa melakukan itu - secara langsung. Apakah ada alasan tertentu Anda tidak bisa memanggil perintah DDL begitu saja?
DROP database $mydb;
Anda bisa menghindari pembatasan ini dengan modul tambahan dblink
sebagai @Igor disarankan. Anda perlu menginstalnya sekali per database - database tempat Anda memanggil fungsi dblink, bukan database (lainnya) tempat Anda menjalankan perintah.
Memungkinkan Anda menulis fungsi menggunakan dblink_exec()
seperti ini:
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()
mencegah kemungkinan injeksi SQL.
Telepon:
SELECT f_drop_db('mydb');
Saat sukses, Anda akan melihat:
String koneksi bahkan dapat menunjuk ke db yang sama dengan sesi Anda berjalan. Perintah berjalan di luar blok transaksi, yang memiliki dua konsekuensi:
- Tidak dapat dibatalkan.
- Ini memungkinkan Anda untuk memanggil
DROP DATABASE
"melalui proxy" dari dalam suatu fungsi.
Anda dapat membuat FOREIGN DATA WRAPPER
dan FOREIGN SERVER
untuk menyimpan koneksi dan menyederhanakan panggilan:
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');
Menggunakan pemeliharaan default db postgres
, yang akan menjadi pilihan yang jelas. Tetapi db apa pun dimungkinkan.
Fungsi yang disederhanakan memanfaatkan itu:
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$;