Sélectionnez le type de données du champ dans postgres

165

Comment obtenir le type de données d'un champ spécifique à partir d'une table dans postgres? Par exemple, j'ai le tableau suivant, student_details (stu_id integer, stu_name varchar (30), join_date timestamp);

Dans ce cas en utilisant le nom du champ / ou de toute autre manière, je dois obtenir le type de données du champ spécifique. Y a-t-il une possibilité?

Nathan Villaescusa
la source
1
Également demandé et répondu à stackoverflow.com/q/20194806/65458
Piotr Findeisen

Réponses:

173

Vous pouvez obtenir des types de données à partir de l' information_schema (documentation 8.4 référencée ici, mais ce n'est pas une nouvelle fonctionnalité):

=# 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)
Wayne Conrad
la source
Si simple et sympa! Maintenant, je peux remplacer la requête actuelle que j'ai trouvée qui est de 310 caractères (sans le nom de la table), 4 jointures de table, pas de schéma conscient, cher, et qui donne «int4» et autres comme types au lieu d'entiers. Je vous remercie!
certains
2
PostgreSQL vous permet d'avoir le même nom de table (même une table identique) dans plusieurs schémas. La manière robuste d'écrire cette clause WHERE considère cette possibilité: where table_catalog = ? and table_schema = ? and table_name = ?;Mais cette vue information_schema ne considère pas que le DDL a pu utiliser des domaines .
Mike Sherrill 'Cat Recall'
1
Cela ne vous donnera pas le type de tableau, il doit donc être utilisé avecpg_typeof
Daria
146

Vous pouvez utiliser la fonction pg_typeof () , qui fonctionne également bien pour les valeurs arbitraires.

SELECT pg_typeof("stu_id"), pg_typeof(100) from student_details limit 1;
Nathan Villaescusa
la source
cela renvoie une ligne par enregistrement dans la table. Ne l'exécutez pas si vous avez des millions d'enregistrements
Saarang
3
Cela fonctionne à merveille si vous devez déterminer le type de calcul. par exemple, SELECT pg_typeof( date_part( 'year', now() ) ) AS exprest probablement différent de ce à quoi vous vous attendez.
Leo Orientis
la chose intelligente ici est que cela pg_typeoffonctionne pour les champs provenant de procédures stockées, pour lesquels la table backend, si elle existe même, est inconnue / peu claire. select state, qstart, pg_typeof(qstart) as ty_qstart from listconn(). information_schema n'aiderait pas beaucoup ici.
JL Peyret
40

Essayez cette demande:

SELECT column_name, data_type FROM information_schema.columns WHERE 
table_name = 'YOUR_TABLE' AND column_name = 'YOUR_FIELD';
Romulo Freires
la source
4
table_name = 'YOUR_TABLE' AND column_name = 'YOUR_FIELD';
haitham
38

courir psql -Eet puis\d student_details


la source
simple et utile
horoyoi o
11

Si vous aimez la solution 'Mike Sherrill' mais que vous ne voulez pas utiliser psql, j'ai utilisé cette requête pour obtenir les informations manquantes:

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'

avec résultat:

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

Les vues de schéma d'informations et pg_typeof () renvoient des informations de type incomplètes. Parmi ces réponses, psqldonne les informations de type les plus précises. (Le PO n'a peut-être pas besoin d'informations aussi précises, mais devrait connaître les limites.)

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

Utiliser psqlet \d public.testmontre correctement l'utilisation du type de données test_domain, la longueur des colonnes varchar (n), ainsi que la précision et l'échelle des colonnes numériques (p, s).

sandbox = # \ d public.test
             Tableau "public.test"
 Colonne | Type | Modificateurs
--------- + ----------------------- + -----------
 test_id | test_domain |
 test_vc | caractère variant (15) |
 test_n | numérique (15,3) |
 big_n | bigint |
 ip_addr | inet |

Cette requête sur une vue information_schema ne montre pas du tout l'utilisation de test_domain. Il ne rapporte pas non plus les détails des colonnes varchar (n) et numeric (p, s).

select column_name, data_type 
from information_schema.columns 
where table_catalog = 'sandbox'
  and table_schema = 'public'
  and table_name = 'test';
nom_colonne | Type de données
------------- + -------------------
 test_id | caractère variant
 test_vc | caractère variant
 test_n | numérique
 big_n | bigint
 ip_addr | inet

Vous pourrez peut- être obtenir toutes ces informations en joignant d'autres vues information_schema ou en interrogeant directement les tables système. psql -Epourrait aider avec cela.

La fonction pg_typeof()montre correctement l'utilisation de test_domain, mais ne rapporte pas les détails des colonnes varchar (n) et numeric (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 | caractère variant | numérique | bigint | inet
Mike Sherrill 'Rappel de chat'
la source
4

Extraire le type de données depuis information_schemaest possible, mais pas pratique (nécessite de joindre plusieurs colonnes avec une caseinstruction). Vous pouvez également utiliser une format_typefonction intégrée pour ce faire, mais cela fonctionne sur les identificateurs de type internes qui sont visibles dans pg_attributemais pas dans information_schema. Exemple

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

Basé sur https://gis.stackexchange.com/a/97834 .

Piotr Findeisen
la source
1
Pour la postérité, avec pg10 remplacer b.relfilenodeparb.oid
tswaters