programing

지정된 스키마에 테이블이 있는지 확인하는 방법

sourcejob 2023. 5. 29. 10:38
반응형

지정된 스키마에 테이블이 있는지 확인하는 방법

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 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_index), 시퀀스, , 구체화된 뷰, 복합 유형 및 TOST 표;

이 특정 질문에 대해서는 시스템 뷰를 사용할 수도 있습니다. 주요 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기본값은 로 설정되며 발견된 첫 번째 테이블에 대한 OID를 반환합니다. 또는 나열된 스키마에 테이블이 없는 경우 예외를 반환합니다.시스템 스키마pg_catalog그리고.pg_temp세션의 에 대한 는으로 (으)로 된 (으)로 됩니다.search_path.

이를 사용하여 함수에서 발생할 수 있는 예외를 탐지할 수 있습니다.예:

위와 같은 쿼리는 가능한 예외를 방지하므로 약간 더 빠릅니다.

이름이 리터럴 문자열로 지정되는 위의 쿼리와 달리 여기서는 이름의 각 구성 요소가 식별자로 처리됩니다.식별자는 이중 따옴표로 묶이지 않는 한 소문자로 캐스팅됩니다.이중 따옴표를 사용하여 불법 식별자를 강제로 지정한 경우 이러한 식별자를 포함해야 합니다.예:

SELECT '"Dumb_SchName"."FoolishTbl"'::regclass;

참조:

to_regclass(rel_name) Postgres 9.4+에서

훨씬 단순해졌습니다.

SELECT to_regclass('schema_name.table_name');

출연진들과 똑같지만, 다시 돌아오는 건...

이름을 찾을 수 없는 경우 오류를 발생시키는 대신 null입니다.

information_schema를 사용합니다.

SELECT EXISTS(
    SELECT * 
    FROM information_schema.tables 
    WHERE 
      table_schema = 'company3' AND 
      table_name = 'tableincompany3schema'
);

Postgre용SQL 9.3 이하...아니면 텍스트로 정규화된 모든 것을 좋아하는 사람.

의 세 맛: 내오래된스칼위도세의관가맛지서스::맛:relname_exists(anyThing),relname_normalized(anyThing)그리고.relnamechecked_to_array(anyThing)pg_catalog.pg_class 테이블에서 모든 검사를 수행하고 표준 범용 데이터 유형(부울, 텍스트 또는 텍스트[])을 반환합니다.

/**
 * 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

반응형