PostgreSQL은 지원하지 않습니다 IF NOT EXISTS
에 대한 CREATE DATABASE
문. .NET에서만 지원됩니다 CREATE SCHEMA
. 또한 CREATE DATABASE
거래에서 발행 할 수 없으므로DO
예외 포착 블록에 .
언제 CREATE SCHEMA IF NOT EXISTS
발행 및 스키마가 이미 중복 객체 정보를 다음 예고 (안 오류)가 존재한다 발생합니다.
이러한 문제를 해결하려면 dblink
데이터베이스 서버에 대한 새 연결을 열고 트랜잭션에 들어 가지 않고 쿼리를 실행하는 확장 을 사용해야 합니다. 빈 문자열을 제공하여 연결 매개 변수를 재사용 할 수 있습니다.
다음은에서 와 같은 동작으로 PL/pgSQL
완전히 시뮬레이션하는 코드 CREATE DATABASE IF NOT EXISTS
입니다 CREATE SCHEMA IF NOT EXISTS
. , catch 예외 (데이터베이스가 이미 존재하는 경우 발행 됨) CREATE DATABASE
를 통해 호출 하고 전파하는 알림으로 변환합니다 . 문자열 메시지는 같은 방식으로 추가 되었습니다 .dblink
duplicate_database
errcode
, skipping
CREATE SCHEMA IF NOT EXISTS
CREATE EXTENSION IF NOT EXISTS dblink;
DO $$
BEGIN
PERFORM dblink_exec('', 'CREATE DATABASE testdb');
EXCEPTION WHEN duplicate_database THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;
END
$$;
이 솔루션은 데이터베이스가 존재하는지 확인하고 자체 생성 사이에 외부 프로세스 (또는 동일한 스크립트의 다른 인스턴스)에 의해 데이터베이스를 생성 할 수있는 다른 답변과 같이 경쟁 조건이 없습니다.
또한 CREATE DATABASE
데이터베이스 이외의 다른 오류로 인해 실패하면이 오류가 오류로 전파되고 자동으로 삭제되지 않습니다. duplicate_database
오류 만 포착 할 수 있습니다. 그래서 그것은 정말로 IF NOT EXISTS
해야하는 대로 작동 합니다.
이 코드를 자체 함수에 넣거나 직접 호출하거나 트랜잭션에서 호출 할 수 있습니다. 롤백 (삭제 된 데이터베이스 복원)은 작동하지 않습니다.
출력 테스트 (DO를 통해 두 번 호출 한 다음 직접 호출) :
$ sudo -u postgres psql
psql (9.6.12)
Type "help" for help.
postgres=# \set ON_ERROR_STOP on
postgres=# \set VERBOSITY verbose
postgres=#
postgres=# CREATE EXTENSION IF NOT EXISTS dblink;
CREATE EXTENSION
postgres=# DO $$
postgres$# BEGIN
postgres$# PERFORM dblink_exec('', 'CREATE DATABASE testdb');
postgres$# EXCEPTION WHEN duplicate_database THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;
postgres$# END
postgres$# $$;
DO
postgres=#
postgres=# CREATE EXTENSION IF NOT EXISTS dblink;
NOTICE: 42710: extension "dblink" already exists, skipping
LOCATION: CreateExtension, extension.c:1539
CREATE EXTENSION
postgres=# DO $$
postgres$# BEGIN
postgres$# PERFORM dblink_exec('', 'CREATE DATABASE testdb');
postgres$# EXCEPTION WHEN duplicate_database THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;
postgres$# END
postgres$# $$;
NOTICE: 42P04: database "testdb" already exists, skipping
LOCATION: exec_stmt_raise, pl_exec.c:3165
DO
postgres=#
postgres=# CREATE DATABASE testdb;
ERROR: 42P04: database "testdb" already exists
LOCATION: createdb, dbcommands.c:467
dblink_connect
.