패턴 사용에 대한 몇 가지 답변 : 역할이 존재하지 않는지 확인하고 그렇지 않으면 CREATE ROLE
명령 을 발행하십시오 . 여기에는 경쟁 조건이라는 한 가지 단점이 있습니다. 다른 사람이 확인과 CREATE ROLE
명령 실행 사이에 새로운 역할을 생성 CREATE ROLE
하면 치명적인 오류로 인해 실패합니다.
위의 문제를 해결하기 위해 더 많은 다른 답변은 이미 사용에 대해 언급 PL/pgSQL
하고 CREATE ROLE
무조건 실행 한 다음 해당 호출에서 예외를 포착합니다. 이러한 솔루션에는 한 가지 문제가 있습니다. 역할이 이미 존재한다는 사실로 인해 생성되지 않은 오류를 포함하여 모든 오류를 자동으로 삭제합니다. CREATE ROLE
다른 오류도 발생할 수 있으며 시뮬레이션 IF NOT EXISTS
은 역할이 이미 존재하는 경우에만 오류를 침묵시켜야합니다.
CREATE ROLE
던져 duplicate_object
역할이 이미 존재하는 경우 오류가 발생했습니다. 그리고 예외 처리기는이 오류 하나만 잡아야합니다. 다른 답변에서 언급했듯이 치명적인 오류를 간단한 알림으로 변환하는 것이 좋습니다. 다른 PostgreSQL IF NOT EXISTS
명령 , skipping
은 메시지에 추가 되므로 일관성을 위해 여기에도 추가합니다.
다음은 CREATE ROLE IF NOT EXISTS
올바른 예외 및 sqlstate 전파 시뮬레이션을위한 전체 SQL 코드입니다 .
DO $$
BEGIN
CREATE ROLE test;
EXCEPTION WHEN duplicate_object THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;
END
$$;
테스트 출력 (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=# DO $$
postgres$# BEGIN
postgres$# CREATE ROLE test;
postgres$# EXCEPTION WHEN duplicate_object THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;
postgres$# END
postgres$# $$;
DO
postgres=#
postgres=# DO $$
postgres$# BEGIN
postgres$# CREATE ROLE test;
postgres$# EXCEPTION WHEN duplicate_object THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;
postgres$# END
postgres$# $$;
NOTICE: 42710: role "test" already exists, skipping
LOCATION: exec_stmt_raise, pl_exec.c:3165
DO
postgres=#
postgres=# CREATE ROLE test;
ERROR: 42710: role "test" already exists
LOCATION: CreateRole, user.c:337