Wir haben darüber oft diskutiert. Das Informationsschema dient bestimmten Zwecken. Wenn Sie sich in den Systemkatalogen auskennen, dienen diese den meisten Zwecken besser , IMO. Die Systemkataloge sind die eigentliche Quelle aller Informationen.
Das Informationsschema bietet standardisierte Ansichten, die die Portabilität erleichtern, vor allem über die wichtigsten Postgres-Versionen hinweg, da die Portabilität über verschiedene RDBMS-Plattformen in der Regel eine Illusion ist, wenn Ihre Abfragen so komplex sind, dass sie nach Systemkatalogen suchen müssen. Insbesondere unterstützt Oracle das Informationsschema immer noch nicht.
Ansichten im Informationsschema müssen durch viele Rahmen springen, um ein Format zu erreichen, das dem Standard entspricht. Das macht sie langsam, manchmal sehr langsam. Vergleichen Sie Pläne und Leistung für diese grundlegenden Objekte:
EXPLAIN ANALYZE SELECT * from information_schema.columns;
EXPLAIN ANALYZE SELECT * from pg_catalog.pg_attribute;
Der Unterschied ist bemerkenswert. Es kommt wirklich darauf an, wonach Sie suchen.
Dein Beispiel
SELECT * from tbl
Vergleichen Sie für Ihr Beispiel die beiden folgenden Abfragen für diese einfache Tabelle:
CREATE TEMP TABLE foo(
A numeric(12,3)
, b timestamp(0)
);
Verwenden von 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()
Gibt den vollständigen Typ mit allen Modifikatoren zurück:
attname | type
--------+-------------------------------
a | numeric(12,3)
b | timestamp(0) without time zone
Beachten Sie auch, dass die regclass
Umwandlung des Tabellennamens entsprechend der aktuellen Situation etwas intelligent ist search_path
. Es wird auch eine Ausnahme ausgelöst, wenn der Name nicht gültig ist. Einzelheiten:
Verwenden von information_schema.columns
:
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'foo'
ORDER BY ordinal_position;
Die Informationen sind standardisiert, aber unvollständig :
column_name | data_type
------------+----------------------------
a | numeric
b | timestamp without time zone
Um vollständige Informationen für den Datentyp zu erhalten, müssen Sie zusätzlich alle folgenden Spalten berücksichtigen:
character_maximum_length
character_octet_length
numeric_precision
numeric_precision_radix
numeric_scale
datetime_precision
interval_type
interval_precision
Verwandte Antworten:
Eine Liste der Vor-und Nachteile , die größten Vor-und Nachteile (IMO) in Fettschrift:
Informationsschema-Ansichten
- oft einfacher (ab)
- schleppend
- vorverarbeitet, je nachdem, ob es Ihren Anforderungen entspricht oder nicht
- selektiv (Benutzer sehen nur Objekte, für die sie Berechtigungen haben)
- Konform mit einem SQL-Standard (der von einigen der wichtigsten RDBMS implementiert wurde)
- meist portabel für alle gängigen Postgres-Versionen
- erfordern nicht viel spezifisches Wissen über Postgres
- Bezeichner sind beschreibend, lang und manchmal umständlich
Systemkataloge
- oft komplexer (hängt davon ab), näher an der Quelle
- schnell
- komplett (Systemspalten wie
oid
enthalten)
- entspricht nicht einem SQL-Standard
- weniger portabel für alle wichtigen Postgres-Versionen (aber die Grundlagen werden sich nicht ändern)
- erfordern genauere Kenntnisse über Postgres
- Bezeichner sind knapp, weniger beschreibend, aber zweckmäßig kurz
Beliebige Abfrage
Um dieselbe Liste von Spaltennamen und -typen aus einer Abfrage zu erhalten, können Sie einen einfachen Trick verwenden: ERSTELLEN Sie eine temporäre Tabelle aus der Abfrageausgabe und verwenden Sie dann dieselben Techniken wie oben.
Sie können Folgendes anhängen LIMIT 0
, da Sie keine aktuellen Daten benötigen:
CREATE TEMP TABLE tmp123 AS
SELECT 1::numeric, now()
LIMIT 0;
Um den Datentyp einzelner Spalten abzurufen, können Sie auch die Funktion verwenden pg_typeof()
:
SELECT pg_typeof(1);