使用存储的函数创建数据库

时间:2010-12-08 09:51:53

标签: database postgresql transactions stored-functions

我是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语句?

4 个答案:

答案 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

检查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上 - 你没有指定你的版本)