jdk - postgresql 42.1 3 jre7 jar
¿Simula CREATE DATABASE IF EXISTS para PostgreSQL? (3)
Puede consultar el catálogo del sistema. La parte difícil es (como se ha comentado) que CREATE DATABASE
solo se puede ejecutar como una declaración única. Por documentación:
CREATE DATABASE
no se puede ejecutar dentro de un bloque de transacción.
Por lo tanto, no se puede ejecutar dentro de una función o declaración DO
, donde estaría implícitamente dentro de un bloque de transacción. Sin embargo, eso se puede eludir mediante el uso de una conexión dblink
a la base de datos actual, que se ejecuta fuera del bloque de transacción. Por lo tanto, los efectos tampoco pueden revertirse.
Necesita instalar el módulo adicional dblink (una vez por db):
Entonces:
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$;
Una explicación detallada de cómo funciona:
Probado con Postgres 9.3. Puede hacer que esto sea una función para un uso repetido.
Quiero crear una base de datos que no exista a través de JDBC. A diferencia de MySQL, PostgreSQL no admite la sintaxis de create if not exists
. Cuál es la mejor manera de lograr esto?
La aplicación no sabe si la base de datos existe o no. Debe verificar y si la base de datos existe, se debe usar. Por lo tanto, tiene sentido conectarse a la base de datos deseada y si la conexión falla debido a la inexistencia de una base de datos, debe crear una nueva base de datos (conectándose a la postgres
datos predeterminada de postgres
). Comprobé el código de error devuelto por Postgres, pero no pude encontrar ningún código relevante que especifique lo mismo.
Otro método para lograr esto sería conectarse a la postgres
datos de postgres
y verificar si existe la base de datos deseada y actuar en consecuencia. El segundo es un poco tedioso para hacer ejercicio.
¿Hay alguna forma de lograr esta funcionalidad en Postgres?
Tuve que usar una versión ligeramente extendida @Erwin Brandstetter utilizada:
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$
Tuve que habilitar la extensión dblink
, además tuve que proporcionar las credenciales para dblink. Funciona con Postgres 9.4.
otra alternativa, en caso de que quiera tener un script de shell que crea la base de datos si no existe y de lo contrario solo lo mantiene como está:
psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname = ''my_db''" | grep -q 1 || psql -U postgres -c "CREATE DATABASE my_db"
Encontré que esto es útil en las secuencias de comandos de suministro de Devops, que es posible que desee ejecutar varias veces en la misma instancia.