/ / Utwórz bazę danych za pomocą zapisanej funkcji - bazy danych, postgresql, transakcji, przechowywanych funkcji

Utwórz bazę danych za pomocą funkcji zapisanej - bazy danych, postgresql, transakcji, funkcji przechowywanych

Jestem nowy w PostgreSQL i chcę utworzyć bazę danych przy użyciu funkcji zapisanej.
Na przykład:

CREATE OR REPLACE FUNCTION mt_test(dbname character varying)
RETURNS integer AS
$BODY$

Create Database $1;

Select 1;

$BODY$
LANGUAGE sql;

Kiedy próbuję wykonać tę funkcję, otrzymuję błąd składni.

Czy Postgres obsługuje CREATE DATABASE instrukcja w przechowywanych funkcjach?

Odpowiedzi:

8 dla odpowiedzi № 1

To pytanie jest stare, ale ze względu na kompletność ...

Jak wskazano w innych odpowiedziach, nie jest to po prostu możliwe, ponieważ (według dokumentacji):

CREATE DATABASE nie można wykonać w bloku transakcji.

Donoszono również, że ograniczenie można ominąć dblink.
Jak używać (instalować) dblink w PostgreSQL?

To, czego brakowało do tej pory, to właściwa funkcja, która faktycznie to robi:

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;

Sprawdza, czy db już istnieje w klastrze lokalnym. Jeśli nie, należy go utworzyć - za pomocą oczyszczonego identyfikatora. Nie chcielibyśmy zaprosić SQL injection.


2 dla odpowiedzi nr 2

Znalazłem podchwytliwe rozwiązanie tego problemu, ale możliwe. Po przejrzeniu i czytaniu niemal wszędzie spróbowałem czegoś i zadziałało.

jeśli błąd jest "CREATE DATABASE nie można wykonać z ciągu funkcji lub wielu poleceń" możemy wymusić jeden ciąg poleceń za pomocą dblink. I spraw, by łączył się ze sobą.

Sprawdź instrukcje instalacji dblink na 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");

W moim przypadku używam różnych rodzajów szablonów.

Pozdrowienia


1 dla odpowiedzi nr 3

Nie można utworzyć bazy danych wewnątrz funkcji, ponieważ nie można utworzyć bazy danych wewnątrz transakcji.

Ale najprawdopodobniej nie chodzi o tworzenie baz danych, ale schematy, które bardziej przypominają bazy danych MySQL.


1 dla odpowiedzi nr 4
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=>

zanotuj komunikat o błędzie: CREATE DATABASE cannot be executed from a function or multi-command string

więc odpowiedź na pytanie:

Czy postgresql obsługuje tworzenie instrukcji w przechowywanej funkcji

jest "nie" (przynajmniej 8,4 - nie określasz swojej wersji)