[SQL] PostgreSQL을 위해하지 않음있는 경우 DATABASE를 생성 시뮬레이션?
SQLPostgreSQL을 위해하지 않음있는 경우 DATABASE를 생성 시뮬레이션?
나는 JDBC를 통해 존재하지 않는 데이터베이스를 만들려고합니다. MySQL을 달리 PostgreSQL은하지 구문을 존재하는 경우 생성을 지원하지 않습니다. 이 작업을 수행하는 가장 좋은 방법은 무엇입니까?
데이터베이스가 존재하거나하지 않을 경우 응용 프로그램이 알 수 없습니다. 그것은 확인해야하고 데이터베이스가 존재하는 경우에 사용해야합니다. 이 원하는 데이터베이스와 경우에 연결하는 의미가 그래서 연결이 그것 때문에 (기본 포스트 그레스 데이터베이스에 연결하여) 새 데이터베이스를 작성해야합니다 데이터베이스의 비 존재에 실패합니다. 나는 포스트 그레스에 의해 반환 된 오류 코드를 확인하지만 난 어떤 관련 코드 종 같은 것을 찾을 수 없습니다.
이를 달성하기 위해 또 다른 방법은 포스트 그레스 데이터베이스에 연결하고 원하는 데이터베이스가 존재하는지 확인하고 그에 따라 조치를 취할 것입니다. 두 번째는 운동하는 비트 지루한입니다.
포스트 그레스에서이 기능을 달성 할 수있는 방법이 있습니까?
해결법
-
==============================
1.동일한 데이터베이스 클러스터의 모든 데이터베이스에서 액세스 할 수 - 당신은 시스템 카탈로그 pg_database을 요청할 수 있습니다. 까다로운 부분은 DATABASE는 하나의 문으로 실행할 수 있습니다 만드는 것이있다. 수동 :
동일한 데이터베이스 클러스터의 모든 데이터베이스에서 액세스 할 수 - 당신은 시스템 카탈로그 pg_database을 요청할 수 있습니다. 까다로운 부분은 DATABASE는 하나의 문으로 실행할 수 있습니다 만드는 것이있다. 수동 :
그래서는이 암시 적 트랜잭션 블록 내부 될 함수 또는 DO 문, 내부에서 직접 실행할 수 없습니다.
(포스트 그레스 (11)에 도입 된 SQL 절차, 하나이하지 도움이 될 수 있습니다.)
당신은 조건부로 DDL 문을 실행하여 psql 프로그램 내에서 해결할 수 있습니다 :
SELECT 'CREATE DATABASE mydb' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'mydb')\gexec
수동 :
당신은 단지 전화 psql의 필요 \ 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 옵션은 단일 명령 기대 때문에하는 수동 상태에 대한 :
당신은 외부 트랜잭션 블록의 실행은 현재 데이터베이스에 DBLINK 연결 등을 사용할 수 있습니다. 따라서도 영향을 롤백 할 수 없다.
이 (한 번 데이터베이스 당)에 대한 추가 모듈 DBLINK를 설치합니다 :
그때:
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에 대한 상세 설명 :
당신은 반복 사용하기 위해 이것을 기능을 할 수 있습니다.
-
==============================
2.또 다른 대안은, 단지 경우에 당신은 존재하고 그대로 그렇지 않으면 그냥 유지하지 않는 경우 데이터베이스를 생성 쉘 스크립트를 갖고 싶어 :
또 다른 대안은, 단지 경우에 당신은 존재하고 그대로 그렇지 않으면 그냥 유지하지 않는 경우 데이터베이스를 생성 쉘 스크립트를 갖고 싶어 :
psql -U postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'my_db'" | grep -q 1 || psql -U postgres -c "CREATE DATABASE my_db"
나는이 같은 인스턴스에 여러 번 실행할 수 있습니다 스크립트를 프로비저닝 개발 운영 팀에 도움이 될 것으로.
-
==============================
3.나는 @Erwin Brandstetter 사용 약간 확장 된 버전을 사용했다 :
나는 @Erwin Brandstetter 사용 약간 확장 된 버전을 사용했다 :
DO $do$ DECLARE _db TEXT := 'some_db'; _user TEXT := 'postgres_user'; _password TEXT := 'password'; 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에 대한 자격 증명을 제공했다. 포스트 그레스 9.4에서 작동합니다.
-
==============================
4.PostgreSQL는 IF NOT은 CREATE DATABASE 문을 위해 존재 지원하지 않습니다. 단지에서 스키마를 작성 지원됩니다. 또한 데이터베이스가 트랜잭션에 발행 할 수 없습니다 CREATE 따라서 예외 잡기와 DO 블록에있을 수 없습니다.
PostgreSQL는 IF NOT은 CREATE DATABASE 문을 위해 존재 지원하지 않습니다. 단지에서 스키마를 작성 지원됩니다. 또한 데이터베이스가 트랜잭션에 발행 할 수 없습니다 CREATE 따라서 예외 잡기와 DO 블록에있을 수 없습니다.
SCHEMA IF가 NOT 발행 존재하고 스키마가 벌써 중복 객체 정보 통지 (안 오류)가 발생합니다 존재 만들 때.
당신이 데이터베이스 서버에 대한 새 연결을 엽니 다 DBLINK 확장자를 사용하고 거래를 입력하지 않고 쿼리를 실행해야 이러한 문제를 해결합니다. 당신은 빈 문자열을 공급하여 연결 매개 변수를 다시 사용할 수 있습니다.
아래 NOT은 CREATE SCHEMA IF가 NOT EXISTS처럼 같은 동작으로 존재하는 경우 완벽하게 시뮬레이트 데이터베이스를 만들 PL / pgSQL의 코드입니다. 그것은 errcode를 전파로 통지로 (데이터베이스가 이미 존재하는 경우 발행) DBLINK를 통해 DATABASE, 예외 duplicate_database 캐치 및 변환을 CREATE 호출합니다. 문자열 메시지가 SCHEMA IF가 NOT EXISTS CREATE 않는 방법과 동일한 방법으로 건너 뜁니다 추가했다.
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 $$;
이 솔루션은 데이터베이스가 존재 해, 그 자신의 창조물 경우 확인과 데이터베이스가 외부 프로세스 (또는 동일한 스크립트의 다른 인스턴스)을 생성 할 수있는 다른 답변처럼 어떤 경쟁 조건없이.
또한 데이터베이스를 만들 때 데이터베이스가 이미이 오류가 오류로 전파되고 자동으로 삭제하지 존재 이외의 오류와 함께 실패합니다. duplicate_database 오류 만 캐치가있다. IF NOT 정상적으로 존재하는 그래서 정말 작동합니다.
직접 또는 거래에서 호출, 자신의 기능에이 코드를 넣을 수 있습니다. 그냥 롤백 (떨어 데이터베이스를 복원 할) 것없는 일.
(두 번 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
-
==============================
5.당신이 데이터에 대해 상관하지 않는 경우, 먼저 데이터베이스를 삭제 한 다음 다시 만들 수 있습니다 :
당신이 데이터에 대해 상관하지 않는 경우, 먼저 데이터베이스를 삭제 한 다음 다시 만들 수 있습니다 :
DROP DATABASE IF EXISTS dbname; CREATE DATABASE dbname;
-
==============================
6.그냥 CREATEDB CLI 도구를 사용하여 데이터베이스를 만들 :
그냥 CREATEDB CLI 도구를 사용하여 데이터베이스를 만들 :
PGHOST="my.database.domain.com" PGUSER="postgres" PGDB="mydb" createdb -h $PGHOST -p $PGPORT -U $PGUSER $PGDB
데이터베이스가 존재하는 경우는 오류를 반환합니다 :
createdb: database creation failed: ERROR: database "mydb" already exists
-
==============================
7.당신이 쉘을 사용할 수 있다면, 시도
당신이 쉘을 사용할 수 있다면, 시도
psql -U postgres -c 'select 1' -d $DB &>dev/null || psql -U postgres -tc 'create database $DB'
내 생각 psql의 -U 포스트 그레스 -c datname = 'my_db'과는 쉬 -c와 결합하기 쉽게 인용 한 유형을 필요로하는 곳에 -d $ DB가 pg_database에서 선택 1보다 쉽습니다 "1 선택".
내 ansible 작업에서 이것을 사용
- name: create service database shell: docker exec postgres sh -c '{ psql -U postgres -tc "SELECT 1" -d {{service_name}} &> /dev/null && echo -n 1; } || { psql -U postgres -c "CREATE DATABASE {{service_name}}"}' register: shell_result changed_when: "shell_result.stdout != '1'"
-
==============================
8.PostgreSQL을 9.5 이상으로 업그레이드합니다. 경우 (안) 버전 9.5에 도입 된 존재.
PostgreSQL을 9.5 이상으로 업그레이드합니다. 경우 (안) 버전 9.5에 도입 된 존재.
from https://stackoverflow.com/questions/18389124/simulate-create-database-if-not-exists-for-postgresql by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] PostgreSQL을 신속하게 비슷한 문자열 찾기 (0) | 2020.04.14 |
---|---|
[SQL] 15 분 간격으로 그룹 MySQL의 쿼리 (0) | 2020.04.13 |
[SQL] 목록에서 SqlBulkCopy의 <> (0) | 2020.04.13 |
[SQL] 안드로이드 여러 데이터베이스가 열립니다 (0) | 2020.04.13 |
[SQL] SQL 데이터베이스 테이블에서 다형성? (0) | 2020.04.13 |