Bir sorgu, tablo veya görünümün çıktı sütun adlarını ve veri türlerini döndürme sorgusu


21

Bir sorgu, tablo veya görünümün alan adlarını ve alan türlerini döndüren bir PostgreSQL sorgusu veya komutu var mı?

Örneğin, basit SELECT sorgusuna uygulanırsa bir çözüm şöyle SELECT * from personbir liste döndürmelidir:

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

information_schemaAşağıda bir cevapta açıklanan görüşlere baktım ve tabloları oldukça iyi kapsar gibi görünüyor ve ben de görüşlerini kapsayan şüpheli ama henüz kontrol etmedi.

Sonuncusu, herhangi bir keyfi ancak geçerli SELECT sorgusudur, örneğin veritabanına JOINS, UNIONSvb. Dahil olmak. Herhangi bir geçerli QUERY için aynısını döndürebilen yerleşik bir yordam veya başka bir saklı yordam veya komut dosyası var mı?

Veri oluşturan ve formları sorgulayan bir program geliştiriyorum ve bilgi veri doğrulama ve döndürülen verilerdeki işlevleri yürütmek için gereklidir.


Açıkçası tek bir "komut" yoktur, ancak sistem kataloglarından bilgi almanın çeşitli yolları vardır. Lütfen belirli bir soru sorun , bir örnek ve karşılığında ne beklediğinizi ekleyin ve arkasındaki niyet hakkında bize bir fikir verin.
Erwin Brandstetter

1
Basitliğin nedeni, istemciler SELECTsorgularda, yani sorgularda, yani tablolarda, görünümlerde veya diğer sorgularda veri tanımlama veya veri işleme sorguları söz konusu olduğunda , PostgreSQL'in sütun adlarının listesi ve veri türleri. information_schemaCevapları aşağıda belirtilen görüşleri tablolar ve görünümler için cevap görünmektedir. Keyfi SELECT sorguları son sınırdır. Daha iyi açıklamak için cevabı düzenleyeceğim
vfclists

Yanıtlar:


22

Bilgi şeması ve sistem katalogları

Bunun hakkında birçok kez tartıştık. Bilgi şeması belirli amaçlara hizmet eder. Sistem kataloglarında yolunuzu biliyorsanız, bunlar çoğu amaca daha iyi hizmet eder , IMO. Sistem katalogları tüm bilgilerin asıl kaynağıdır.

Bilgi şema sorgularınız sistem katalogları aramak için ihtiyaca sofistike yeterlidir kez farklı RDBMS platformlarındaki taşınabilirlik tipik bir yanılsama olduğu için yardım çoğunlukla büyük Postgres sürümleri arasında taşınabilirlik, birlikte, görüşlerini standardize sağlar. Ve özellikle Oracle hala bilgi şemasını desteklemiyor.

Bilgi şemasındaki görünümler, standarda uygun bir biçim elde etmek için birçok çemberin içinden atlamak zorundadır. Bu onları yavaş, bazen çok yavaş yapar. Bu temel nesneler için planları ve performansı karşılaştırın:

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

Fark dikkat çekicidir. Gerçekten ne aradığınıza bağlıdır.

Örneğiniz

Örneğin SELECT * from tbl, bu basit tablo için aşağıdaki iki sorguyu karşılaştırın:

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

Kullanma 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() tüm değiştiricileri içeren tam türü döndürür:

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

Ayrıca regclass, akıma göre tablo adını biraz akıllıca çözecek şekilde yayınlandığına dikkat edin search_path. Ayrıca, ad geçerli değilse bir istisna oluşturur. Detaylar:

Kullanma information_schema.columns:

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

Bilgiler standartlaştırılmıştır, ancak eksik :

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

Veri türü hakkında tam bilgi almak için bu sütunların tümünü ayrıca dikkate almanız gerekir:

character_maximum_length
character_octet_length
numeric_precision
numeric_precision_radix
numeric_scale
datetime_precision
interval_type
interval_precision

İlgili cevaplar:

Bir listesi artıları ve eksileri , kalın büyük artıları (IMO):

Bilgi şeması görünümleri

  • genellikle daha basit (bağlıdır)
  • yavaş
  • Önceden işlenmiş, ihtiyaçlarınıza uygun olabilir veya olmayabilir
  • seçici (kullanıcılar yalnızca ayrıcalıklarına sahip oldukları nesneleri görürler)
  • SQL standardına uygunluk (bazı büyük RDBMS'ler tarafından uygulanır)
  • çoğunlukla büyük Postgres sürümlerinde taşınabilir
  • Postgres hakkında çok özel bilgi gerektirmez
  • tanımlayıcılar açıklayıcı, uzun ve bazen gariptir

Sistem katalogları

  • genellikle daha karmaşık (bağımlı), kaynağa daha yakın
  • hızlı
  • complete ( oiddahil edilen sistem sütunları )
  • SQL standardına uymamak
  • büyük Postgres sürümlerinde daha az taşınabilir (ancak temel bilgiler değişmeyecek)
  • Postgres hakkında daha spesifik bilgi gerektirir
  • tanımlayıcılar kısa, daha az açıklayıcı ancak kısa

Rasgele sorgu

Bir sorgudan aynı sütun adları ve türleri listesini almak için basit bir hile kullanabilirsiniz: Sorgu çıktısından geçici bir tablo OLUŞTURUN , sonra yukarıdakiyle aynı teknikleri kullanın.

LIMIT 0Gerçek verilere ihtiyacınız olmadığından ekleyebilirsiniz.

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

Tek tek sütunların veri türünü almak için aşağıdaki işlevi de kullanabilirsiniz pg_typeof():

SELECT pg_typeof(1);

Çok teşekkür ederim. Bir süre için pg_attribute sütun veri türü almak için bakıyordum ve sadece bu yazı rastladı. Gönderinizi takdir edin.
Melinda

Bu genel olarak yararlıdır, ancak SELECT ifadesinin sunduğu sütunların veri türleri hakkında nasıl bilgi edinileceği hakkındaki orijinal soruyu yanıtlamaz. O was değil de bilgi şemasındaki gösterilmektedir sistem kataloglarında kurs, İkamet ve görünümleri veya tabloları sütunlar, yaklaşık.
Holger Jakobs


2

Pg_catalog erişiminiz varsa ve PgAdmin3 kullanıyorsanız, Valentine's Tech blogunda bulduğum bir çözümü şiddetle tavsiye ederim ( http://tech.valgog.com/2011/02/pgadmin-iii-macros-get-table-fields. html ). Seçili bir tablo adının tanımını görüntülemek için bir kısayolla erişilebilen bir PgAdmin3 makrosudur.

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;

Bir cazibe gibi çalışır ve son derece yararlı.


1

Kullanım görüşlerini , onlar sizsiniz, SQL standardı ve istediğiniz bilgileri içerir.information_schema

Ayrıca doğrudan erişim pg_class, pg_attributevb, ama bu genellikle fiddlier unportable ve var; Eğer gerekebilir gibi yardımcı işlevlerinioidvectortypes , pg_get_function_argumentsbazı şeyler için, vb.

Nasıl bir psqlşey yürüttüğünü görmek istiyorsanız \dt, çalıştırın psql -E- sorguyu yazdırır. Ancak, information_schemaihtiyaçlarınızı karşılayacaksa kullanmak daha iyidir .


1

Bu aşırı basit olabilir, ancak pgAdmin4 çıktı sonuçlarındaki alan türlerini gösterir. Yukarıdaki diğer çözümler muhtemelen daha zariftir, ancak hızlı bir cevaba ihtiyacım olduğunda, pgAdmin4'ün sorgu GUI'sinin oldukça iyi çalıştığını görüyorum. Bir görünüm veya işlev tarafından döndürülen hesaplanmış bir alanın alan türünü anlamaya çalışmak zor olabilir.

resim açıklamasını buraya girin


PgAdmin4'ün bunu yapması çok güzel, ama bunu nasıl yapıyor? Bulabilir miyiz olmadan PgAdmin4 tüm kaynak koduna göz tarayarak?
Holger Jakobs
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.