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 № 1To 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)