Seleccione el tipo de datos del campo en postgres


165

¿Cómo obtengo el tipo de datos de un campo específico de la tabla en postgres? Por ejemplo, tengo la siguiente tabla, student_details (stu_id entero, stu_name varchar (30), join_date timestamp);

Al usar el nombre del campo / o de cualquier otra forma, necesito obtener el tipo de datos del campo específico. Hay alguna posibilidad ?


1
También preguntó y respondió stackoverflow.com/q/20194806/65458
Piotr Findeisen el

Respuestas:


173

Puede obtener tipos de datos del esquema de información (8.4 documentos a los que se hace referencia aquí, pero esta no es una característica nueva):

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

¡Tan simple y agradable! Ahora puedo reemplazar la consulta actual que encontré que tiene 310 caracteres (sin el nombre de la tabla), 4 uniones a la tabla, no es consciente del esquema, es costosa y eso da 'int4' y otros como tipos en lugar de enteros. ¡Gracias!
Algunos

2
PostgreSQL le permite tener el mismo nombre de tabla (incluso una tabla idéntica) en múltiples esquemas. La forma sólida de escribir esa cláusula WHERE considera esa posibilidad: where table_catalog = ? and table_schema = ? and table_name = ?;Pero esta vista de información_esquema no considera que el DDL podría haber usado dominios .
Mike Sherrill 'Cat Recall'

1
Esto no le dará el tipo de matriz, por lo que debe usarse junto conpg_typeof
Daria

146

Puede usar la función pg_typeof () , que también funciona bien para valores arbitrarios.

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

Esto devuelve una fila por registro en la tabla. No lo ejecute si tiene millones de registros
Saarang

3
Esto funciona de maravilla si necesita determinar el tipo de cálculo. por ejemplo, SELECT pg_typeof( date_part( 'year', now() ) ) AS exprprobablemente sea diferente de lo que esperarías.
Leo Orientis

Lo inteligente aquí es que pg_typeoffunciona para los campos que salen de los procedimientos almacenados, para los cuales la tabla de fondo, si existe, es desconocida / no está clara. select state, qstart, pg_typeof(qstart) as ty_qstart from listconn(). información_esquema no ayudaría mucho aquí.
JL Peyret

40

Prueba esta solicitud:

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

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

38

correr psql -Ey luego\d student_details


simple y útil
horoyoi o

11

Si te gusta la solución 'Mike Sherrill' pero no quieres usar psql, utilicé esta consulta para obtener la información que falta:

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 resultado:

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

8

Las vistas de esquema de información y pg_typeof () devuelven información de tipo incompleta. De estas respuestas, psqlproporciona la información de tipo más precisa. (El OP podría no necesitar información tan precisa, pero debería conocer las limitaciones).

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

El uso psqly \d public.testmuestra correctamente el uso del tipo de datos test_domain, la longitud de las columnas varchar (n) y la precisión y escala de las columnas numéricas (p, s).

sandbox = # \ d public.test
             Tabla "public.test"
 Columna | Tipo | Modificadores
--------- + ----------------------- + -----------
 test_id | test_domain |
 test_vc | carácter variable (15) |
 prueba_n | numérico (15,3) |
 big_n | bigint |
 ip_addr | inet |

Esta consulta contra una vista de información_esquema no muestra el uso de test_domain. Tampoco informa los detalles de las columnas varchar (n) y numéricas (p, s).

select column_name, data_type 
from information_schema.columns 
where table_catalog = 'sandbox'
  and table_schema = 'public'
  and table_name = 'test';
nombre_columna | tipo de datos
------------- + -------------------
 test_id | carácter variable
 test_vc | carácter variable
 prueba_n | numérico
 big_n | Empezando
 ip_addr | inet

Es posible que pueda obtener toda esa información uniéndose a otras vistas de información_esquema o consultando directamente las tablas del sistema. psql -Epodría ayudar con eso.

La función pg_typeof()muestra correctamente el uso de test_domain, pero no informa los detalles de las columnas varchar (n) y numéricas (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 | prueba_n | big_n | ip_addr
------------- + ------------------- + --------- + ------ - + ---------
 test_domain | carácter variable | numérico | bigint | inet

4

information_schemaEs posible extraer el tipo de datos , pero no es conveniente (requiere unir varias columnas con una casedeclaración). Alternativamente, uno puede usar la format_typefunción incorporada para hacer eso, pero funciona en identificadores de tipo internos que están visibles pg_attributepero no en information_schema. Ejemplo

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

Basado en https://gis.stackexchange.com/a/97834 .


1
Para la posteridad, con pg10 reemplazar b.relfilenodeconb.oid
tswaters
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.