我有一个看起来像这样的函数:
BEGIN
DROP DATABASE IF EXISTS db_1;
END;
我收到以下错误:
错误:不能从函数或多命令字符串执行 DROP DATABASE。
不能从 PostgreSQL 的存储过程中删除数据库吗?我正在使用 plpgsql。
我有一个看起来像这样的函数:
BEGIN
DROP DATABASE IF EXISTS db_1;
END;
我收到以下错误:
错误:不能从函数或多命令字符串执行 DROP DATABASE。
不能从 PostgreSQL 的存储过程中删除数据库吗?我正在使用 plpgsql。
错误消息与手册一样清楚:
DROP DATABASE
不能在事务块内执行。
plgpsql 函数自动被事务块包围。长与短:你不能直接这样做。有什么特殊原因不能只调用 DDL 命令吗?
DROP database $mydb;
您可以使用@Igor建议的附加模块dblink来规避这些限制。您需要为每个数据库安装一次 - 您调用 dblink 函数的数据库,而不是您执行命令的(其他)数据库。
允许您使用如下方式编写函数: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
从函数中“通过代理”调用。您可以创建 aFOREIGN DATA WRAPPER
和 aFOREIGN 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');
使用默认维护 db 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$;