Seleziona il tipo di dati del campo in postgres


165

Come posso ottenere il tipo di dati di un campo specifico dalla tabella in postgres? Ad esempio, ho la tabella seguente, student_details (numero intero stu_id, nome_stu varchar (30), data / ora del join_data);

In questo usando il nome del campo / o in qualsiasi altro modo, ho bisogno di ottenere il tipo di dati del campo specifico. C'è qualche possibilità?


1
Ha anche chiesto e risposto stackoverflow.com/q/20194806/65458
Piotr Findeisen

Risposte:


173

Puoi ottenere tipi di dati da information_schema (8.4 documenti citati qui, ma questa non è una nuova funzionalità):

=# 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)

Così semplice e carino! Ora posso sostituire la query corrente che ho trovato di 310 caratteri (senza il nome della tabella), 4 join di tabella, non compatibile con lo schema, costoso e che fornisce "int4" e altri come tipi anziché intero. Grazie!
un po '

2
PostgreSQL ti consente di avere lo stesso nome di tabella (anche una tabella identica) in più schemi. Il modo affidabile per scrivere quella clausola WHERE considera questa possibilità: where table_catalog = ? and table_schema = ? and table_name = ?;Ma questa visualizzazione information_schema non considera che il DDL potrebbe aver usato domini .
Mike Sherrill "Cat Recall",

1
Questo non ti darà il tipo di array, quindi deve essere usato insieme apg_typeof
Daria,

146

È possibile utilizzare la funzione pg_typeof () , che funziona anche con valori arbitrari.

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

questo restituisce una riga per record nella tabella. Non eseguirlo se hai milioni di dischi
Saarang

3
Funziona magnificamente se è necessario ottenere la determinazione del tipo di calcolo. ad esempio, SELECT pg_typeof( date_part( 'year', now() ) ) AS exprprobabilmente è diverso da quello che ti aspetteresti.
Leo Orientis,

la cosa intelligente qui è che pg_typeoffunziona per i campi che escono da stored procedure, per cui la tabella di backend, se esiste, è sconosciuta / non chiara. select state, qstart, pg_typeof(qstart) as ty_qstart from listconn(). information_schema non sarebbe di grande aiuto qui.
JL Peyret,

40

Prova questa richiesta:

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

corri psql -Ee poi\d student_details


semplice e utile
horoyoi o

11

Se ti piace la soluzione "Mike Sherrill" ma non vuoi usare psql, ho usato questa query per ottenere le informazioni mancanti:

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'

con risultato:

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

8

Le viste dello schema di informazioni e pg_typeof () restituiscono informazioni di tipo incomplete. Di queste risposte, psqlfornisce le informazioni più precise sul tipo. (L'OP potrebbe non aver bisogno di informazioni così precise, ma dovrebbe conoscere i limiti.)

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
);

L'utilizzo psqle \d public.testmostra correttamente l'uso del tipo di dati test_domain, la lunghezza delle colonne varchar (n) e la precisione e la scala delle colonne numeriche (p, s).

sandbox = # \ d public.test
             Tabella "public.test"
 Colonna | Digita | modificatori
--------- + ----------------------- + -----------
 test_id | test_domain |
 test_vc | carattere variabile (15) |
 test_n | numerico (15,3) |
 big_n | bigotto |
 ip_addr | inet |

Questa query su una vista information_schema non mostra affatto l'uso di test_domain. Inoltre non riporta i dettagli delle colonne varchar (n) e numeriche (p, s).

select column_name, data_type 
from information_schema.columns 
where table_catalog = 'sandbox'
  and table_schema = 'public'
  and table_name = 'test';
nome_colonna | tipo di dati
------------- + -------------------
 test_id | carattere variabile
 test_vc | carattere variabile
 test_n | numerico
 big_n | bigint
 ip_addr | inet

Si potrebbe essere in grado di ottenere tutte le informazioni che unendo altre viste INFORMATION_SCHEMA, o interrogando direttamente le tabelle di sistema. psql -Epotrebbe aiutare con quello.

La funzione pg_typeof()mostra correttamente l'uso di test_domain, ma non riporta i dettagli delle colonne varchar (n) e numeriche (p, s).

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 | carattere variabile | numerico | bigotto | inet

4

Estrarre il tipo di dati information_schemaè possibile, ma non conveniente (richiede l'unione di più colonne con caseun'istruzione). In alternativa, è possibile utilizzare la format_typefunzione integrata per farlo, ma funziona su identificatori di tipo interni che sono visibili in pg_attributema non in information_schema. Esempio

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

Basato su https://gis.stackexchange.com/a/97834 .


1
Per i posteri, con pg10 sostituire b.relfilenodeconb.oid
tswaters
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.