정확히 테스트하려는 대상에 따라 다릅니다 .
정보 스키마?
"테이블이 존재하는지 여부"( 누가 묻든 관계없이) 를 찾으려면 정보 스키마 ( information_schema.tables
)를 쿼리하는 것은 정확하지 않습니다 . 문서 당 ) :
현재 사용자가 (소유자 또는 일부 권한을 가지고) 액세스 할 수있는 테이블 및 뷰만 표시됩니다.
@kong 이 제공 한 쿼리 는 다음을 반환 할 수 있습니다.FALSE
있지만 테이블은 여전히 존재할 수 있습니다. 그것은 질문에 대답합니다 :
테이블 (또는 뷰)이 있는지 확인하고 현재 사용자가 테이블에 액세스 할 수 있습니까?
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
);
정보 스키마는 주요 버전과 다른 RDBMS간에 이식성을 유지하는 데 주로 유용합니다. 그러나 Postgres는 표준을 준수하기 위해 정교한 뷰를 사용해야하기 때문에 구현 속도가 느립니다 information_schema.tables
. 그리고 OID와 같은 일부 정보는 시스템 카탈로그에서 번역시 손실됩니다. 실제로 모든 정보를 전달 .
시스템 카탈로그
당신의 질문은 :
테이블이 있는지 확인하는 방법?
SELECT EXISTS (
SELECT FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'schema_name'
AND c.relname = 'table_name'
AND c.relkind = 'r' -- only tables
);
시스템 카탈로그 pg_class
를 pg_namespace
직접 사용하면 훨씬 빠릅니다. 그러나 설명서에 따라pg_class
:
카탈로그 pg_class
카탈로그 테이블과 열을가하거나 테이블에 다른 유사하다 다른 대부분의 모든 것을. 여기에는 인덱스 (또는 참조 pg_index
), 시퀀스 , 뷰 , 구체화 된 뷰 , 복합 유형 및 TOAST 테이블이 포함됩니다. ;
이 특정 질문에 대해 시스템보기를pg_tables
사용할 수도 있습니다 . 주요 Postgres 버전에서 조금 더 간단하고 이식성이 뛰어납니다 (이 기본 쿼리에는 거의 관심이 없습니다).
SELECT EXISTS (
SELECT FROM pg_tables
WHERE schemaname = 'schema_name'
AND tablename = 'table_name'
);
식별자는 모두 고유해야 합니다 위에서 언급 한 개체 합니다. 물어보고 싶은 경우 :
주어진 스키마에서 테이블 또는 유사한 객체의 이름이 사용되는지 확인하는 방법은 무엇입니까?
SELECT EXISTS (
SELECT FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'schema_name'
AND c.relname = 'table_name'
);
SELECT 'schema_name.table_name'::regclass
이 예외를 발생 제 (검증을 거친 스키마) 테이블 (또는 그 이름을 점유하는 다른 개체)가 존재하지 않는 경우.
테이블 이름을 스키마로 한정하지 않으면 캐스트는 regclass
기본적으로로 설정되어 search_path
발견 된 첫 번째 테이블에 대한 OID를 반환합니다. 시스템 스키마 pg_catalog
와pg_temp
(현재 세션의 임시 객체에 대한 스키마)는 자동으로의 일부입니다 search_path
.
이것을 사용하고 함수에서 가능한 예외를 잡을 수 있습니다. 예:
위와 같은 쿼리는 가능한 예외를 피하므로 약간 더 빠릅니다.
훨씬 간단 해졌습니다 :
SELECT to_regclass('schema_name.table_name');
캐스트와 동일 하지만 반환합니다 ...
... 이름을 찾지 못하면 오류가 발생하지 않고 null
[[ `psql dbname -tAc "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'ejabberd' AND table_name = 'users');"` = 't' ]]