我有一个函数看起来像这样:
BEGIN
DROP DATABASE IF EXISTS db_1;
END;
我遇到了以下错误:
ERROR: DROP DATABASE不能在函数或多命令字符串中执行。
在 PostgreSQL 中,无法从存储过程中删除数据库吗?我正在使用 plpgsql。
我有一个函数看起来像这样:
BEGIN
DROP DATABASE IF EXISTS db_1;
END;
plgpsql函数会自动被一个事务块包围。长话短说:你不能直接这样做。是否有什么特殊原因,使你不能调用DDL命令呢?
DROP DATABASE
不能在事务块内执行。
DROP database $mydb;
dblink_exec()
函数的代码,例如: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()
可以防止 SQL 注入攻击。
调用方式:
SELECT f_drop_db('mydb');
连接字符串甚至可以指向您的会话运行的同一数据库。该命令在事务块之外运行,这有两个后果:DROP DATABASE
DROP DATABASE
。FOREIGN DATA WRAPPER
和一个FOREIGN SERVER
来存储连接并简化调用: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');
使用默认维护数据库 postgres
,这是一个显而易见的选择。但可以使用任何数据库。
利用此功能的简化函数:
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$;
dblink
连接到此集群上的任何数据库(除了您想要删除的那个),并从dblink
执行DROP DATABASE IF EXISTS db_1;
。 - Ihor Romanchenko