Ne abbiamo discusso molte volte. Lo schema informativo ha determinati scopi. Se conosci i cataloghi di sistema, quelli servono meglio gli scopi , IMO. I cataloghi di sistema sono la vera fonte di tutte le informazioni.
Lo schema informativo fornisce viste standardizzate che aiutano la portabilità, soprattutto nelle principali versioni di Postgres, perché la portabilità su piattaforme RDBMS diverse è in genere un'illusione quando le tue query sono abbastanza sofisticate da richiedere la ricerca di cataloghi di sistema. E, in particolare, Oracle non supporta ancora lo schema delle informazioni.
Le viste nello schema delle informazioni devono passare attraverso molti cerchi per ottenere un formato conforme allo standard. Questo li rende lenti, a volte molto lenti. Confronta piani e prestazioni per questi oggetti di base:
EXPLAIN ANALYZE SELECT * from information_schema.columns;
EXPLAIN ANALYZE SELECT * from pg_catalog.pg_attribute;
La differenza è notevole. Dipende davvero da cosa stai cercando.
Il tuo esempio
Per il tuo esempio SELECT * from tbl
, confronta le due query seguenti per questa semplice tabella:
CREATE TEMP TABLE foo(
A numeric(12,3)
, b timestamp(0)
);
Utilizzando 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()
restituisce il tipo completo con tutti i modificatori:
attname | type
--------+-------------------------------
a | numeric(12,3)
b | timestamp(0) without time zone
Si noti inoltre che il cast regclass
risolve il nome della tabella in modo un po 'intelligente in base alla corrente search_path
. Inoltre genera un'eccezione se il nome non è valido. Dettagli:
Utilizzando information_schema.columns
:
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'foo'
ORDER BY ordinal_position;
Le informazioni sono standardizzate, ma incomplete :
column_name | data_type
------------+----------------------------
a | numeric
b | timestamp without time zone
Per ottenere informazioni complete per il tipo di dati, è necessario considerare anche tutte queste colonne:
character_maximum_length
character_octet_length
numeric_precision
numeric_precision_radix
numeric_scale
datetime_precision
interval_type
interval_precision
Risposte correlate:
Un elenco di pro e contro , i più grandi pro (IMO) in grassetto:
Viste dello schema di informazioni
- spesso più semplice (dipende)
- lento
- preelaborato, che può o meno soddisfare le tue esigenze
- selettivo (gli utenti vedono solo gli oggetti per i quali dispongono dei privilegi)
- conforme a uno standard SQL (implementato da alcuni dei principali RDBMS)
- per lo più portatile nelle principali versioni di Postgres
- non richiedono conoscenze specifiche su Postgres
- gli identificatori sono descrittivi, lunghi e talvolta imbarazzanti
Cataloghi di sistema
- spesso più complesso (dipende), più vicino alla fonte
- veloce
- completo (colonne di sistema come
oid
incluse)
- non conforme a uno standard SQL
- meno portatile tra le principali versioni di Postgres (ma le basi non cambieranno)
- richiede conoscenze più specifiche su Postgres
- gli identificatori sono concisi, meno descrittivi ma convenientemente brevi
Quesito arbitrario
Per ottenere lo stesso elenco di nomi e tipi di colonne da una query, è possibile utilizzare un semplice trucco: CREARE una tabella temporanea dall'output della query, quindi utilizzare le stesse tecniche di cui sopra.
È possibile aggiungere LIMIT 0
, poiché non sono necessari dati effettivi:
CREATE TEMP TABLE tmp123 AS
SELECT 1::numeric, now()
LIMIT 0;
Per ottenere il tipo di dati di singole colonne, puoi anche utilizzare la funzione pg_typeof()
:
SELECT pg_typeof(1);