2013-08-22 9 views
50

Ich möchte eine Datenbank erstellen, die nicht über JDBC existiert. Im Gegensatz zu MySQL unterstützt PostgreSQL keine create if not exists Syntax. Was ist der beste Weg, dies zu erreichen?Simulieren CREATE DATABASE, wenn nicht für PostgreSQL EXISTS?

Die Anwendung weiß nicht, ob die Datenbank existiert oder nicht. Es sollte überprüft werden und ob die Datenbank existiert sollte es verwendet werden. Daher ist es sinnvoll, sich mit der gewünschten Datenbank zu verbinden. Wenn die Verbindung aufgrund einer fehlenden Datenbank fehlschlägt, sollte eine neue Datenbank erstellt werden (durch Verbinden mit der Standarddatenbank postgres). Ich habe den von Postgres zurückgegebenen Fehlercode überprüft, aber ich konnte keinen relevanten Code finden, der dieselbe Spezies hat.

Eine andere Methode, um dies zu erreichen, wäre, eine Verbindung zur postgres Datenbank herzustellen und zu prüfen, ob die gewünschte Datenbank existiert und entsprechende Maßnahmen zu ergreifen. Der zweite ist ein bisschen mühsam zu trainieren.

Gibt es eine Möglichkeit, diese Funktionalität in Postgres zu erreichen?

Antwort

43

Sie können den Systemkatalog fragen. Der heikle Teil ist (wie kommentiert wurde), dass CREATE DATABASE nur als eine einzige Anweisung ausgeführt werden kann. Per documentation:

CREATE DATABASE cannot be executed inside a transaction block.

So kann es nicht in einer Funktion oder DO Anweisung ausgeführt werden, wo sie implizit in einem Transaktionsblock wären. Dies kann jedoch umgangen werden, indem eine dblink Verbindung zurück zur aktuellen Datenbank verwendet wird, die außerhalb des Transaktionsblocks ausgeführt wird. Effekte können daher auch nicht zurückgesetzt werden.

Sie müssen das Zusatzmodul dblink (einmal pro db) installieren:

Dann:

DO 
$do$ 
BEGIN 
    IF EXISTS (SELECT 1 FROM pg_database WHERE datname = 'mydb') THEN 
     RAISE NOTICE 'Database already exists'; 
    ELSE 
     PERFORM dblink_exec('dbname=' || current_database() -- current db 
         , 'CREATE DATABASE mydb'); 
    END IF; 
END 
$do$; 

Eine detaillierte Erklärung, wie es funktioniert:

Getestet mit Postgres 9.3. Sie könnten dies zu einer Funktion für die wiederholte Verwendung machen.

+0

Wie können wir dies mit 'jdbc' schreiben oder dies in Java-Code einbetten? –

+1

@AmanDeepGautam: Es ist eine einfache SQL-Anweisung.Sie sollten es wie jedes andere mit 'stmt.executeQuery (query)' ausführen können. –

+1

Leider 9.3 (mindestens) nicht wie folgt: "FEHLER: CREATE DATABASE kann nicht von einer Funktion oder Multi-Befehl-Zeichenfolge ausgeführt werden" –

5

Ich hatte eine etwas erweiterte Version @Erwin Brandstetter verwendet verwenden:

DO 
$do$ 
DECLARE 
    _db TEXT := 'some_db'; 
    _user TEXT := 'posrgres'; 
    _password TEXT := 'posrgres'; 
BEGIN 
    CREATE EXTENSION IF NOT EXISTS dblink; -- enable extension 
    IF EXISTS (SELECT 1 FROM pg_database WHERE datname = _db) THEN 
    RAISE NOTICE 'Database already exists'; 
    ELSE 
    PERFORM dblink_connect('host=localhost user=' || _user || ' password=' || _password || ' dbname=' || current_database()); 
    PERFORM dblink_exec('CREATE DATABASE ' || _db); 
    END IF; 
END 
$do$ 

ich die dblink Erweiterung zu ermöglichen, hatte, und ich hatte die Anmeldeinformationen für dblink bereitzustellen. Arbeitet mit Postgres 9.4.

64

eine weitere Alternative, nur für den Fall, dass Sie ein Shell-Skript haben, die die Datenbank erstellt, wenn es nicht und auch sonst hält existiert nur, wie es ist:

psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'my_db'" | grep -q 1 || psql -U postgres -c "CREATE DATABASE my_db" 

ich dies in DevOps hilfreich erwiesen Provisioning-Skripte, die Sie möglicherweise mehrmals für dieselbe Instanz ausführen möchten.

+0

Es funktioniert nicht für mich. 'c: \ Programme \ PostgreSQL \ 9.6 \ bin $ psql.exe -U Admin -tc" SELECT 1 aus pg_database WHERE datname = 'my_db' "| grep -q 1 || psql -U admin -c "CREATE DATABASE my_db" 'grep' wird nicht als interner oder externer Befehl erkannt, ausführbare Programm- oder Batch-Datei.Was habe ich falsch gemacht? –

+0

Sie haben nicht 'grep' in Ihrem Pfad. Unter Windows ist 'grep' nicht standardmäßig installiert. Sie können nach 'gnu grep windows' suchen, um eine Version zu finden, die unter Windows funktioniert. – Rod

+0

Thx @Rod. Nachdem ich Grep installiert hatte, funktionierte dieses Skript für mich. –

Verwandte Themen