2013-08-22 9 views
50

JDBC経由で存在しないデータベースを作成したい。 MySQLとは異なり、PostgreSQLはcreate if not exists構文をサポートしていません。これを達成する最良の方法は何ですか?PostgreSQL用に存在しない場合、CREATE DATABASEをシミュレートしますか?

アプリケーションはデータベースが存在するかどうかわかりません。チェックし、データベースが存在する場合はそれを使用する必要があります。したがって、目的のデータベースに接続することは理にかなっており、データベースが存在しないために接続が失敗した場合は、新しいデータベースを作成する必要があります(デフォルトのpostgresデータベースに接続してください)。私はPostgresから返されたエラーコードをチェックしましたが、同じ種類の関連するコードは見つかりませんでした。

これを達成するもう1つの方法は、postgresデータベースに接続し、目的のデータベースが存在するかどうかを確認し、それに応じて対処することです。もう1つはちょっと面倒です。

この機能をPostgresで実現する方法はありますか?

答えて

43

システムカタログを尋ねることができます。面倒な部分は、CREATE DATABASEは1つのステートメントとしてしか実行できないとコメントされています。 Per documentation:

CREATE DATABASE cannot be executed inside a transaction block.

だから、それは暗黙的にトランザクションブロック内になる機能やDO文内で実行することはできません。トランザクションブロックの外側で実行される現在のデータベースに接続してdblink接続を使用することで回避できます。したがって、エフェクトをロールバックすることもできません。その後

あなたは(一度デシベルあたり)の追加モジュールのdblinkをインストールする必要が

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$; 

それがどのように動作するかについての詳細な説明:

Postgres 9.3でテスト済みです。これを繰り返し使用するための機能にすることができます。私は少し拡張したバージョン@Erwin Brandstetterを使用する必要がありました

+0

これを 'jdbc'を使って書くか、これをjavaコードに埋め込むにはどうすればいいですか? –

+1

@AmanDeepGautam:これは単純なSQL文です。'stmt.executeQuery(query)'を使って他のものと同じように実行できるはずです。 –

+1

残念ながら、9.3(少なくとも)はこれを好まない:「エラー:関数またはマルチコマンド文字列からのCREATE DATABASEを実行できない」 –

5

を使用:

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$ 

を私はdblink拡張を有効にする必要がありました、プラス私は、データベース・リンクのための資格情報を提供する必要がありました。 Postgres 9.4で動作します。

64

別の代替は、ちょうどあなたがそれが存在しない場合には、データベースを作成し、それがあるとしてそれ以外の場合はちょうどそれを保持するシェルスクリプトを持つようにしたい場合には:

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

私は、これはDevOpsチームに有用であることが判明プロビジョニングスクリプトは、同じインスタンス上で複数回実行したい場合があります。

+0

それは私のためには機能しません。 'c:¥Program Files¥PostgreSQL¥9.6¥bin $ psql.exe -U admin -tc" SELECT 1 FROM pg_database WHERE datname = 'my_db' "" grep -q 1 || psql -U admin -c "CREATE DATABASE my_db" 'grep'が内部または外部コマンド、 実行可能なプログラムまたはバッチファイルとして認識されません。 –

+0

パスに 'grep'がありません。 Windowsでは、 'grep'はデフォルトではインストールされません。 'gnu grep windows 'を検索すると、Windows上で動作するバージョンを見つけることができます。 – Rod

+0

Thx @Rod。私はgrepをインストールした後、このスクリプトは私のために働いた。 –

関連する問題