쿼리, 테이블 또는 뷰의 출력 열 이름 및 데이터 유형을 반환하는 쿼리


21

쿼리, 테이블 또는 뷰의 필드 이름과 필드 유형을 반환하는 PostgreSQL 쿼리 또는 명령이 있습니까?

예를 들어, 간단한 SELECT 쿼리에 적용되는 솔루션 SELECT * from person은 다음과 같은 목록을 반환해야합니다.

Column Name   | Column Type
===========================
First Name    | character
Last Name     | character
Age           | integer
Date of Birth | date

information_schema아래 답변에 설명 된보기를 살펴 보았고 테이블을 잘 다루는 것 같으며보기도 포함한다고 생각하지만 아직 확인하지 않았습니다.

마지막으로는 임의하지만 유효한 SELECT 쿼리 등 포함입니다 JOINS, UNIONS데이터베이스에 등. 유효한 QUERY에 대해 동일하게 리턴 할 수있는 내장 프로 시저 또는 기타 스토어드 프로 시저 또는 스크립트가 있습니까?

데이터를 만들고 양식을 쿼리하는 프로그램을 개발 중이며 정보가 데이터 유효성 검사 및 반환 된 데이터에서 함수를 실행하는 데 필요합니다.


분명히 "명령"은 하나도 없지만 시스템 카탈로그에서 정보를 검색하는 다양한 방법이 있습니다. 요청하시기 바랍니다 특정 질문을 대가로 예를 들어 어떤 예상을 추가하고, 우리에게 그 뒤에 의도에 대한 아이디어를 제공합니다.
Erwin Brandstetter 1

1
단순성의 이유는 클라이언트가 SELECT쿼리, 즉 쿼리, 즉 비 데이터 정의 또는 데이터 조작 쿼리와 관련하여 테이블, 뷰 또는 기타 쿼리가 데이터의 행과 열을 반환하는지 여부에 관계없이 PostgreSQL은 다음을 반환 할 수 있기 때문입니다. 열 이름 및 해당 데이터 유형 목록. information_schema답변에서 아래에 언급 된 보기는 테이블 및보기에 대한 것으로 보입니다. 임의의 SELECT 쿼리가 최종 경계입니다. 더 잘 설명하기 위해 답변을 편집하겠습니다
vfclists

답변:


22

정보 스키마시스템 카탈로그

우리는 이것에 대해 여러 번 토론했습니다. 정보 스키마는 특정 목적을 수행합니다. 시스템 카탈로그를 둘러 보는 방법을 알고 있다면 IMO가 대부분의 목적에 더 적합 합니다. 시스템 카탈로그는 모든 정보의 실제 소스입니다.

정보 스키마는 쿼리가 시스템 카탈로그를 조회해야하는 복잡한 정도가되면 다른 RDBMS 플랫폼 이식성은 일반적으로 환상 때문에 도움 대부분의 주요 포스트 그레스 버전 이식성과, 뷰를 표준화 제공합니다. 특히, Oracle은 여전히 ​​정보 스키마를 지원하지 않습니다.

정보 스키마의 뷰는 표준을 준수하는 형식을 달성하기 위해 많은 후프를 뛰어 넘어야합니다. 이로 인해 속도가 느려지고 때로는 매우 느립니다. 이러한 기본 개체에 대한 계획과 성능을 비교하십시오.

EXPLAIN ANALYZE SELECT * from information_schema.columns;
EXPLAIN ANALYZE SELECT * from pg_catalog.pg_attribute;

그 차이는 놀랍습니다. 그것은 실제로 당신이 찾고있는 것에 달려 있습니다.

당신의 예

예를 들어 SELECT * from tbl,이 간단한 테이블에 대해 아래 두 쿼리를 비교하십시오.

CREATE TEMP TABLE foo(
   A numeric(12,3)
 , b timestamp(0)
);

사용 pg_attribute:

SELECT attname, format_type(atttypid, atttypmod) AS type
FROM   pg_attribute
WHERE  attrelid = 'foo'::regclass
AND    attnum > 0
AND    NOT attisdropped
ORDER  BY attnum;

format_type() 모든 수정 자와 함께 전체 유형을 반환합니다.

attname | type
--------+-------------------------------
a       | numeric(12,3)
b       | timestamp(0) without time zone

또한 캐스트 regclass는 현재에 따라 테이블 이름을 다소 지능적 으로 해석합니다 search_path. 이름이 유효하지 않은 경우에도 예외가 발생합니다. 세부:

사용 information_schema.columns:

SELECT column_name, data_type
FROM   information_schema.columns
WHERE  table_name = 'foo'
ORDER  BY ordinal_position;

정보는 표준화되었지만 불완전합니다 .

column_name | data_type
------------+----------------------------
a           | numeric
b           | timestamp without time zone

데이터 유형에 대한 전체 정보를 얻으려면 다음 열을 모두 추가로 고려해야합니다.

character_maximum_length
character_octet_length
numeric_precision
numeric_precision_radix
numeric_scale
datetime_precision
interval_type
interval_precision

관련 답변 :

가장 큰 장점 (IMO) 인 장단점 목록 :

정보 스키마 뷰

  • 종종 더 단순하다 (의존한다)
  • 느린
  • 사전 처리, 요구 사항에 맞거나 맞지 않을 수 있음
  • 선택적 (사용자에게는 권한이있는 개체 만 표시됨)
  • SQL 표준 준수 (일부 주요 RDBMS에 의해 구현 됨)
  • 대부분의 주요 Postgres 버전에서 이식 가능
  • Postgres에 대한 특정 지식이 필요하지 않습니다
  • 식별자는 설명 적이며 길고 때로는 어색합니다.

시스템 카탈로그

  • 소스에 더 가깝고 종종 더 복잡합니다 (의존적)
  • 빠른
  • 완료 ( oid포함 된 시스템 열 )
  • SQL 표준을 준수하지 않음
  • 주요 Postgres 버전에서 이식성이 떨어짐 (기본 사항은 변경되지 않음)
  • Postgres에 대한보다 구체적인 지식이 필요합니다
  • 식별자는 간결하고 설명이 적지 만 편리합니다.

임의 쿼리

쿼리에서 동일한 열 이름 및 유형 목록을 얻으려면 간단한 트릭 을 사용하십시오. 쿼리 출력에서 임시 테이블 을 만든 다음 위와 동일한 기술을 사용하십시오.

LIMIT 0실제 데이터가 필요하지 않으므로을 추가 할 수 있습니다 .

CREATE TEMP TABLE tmp123 AS
SELECT 1::numeric, now()
LIMIT  0;

개별 열의 데이터 유형을 얻으려면 다음 함수를 사용할 수도 있습니다 pg_typeof().

SELECT pg_typeof(1);

정말 고맙습니다. 나는 잠시 동안 pg_attribute에서 열의 데이터 유형을 얻는 방법을 찾고 있었고이 게시물을 보았습니다. 게시물 감사합니다.
Melinda

이것은 일반적으로 도움이되지만 SELECT 문이 제공하는 열의 데이터 형식에 대한 정보를 얻는 방법에 대한 원래 질문에는 대답하지 않습니다. 뷰 또는 테이블의 열에 관한 것이 아니며 시스템 카탈로그에 상주하고 정보 스키마에도 표시됩니다.
Holger Jakobs


2

pg_catalog에 액세스하고 PgAdmin3을 사용하는 경우 Valentine 's Tech 블로그 ( http://tech.valgog.com/2011/02/pgadmin-iii-macros-get-table-fields) 에서 찾은 솔루션을 적극 권장합니다 . html ). 선택한 테이블 이름의 정의를 표시하기 위해 바로 가기로 액세스 할 수있는 PgAdmin3 매크로입니다.

select quote_ident(nspname) || '.' || quote_ident(relname) as table_name, 
       quote_ident(attname) as field_name, 
       format_type(atttypid,atttypmod) as field_type, 
       case when attnotnull then ' NOT NULL' else '' end as null_constraint,
       case when atthasdef then 'DEFAULT ' || 
                                ( select pg_get_expr(adbin, attrelid) 
                                    from pg_attrdef 
                                   where adrelid = attrelid and adnum = attnum )::text else ''
       end as dafault_value,
       case when nullif(confrelid, 0) is not null
            then confrelid::regclass::text || '( ' || 
                 array_to_string( ARRAY( select quote_ident( fa.attname ) 
                                           from pg_attribute as fa 
                                          where fa.attnum = ANY ( confkey ) 
                                            and fa.attrelid = confrelid
                                          order by fa.attnum 
                                        ), ','
                                 ) || ' )'
            else '' end as references_to
  from pg_attribute 
       left outer join pg_constraint on conrelid = attrelid 
                                    and attnum = conkey[1] 
                                    and array_upper( conkey, 1 ) = 1,
       pg_class, 
       pg_namespace
 where pg_class.oid = attrelid
   and pg_namespace.oid = relnamespace
   and pg_class.oid = btrim( '$SELECTION$' )::regclass::oid
   and attnum > 0
   and not attisdropped
 order by attrelid, attnum;

매력처럼 작동하며 매우 유용합니다.


1

사용 전망을 , 그들이있는 거 SQL 표준과 원하는 정보가 포함되어 있습니다.information_schema

당신은 또한 직접 액세스 pg_class, pg_attribute등,하지만 종종 fiddlier 인자를 취하지와의; 당신이해야 할 수도 와 같은 도우미 기능oidvectortypes , pg_get_function_arguments몇 가지에 대해, 등.

어떻게보고 싶다면 psql같은 실행하는 뭔가 \dt를 실행 psql -E- 그것은 쿼리를 인쇄 할 수 있습니다. 그러나 information_schema필요에 따라 if 를 사용하는 것이 좋습니다 .


1

이것은 매우 간단하지만 pgAdmin4는 출력 결과에 필드 유형을 보여줍니다. 위의 다른 솔루션은 아마도 더 우아 할 수 있지만 빠른 답변이 필요할 때 pgAdmin4의 쿼리 GUI가 잘 작동한다는 것을 알았습니다. 뷰 또는 함수에 의해 반환 된 계산 된 필드의 필드 유형을 파악하는 것은 까다로울 수 있습니다.

여기에 이미지 설명을 입력하십시오


pgAdmin4가이 작업을 수행하는 것이 매우 좋지만 어떻게 수행합니까? PgAdmin4의 모든 소스 코드를 스캔 하지 않고도 알 수 있습니까 ?
Holger Jakobs
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.