我是PostgreSQL的新手,想要使用存储的函数创建数据库 例如:
CREATE OR REPLACE FUNCTION mt_test(dbname character varying)
RETURNS integer AS
$BODY$
Create Database $1;
Select 1;
$BODY$
LANGUAGE sql;
当我尝试执行此功能时,我收到语法错误。
Postgres是否支持存储函数中的CREATE DATABASE
语句?
答案 0 :(得分:8)
这个问题很老,但为了完整起见......
正如其他答案所指出的那样,这不仅仅是因为(per documentation):
CREATE DATABASE
无法在事务块中执行。
据报道,dblink
可以绕过限制
How to use (install) dblink in PostgreSQL?
到目前为止缺少的是实际执行的正确功能:
CREATE OR REPLACE FUNCTION f_create_db(dbname text)
RETURNS integer AS
$func$
BEGIN
IF EXISTS (SELECT 1 FROM pg_database WHERE datname = dbname) THEN
RAISE NOTICE 'Database already exists';
ELSE
PERFORM dblink_exec('dbname=' || current_database() -- current db
, 'CREATE DATABASE ' || quote_ident(dbname));
END IF;
END
$func$ LANGUAGE plpgsql;
检查本地群集中是否已存在数据库。如果没有,继续创建它 - 使用已清理的标识符。我们不想邀请SQL注入。
答案 1 :(得分:2)
我找到了解决这个问题的棘手办法,但可能。几乎在所有地方看完和阅读之后,我尝试了一些东西并且有效。
如果错误是“无法从函数或多命令字符串执行CREATE DATABASE”,我们可以使用dblink强制执行单个命令字符串。并使它连接到自己。
检查dblink安装说明PERFORM replication.dblink_connect('myconn','host=127.0.0.1 port=5432 dbname=mydb user=username password=secret');
PERFORM replication.dblink_exec('myconn', 'CREATE DATABASE "DBFROMUSER'||id||'" TEMPLATE "TEMPL'||type||'";',false);
PERFORM replication.dblink_disconnect('myconn');
在我的情况下使用不同种类的模板。
问候
答案 2 :(得分:1)
您无法在函数内创建数据库,因为无法创建数据库inside a transaction。
但很可能你不是要创建数据库,而是schemas,它更像MySQL的数据库。
答案 3 :(得分:1)
postgres=> create or replace function mt_test(dbname text)
returns void language plpgsql as $$
postgres$> begin
postgres$> execute 'create database '||$1;
postgres$> end;$$;
CREATE FUNCTION
postgres=> select work.mt_test('dummy_db');
ERROR: CREATE DATABASE cannot be executed from a function or multi-command string
CONTEXT: SQL statement "create database dummy_db"
PL/pgSQL function "mt_test" line 2 at EXECUTE statement
postgres=>
请注意错误消息:CREATE DATABASE cannot be executed from a function or multi-command string
所以问题的答案是:
postgresql是否支持在存储函数中创建语句
是“否”(至少在8.4上 - 你没有指定你的版本)