[解決済み] PostgreSQLのCREATE DATABASE IF NOT EXISTSをシミュレートしてみませんか?
質問
JDBCで存在しないデータベースを作りたいのですが、どうすればいいですか?PostgreSQLは、MySQLと異なり、JDBCをサポートしていません。
create if not exists
構文があります。これを達成するための最良の方法は何ですか?
アプリケーションは、データベースが存在するかどうかを知りません。データベースが存在するかどうかを確認し、存在する場合はそれを使用する必要があります。したがって、目的のデータベースに接続し、データベースが存在しないために接続に失敗した場合は、新しいデータベースを作成するのが理にかなっています(デフォルトの
postgres
データベース)。Postgresが返すエラーコードを確認しましたが、同じ種族の関連するコードは見つかりませんでした。
これを実現する別の方法として、接続先が
postgres
データベースが存在するかどうかを確認し、それに応じてアクションを起こします。2つ目は、ちょっと面倒な作業ですね。
この機能をPostgresで実現する方法はないのでしょうか?
どのように解決するのですか?
制限事項
システムカタログに問い合わせることができます
pg_database
- 同じデータベースクラスタ内のどのデータベースからでもアクセスできます。厄介なのは
CREATE DATABASE
は1つの文としてしか実行できない。
マニュアルです。
CREATE DATABASE
はトランザクションブロックの中では実行できません。
そのため、関数の内部で直接実行することはできませんし
DO
ステートメントで、暗黙のうちにトランザクションブロックの中に入ることになります。SQLプロシージャはPostgres 11で導入されました。
にも対応できません。
.
psql内部からの回避策
DDL 文を条件付きで実行することにより、psql 内から回避することができます。
SELECT 'CREATE DATABASE mydb'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'mydb')\gexec
\gexec
現在のクエリバッファをサーバに送信し、クエリの出力の各行の各列(もしあれば)を、実行すべきSQL文として扱います。
シェルからの回避策
と
\gexec
を呼び出すだけです。
一度だけ
:
echo "SELECT 'CREATE DATABASE mydb' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'mydb')\gexec" | psql
接続には、ロール、ポート、パスワードなど、より多くのpsqlオプションが必要な場合があります。参照してください。
で呼び出すことはできません。
psql -c "SELECT ...\gexec"
というのは
\gexec
は psql のメタコマンドであり
-c
オプションは、1つの
コマンド
に対して
とマニュアルに記載されています。
command
は、サーバーが完全に解析可能なコマンド文字列 (つまり、psql 固有の機能を含まない) か、シングルバックスラッシュコマンドのいずれかでなければなりません。したがって、SQL と psql のメタコマンドを-c
オプションで指定します。
Postgresのトランザクション内からの回避策
を使用することができます。
dblink
これはトランザクションブロックの外側で実行されます。そのため、エフェクトをロールバックすることはできません。
このために追加モジュールdblinkをインストールします(データベースごとに1回)。
では
DO
$do$
BEGIN
IF EXISTS (SELECT FROM pg_database WHERE datname = 'mydb') THEN
RAISE NOTICE 'Database already exists'; -- optional
ELSE
PERFORM dblink_exec('dbname=' || current_database() -- current db
, 'CREATE DATABASE mydb');
END IF;
END
$do$;
繰り返しになりますが、接続にはさらに多くの psql オプションが必要な場合があります。Ortwinの追加回答を参照してください。
dblinkの詳細説明です。
これを関数にして繰り返し使うことができます。
関連
-
[解決済み] psql: FATAL: データベース "<user>" が存在しない
-
[解決済み] SQL ServerでSELECTからUPDATEする方法とは?
-
[解決済み] PostgreSQLでデータベースのコピーを作成する
-
[解決済み] PostgreSQLデータベースへのSQLダンプのインポート
-
[解決済み] PostgreSQLデータベースの別サーバーへのコピー
-
[解決済み] 項目xにアクセスできるように文字列を分割するにはどうすればよいですか?
-
[解決済み】PostgreSQL。PostgreSQLデータベースでユーザーにすべての権限を与える
-
[解決済み】postgresqlの初回設定方法は?
-
[解決済み】ドッカー化したPostgreSQLデータベースのバックアップ/リストア
-
[解決済み】pgadminでherokuのデータベースに接続する。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] PostgreSQLのROLE(ユーザー)が存在しない場合、それを作成する
-
[解決済み] Oracleで上位100行を選択する方法は?
-
[解決済み] SQLのカラム名があいまいな場合のクエリエラー
-
[解決済み] 1つのPostgreSQLクエリで複数のWITHステートメントを使用するには?
-
[解決済み] SQL Server : 列を行に変換する
-
[解決済み] INNER JOINよりもCROSS APPLYを使用すべきなのはどのような場合ですか?
-
[解決済み] SQL Serverで、指定したテーブルを参照しているすべての外部キーを一覧表示するにはどうすればよいですか?
-
[解決済み] 各グループの上位1行を取得
-
[解決済み] SQL Server の VARCHAR/NVARCHAR 文字列に改行を挿入する方法
-
[解決済み] フラットテーブルをツリーにパースする最も効率的/エレガントな方法は何ですか?