我有一个看起来像这样的函数:
BEGIN
DROP DATABASE IF EXISTS db_1;
END;
我收到以下错误:
错误:无法从函数或多命令字符串执行DROP DATABASE。
是否无法从PostgreSQL中的存储过程中删除数据库?我正在使用plpgsql。
答案 0 :(得分:3)
此错误信息只有the manual:
DROP DATABASE
无法在事务块中执行。
plgpsql函数自动被事务块包围。它的长短:你不能直接做到这一点。有没有特别的原因你不能只调用DDL命令?
DROP database $mydb;
您可以通过建议的dblink附加模块@Igor来规避这些限制。您需要为每个数据库安装一次 - 您调用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
连接字符串甚至可以指向会话运行的同一个db。该命令在事务块之外运行,这有两个结果:
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');
使用默认维护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$;
答案 1 :(得分:1)