주어진 스키마에 테이블이 있는지 확인하는 방법
Postgres 8.4 이상 데이터베이스에는 public
스키마의 공통 테이블과 스키마의 회사 특정 테이블이 company
있습니다.
company
스키마 이름은 항상 'company'
회사 번호로 시작 하고 회사 번호로 끝납니다.
따라서 다음과 같은 스키마가있을 수 있습니다.
public
company1
company2
company3
...
companynn
응용 프로그램은 항상 단일 회사에서 작동합니다.
는 다음 search_path
과 같이 odbc 또는 npgsql 연결 문자열에 따라 지정됩니다.
search_path='company3,public'
주어진 테이블이 지정된 companyn
스키마에 존재하는지 어떻게 확인 합니까?
예 :
select isSpecific('company3','tablenotincompany3schema')
반환해야 false
하고,
select isSpecific('company3','tableincompany3schema')
반환해야합니다 true
.
어쨌든 함수는 companyn
다른 스키마가 아닌 전달 된 스키마 만 확인해야 합니다.
주어진 테이블이 public
전달 된 스키마와 둘 다에 있으면 함수는을 반환해야합니다 true
.
Postgres 8.4 이상에서 작동합니다.
정확히 테스트하려는 대상에 따라 다릅니다 .
정보 스키마?
( "테이블이 존재하는지 여부를"찾으려면 상관없이 누가 요구하지 것 ) 정보 스키마 (쿼리은 information_schema.tables
)는 잘못된 엄격하기 때문에 (, 말하기, 문서 당 ) :
현재 사용자가 (소유자 또는 일부 권한을 가지고) 액세스 할 수있는 테이블 및 뷰만 표시됩니다.
@kong 이 보여주는 쿼리 는을 반환 할 수 FALSE
있지만 테이블은 여전히 존재할 수 있습니다. 그것은 질문에 대답합니다 :
테이블 (또는 뷰)이 있는지 확인하고 현재 사용자가 테이블에 액세스 할 수 있는지 확인하는 방법은 무엇입니까?
SELECT EXISTS (
SELECT 1
FROM information_schema.tables
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
);
정보 스키마는 주로 주요 버전과 다른 RDBMS에서 이식성을 유지하는 데 유용합니다. 그러나 Postgres는 표준을 준수하기 위해 정교한 뷰를 사용해야하기 때문에 구현 속도가 느립니다 information_schema.tables
. 그리고 OID와 같은 일부 정보는 실제로 모든 정보를 전달 하는 시스템 카탈로그에서 번역시 손실됩니다 .
시스템 카탈로그
당신의 질문은 :
테이블이 있는지 확인하는 방법?
SELECT EXISTS (
SELECT 1
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 1
FROM pg_tables
WHERE schemaname = 'schema_name'
AND tablename = 'table_name'
);
식별자는 위에서 언급 한 모든 개체 중에서 고유 해야 합니다. 물어보고 싶은 경우 :
주어진 스키마에서 테이블 또는 유사한 객체의 이름이 사용되는지 확인하는 방법은 무엇입니까?
SELECT EXISTS (
SELECT 1
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'
);
Alternative: cast to regclass
SELECT 'schema_name.table_name'::regclass
This raises an exception if the (optionally schema-qualified) table (or other object occupying that name) does not exist.
If you do not schema-qualify the table name, a cast to regclass
defaults to the search_path
and returns the OID for the first table found - or an exception if the table is in none of the listed schemas. Note that the system schemas pg_catalog
and pg_temp
(the schema for temporary objects of the current session) are automatically part of the search_path
.
You can use that and catch a possible exception in a function. Example:
A query like above avoids possible exceptions and is therefore slightly faster.
to_regclass(rel_name)
in Postgres 9.4+
Much simpler now:
SELECT to_regclass('schema_name.table_name');
Same as the cast, but it returns ...
... null rather than throwing an error if the name is not found
Perhaps use information_schema:
SELECT EXISTS(
SELECT *
FROM information_schema.tables
WHERE
table_schema = 'company3' AND
table_name = 'tableincompany3schema'
);
For PostgreSQL 9.3 or less...Or who likes all normalized to text
Three flavors of my old SwissKnife library: relname_exists(anyThing)
, relname_normalized(anyThing)
and relnamechecked_to_array(anyThing)
. All checks from pg_catalog.pg_class table, and returns standard universal datatypes (boolean, text or text[]).
/**
* From my old SwissKnife Lib to your SwissKnife. License CC0.
* Check and normalize to array the free-parameter relation-name.
* Options: (name); (name,schema), ("schema.name"). Ignores schema2 in ("schema.name",schema2).
*/
CREATE FUNCTION relname_to_array(text,text default NULL) RETURNS text[] AS $f$
SELECT array[n.nspname::text, c.relname::text]
FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace,
regexp_split_to_array($1,'\.') t(x) -- not work with quoted names
WHERE CASE
WHEN COALESCE(x[2],'')>'' THEN n.nspname = x[1] AND c.relname = x[2]
WHEN $2 IS NULL THEN n.nspname = 'public' AND c.relname = $1
ELSE n.nspname = $2 AND c.relname = $1
END
$f$ language SQL IMMUTABLE;
CREATE FUNCTION relname_exists(text,text default NULL) RETURNS boolean AS $wrap$
SELECT EXISTS (SELECT relname_to_array($1,$2))
$wrap$ language SQL IMMUTABLE;
CREATE FUNCTION relname_normalized(text,text default NULL,boolean DEFAULT true) RETURNS text AS $wrap$
SELECT COALESCE(array_to_string(relname_to_array($1,$2), '.'), CASE WHEN $3 THEN '' ELSE NULL END)
$wrap$ language SQL IMMUTABLE;
참고URL : https://stackoverflow.com/questions/20582500/how-to-check-if-a-table-exists-in-a-given-schema
'development' 카테고리의 다른 글
postgres를 사용하여 간격을 여러 시간으로 어떻게 변환합니까? (0) | 2020.06.30 |
---|---|
활성 화면 크기를 얻으려면 어떻게해야합니까? (0) | 2020.06.30 |
Ruby에서 보호 및 개인 메소드를 단위 테스트하는 가장 좋은 방법은 무엇입니까? (0) | 2020.06.30 |
"캐시의 키 저장?" (0) | 2020.06.30 |
힘내 숨김 : "더러운 작업 트리에는 적용 할 수 없습니다. 변경 사항을 준비하십시오" (0) | 2020.06.30 |