2010-12-08 4 views
4

Я новичок в 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

Почему вы хотите это сделать? – eevar 2012-09-04 17:43:25

ответ

1

Вы не можете создать базу данных внутри функции, потому что невозможно создать базу данных inside a transaction.

Но, скорее всего, вы не собираетесь создавать базы данных, а schemas, которые более близки к базам данных MySQL.

+0

Я не хочу создавать схемы. Я хочу создать базу данных только. Да, вы правы в MyQL. Я реализовал его, как в MySQL, нет разницы между Schema и Database. – 2010-12-08 10:08:58

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 - вы не указали свою версию)

+0

Есть ли способ, который я могу реализовать? – 2010-12-08 10:17:33

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'); 

В моем случае с использованием различных видов шаблона.

Привет

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-инъекцию.

Смежные вопросы