模拟CREATE DATABASE如果不存在PostgreSQL?
我想创build一个不存在的数据库通过JDBC。 不像MySQL,PostgreSQL不支持create if not exists
语法。 什么是完成这个最好的方法?
应用程序不知道数据库是否存在。 它应该检查,如果数据库存在,应该使用它。 所以连接到所需的数据库是有道理的,如果由于数据库不存在而导致连接失败,它应该创build新的数据库(通过连接到默认的postgres
数据库)。 我检查了Postgres返回的错误代码,但是我找不到任何相同的代码。
另一种方法是连接到postgres
数据库,并检查是否存在所需的数据库并采取相应的措施。 第二个是有点繁琐的工作。
有什么办法可以在Postgres中实现这个function吗?
你可以问系统目录。 棘手的部分是(正如已经评论的), CREATE DATABASE
只能作为单个语句执行。 每个文档:
CREATE DATABASE
不能在事务块内部执行。
所以它不能在一个函数或者DO
语句中运行,它将隐含在一个事务块中。 这可以通过使用dblink
连接回到当前数据库(在事务块之外运行)来绕过。 因此效果也不能回滚。
您需要安装附加模块dblink(每db一次):
- 如何在PostgreSQL中使用(安装)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$;
关于它是如何工作的详细解释:
- 我如何在PostgreSQL中进行大量的无阻塞更新?
testingPostgres 9.3。 你可以使这个function重复使用。
另一种select,以防万一你想有一个shell脚本创build数据库,如果它不存在,否则保持原样:
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供应脚本中很有用,您可能希望在同一个实例上运行多次。
我不得不使用一个稍微扩展的版本@Erwin Brandstetter使用:
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
扩展,另外我必须提供dblink的凭据。 适用于Postgres 9.4。