복붙노트

[SQL] 테이블이 주어진 스키마에 존재하는지 확인하는 방법

SQL

테이블이 주어진 스키마에 존재하는지 확인하는 방법

포스트 그레스 8.4과 큰 데이터베이스는 기업 스키마 공공 스키마 및 회사의 특정 테이블에서 일반 테이블이 포함되어 있습니다. 회사 스키마 이름은 항상 회사 번호가 '기업'과 끝과 시작합니다. 그래서 같은 스키마가있을 수 있습니다 :

public
company1
company2
company3
...
companynn

응용 프로그램은 항상 하나의 회사와 함께 작동합니다. search_path의는 ODBC 또는 같은 npgsql 연결 문자열에 따라 지정됩니다

search_path='company3,public'

주어진 테이블은 특정 회사 스키마에 존재하는 경우 어떻게 확인할 것인가?

예를 들면 :

select isSpecific('company3','tablenotincompany3schema')

거짓을 반환해야하고

select isSpecific('company3','tableincompany3schema')

사실 반환해야합니다.

어떤 경우에, 기능은 companyn 스키마가 다른 스키마를 통과하지 확인해야합니다.

주어진 표는 공공 및 전달 스키마에 모두 존재하는 경우, 함수는 true를 반환해야합니다. 그것은 나중에 포스트 그레스 8.4에 대한 작동합니다.

해결법

  1. ==============================

    1.그것은 당신이 정확하게 테스트하려는 작업에 따라 달라집니다.

    그것은 당신이 정확하게 테스트하려는 작업에 따라 달라집니다.

    (상관없이 누가 요구하지 것) (INFORMATION_SCHEMA.TABLES) 정보 스키마를 조회 "테이블이 존재하는지 여부를"찾으려면 엄격하기 때문에 (문서 당), 말하기, 잘못된 것입니다 :

    @kong 제공하는 쿼리는 FALSE를 반환 할 수 있지만, 테이블은 여전히 ​​존재할 수 있습니다. 이 질문에 대한 답 :

    어떻게 테이블 (또는 뷰)가 존재하는지 여부를 확인하고 현재 사용자가 액세스 할 수있는가?

    SELECT EXISTS (
       SELECT FROM information_schema.tables 
       WHERE  table_schema = 'schema_name'
       AND    table_name   = 'table_name'
       );
    

    정보 스키마는 주요 버전에서 다른 RDBMS를 통해 휴대용 머물 주로 유용합니다. 포스트 그레스는 (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_tables를 사용할 수 있습니다. A는 (거의이 기본 쿼리에 대한 우려입니다) 주요 포스트 그레스 버전에서 간단하고 휴대용 비트 :

    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
    

    제 (검증을 거친 스키마) 테이블 (또는 그 이름을 점유하는 다른 개체)가 존재하지 않는 경우에 예외를 발생시킵니다.

    당신은 테이블 이름, 첫 번째 테이블의 OID가있는 search_path의 반환에 regclass 형 기본값으로 캐스팅 스키마가 필요하지 않은 경우 - 또는 예외를 테이블에 나열된 스키마 없음에있는 경우. 시스템 스키마 pg_catalog와 pg_temp (현재 세션의 임시 개체에 대한 스키마가) 자동으로 search_path의의 일부합니다.

    당신은 그것을 사용하는 기능에 가능한 예외를 잡을 수 있습니다. 예:

    위의 같은 쿼리는 가능한 예외를 방지하고 약간 빠른 때문에이다.

    지금은 훨씬 더 간단합니다 :

    SELECT to_regclass('schema_name.table_name');
    

    캐스트와 동일하지만 반환 ...

  2. ==============================

    2.아마도 INFORMATION_SCHEMA를 사용합니다 :

    아마도 INFORMATION_SCHEMA를 사용합니다 :

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

    3.내 옛날 SwissKnife 라이브러리의 세 가지 맛 : relname_exists (아무것도), relname_normalized (아무것도)와 relnamechecked_to_array (아무것도). 모든 pg_catalog.pg_class 테이블에서 확인하고 반환 표준 범용 데이터 유형 (부울, 텍스트 또는 텍스트 []).

    내 옛날 SwissKnife 라이브러리의 세 가지 맛 : relname_exists (아무것도), relname_normalized (아무것도)와 relnamechecked_to_array (아무것도). 모든 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;
    
  4. from https://stackoverflow.com/questions/20582500/how-to-check-if-a-table-exists-in-a-given-schema by cc-by-sa and MIT license