Wählen Sie den Datentyp des Feldes in postgres


165

Wie erhalte ich den Datentyp eines bestimmten Felds aus einer Tabelle in Postgres? Zum Beispiel habe ich die folgende Tabelle: student_details (stu_id integer, stu_name varchar (30), join_date timestamp);

In diesem Fall muss ich unter Verwendung des Feldnamens / oder auf andere Weise den Datentyp des spezifischen Felds abrufen. Gibt es eine Möglichkeit ?


1
Auch gefragt und beantwortet stackoverflow.com/q/20194806/65458
Piotr Findeisen

Antworten:


173

Sie können Datentypen aus dem information_schema abrufen (8.4 Dokumente, auf die hier verwiesen wird, dies ist jedoch keine neue Funktion):

=# select column_name, data_type from information_schema.columns
-# where table_name = 'config';
    column_name     | data_type 
--------------------+-----------
 id                 | integer
 default_printer_id | integer
 master_host_enable | boolean
(3 rows)

So einfach und nett! Jetzt kann ich die aktuelle Abfrage ersetzen, die ich gefunden habe: 310 Zeichen (ohne Tabellennamen), 4 Tabellenverknüpfungen, nicht schemabewusst, teuer, und die 'int4' und andere als Typen anstelle von Ganzzahlen angibt. Danke dir!
einige

2
Mit PostgreSQL können Sie denselben Tabellennamen (sogar eine identische Tabelle) in mehreren Schemas verwenden. Die robuste Methode zum Schreiben dieser WHERE-Klausel berücksichtigt diese Möglichkeit: where table_catalog = ? and table_schema = ? and table_name = ?;In dieser Ansicht information_schema wird jedoch nicht berücksichtigt, dass die DDL möglicherweise Domänen verwendet hat .
Mike Sherrill 'Cat Recall'

1
Dies gibt Ihnen nicht die Art des Arrays, so muss es zusammen mitpg_typeof
Daria

146

Sie können die Funktion pg_typeof () verwenden, die auch für beliebige Werte gut funktioniert.

SELECT pg_typeof("stu_id"), pg_typeof(100) from student_details limit 1;

Dies gibt eine Zeile pro Datensatz in der Tabelle zurück. Führen Sie es nicht aus, wenn Sie Millionen von Datensätzen haben
Saarang

3
Dies funktioniert wunderbar, wenn Sie den Typ einer Berechnung bestimmen müssen. zB ist SELECT pg_typeof( date_part( 'year', now() ) ) AS exprwahrscheinlich anders als erwartet.
Leo Orientis

Das Schlaue dabei ist, dass es pg_typeoffür Felder funktioniert, die aus gespeicherten Prozeduren stammen, für die die Backend-Tabelle, falls sie überhaupt existiert, unbekannt / unklar ist. select state, qstart, pg_typeof(qstart) as ty_qstart from listconn(). information_schema würde hier nicht viel helfen.
JL Peyret

40

Versuchen Sie diese Anfrage:

SELECT column_name, data_type FROM information_schema.columns WHERE 
table_name = 'YOUR_TABLE' AND column_name = 'YOUR_FIELD';

4
table_name = 'YOUR_TABLE' AND column_name = 'YOUR_FIELD';
Haitham

38

laufen psql -Eund dann\d student_details


einfach und nützlich
horoyoi o

11

Wenn Sie die Lösung 'Mike Sherrill' mögen, aber keine psql verwenden möchten, habe ich diese Abfrage verwendet, um die fehlenden Informationen abzurufen:

select column_name,
case 
    when domain_name is not null then domain_name
    when data_type='character varying' THEN 'varchar('||character_maximum_length||')'
    when data_type='numeric' THEN 'numeric('||numeric_precision||','||numeric_scale||')'
    else data_type
end as myType
from information_schema.columns
where table_name='test'

mit Ergebnis:

column_name |     myType
-------------+-------------------
 test_id     | test_domain
 test_vc     | varchar(15)
 test_n      | numeric(15,3)
 big_n       | bigint
 ip_addr     | inet

8

Die Informationsschemaansichten und pg_typeof () geben unvollständige Typinformationen zurück. Gibt von diesen Antworten psqldie genauesten Typinformationen. (Das OP benötigt möglicherweise keine so genauen Informationen, sollte jedoch die Einschränkungen kennen.)

create domain test_domain as varchar(15);

create table test (
  test_id test_domain, 
  test_vc varchar(15), 
  test_n numeric(15, 3), 
  big_n bigint,
  ip_addr inet
);

Verwendung psqlund \d public.testzeigt korrekte Verwendung des Datentyps test_domain, der Länge der VARCHAR (n) Spalten, und die Präzision und den Umfang der numerischen (p, n) Spalten.

sandbox = # \ d public.test
             Tabelle "public.test"
 Spalte | Geben Sie | ein Modifikatoren
--------- + ----------------------- + -----------
 test_id | test_domain |
 test_vc | Zeichen variierend (15) |
 test_n | numerisch (15,3) |
 big_n | bigint |
 ip_addr | inet |

Diese Abfrage für eine information_schema-Ansicht zeigt die Verwendung von überhaupt nichttest_domain an. Es werden auch keine Details zu varchar (n) und numerischen (p, s) Spalten gemeldet.

select column_name, data_type 
from information_schema.columns 
where table_catalog = 'sandbox'
  and table_schema = 'public'
  and table_name = 'test';
Spaltenname | Datentyp
------------- + -------------------
 test_id | Zeichen variiert
 test_vc | Zeichen variiert
 test_n | numerisch
 big_n | Bigint
 ip_addr | inet

Sie könnten der Lage sein , alle diese Informationen zu erhalten , indem andere information_schema Ansichten Beitritt oder durch direkt die Systemtabellen abfragen. psql -Ekönnte dabei helfen.

Die Funktion pg_typeof()zeigt die Verwendung von test_domainvarchar (n) und numerischen (p, s) Spalten korrekt an , meldet jedoch nicht die Details.

select pg_typeof(test_id) as test_id, 
       pg_typeof(test_vc) as test_vc,
       pg_typeof(test_n) as test_n,
       pg_typeof(big_n) as big_n,
       pg_typeof(ip_addr) as ip_addr
from test;
   test_id | test_vc | test_n | big_n | ip_addr
------------- + ------------------- + --------- + ------ - + ---------
 test_domain | Zeichen variieren | numerisch | bigint | inet

4

Das Abrufen des Datentyps von information_schemaist möglich, aber nicht bequem (erfordert das Verknüpfen mehrerer Spalten mit einer caseAnweisung). Alternativ kann man die format_typeeingebaute Funktion verwenden, dies funktioniert jedoch mit internen Typkennungen, die in, pg_attributeaber nicht in sichtbar sind information_schema. Beispiel

SELECT a.attname as column_name, format_type(a.atttypid, a.atttypmod) AS data_type
FROM pg_attribute a JOIN pg_class b ON a.attrelid = b.relfilenode
WHERE a.attnum > 0 -- hide internal columns
AND NOT a.attisdropped -- hide deleted columns
AND b.oid = 'my_table'::regclass::oid; -- example way to find pg_class entry for a table

Basierend auf https://gis.stackexchange.com/a/97834 .


1
Für die Nachwelt mit pg10 ersetzen b.relfilenodedurchb.oid
tswaters
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.