Selecione o tipo de dados do campo no postgres


165

Como obtenho o tipo de dados do campo específico da tabela no postgres? Por exemplo, eu tenho a tabela a seguir, student_details (número inteiro stu_id, stu_name varchar (30), registro de data e hora de join_date);

Neste usando o nome do campo / ou qualquer outra maneira, eu preciso obter o tipo de dados do campo específico. Existe alguma possibilidade?


1
Também perguntei e respondi stackoverflow.com/q/20194806/65458
Piotr Findeisen

Respostas:


173

Você pode obter tipos de dados no information_schema (8.4 documentos mencionados aqui, mas este não é um novo recurso):

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

Tão simples e agradável! Agora posso substituir a consulta atual que encontrei com 310 caracteres (sem o nome da tabela), 4 junções na tabela, sem reconhecimento de esquema, caro e que fornece 'int4' e outros como tipos em vez de inteiro. Obrigado!
algum

2
O PostgreSQL permite que você tenha o mesmo nome de tabela (mesmo uma tabela idêntica) em vários esquemas. A maneira robusta de escrever essa cláusula WHERE considera essa possibilidade: where table_catalog = ? and table_schema = ? and table_name = ?;Mas essa visualização information_schema não considera que o DDL possa ter usado domínios .
Mike Sherrill 'Cat Recall'

1
Isso não fornecerá o tipo de matriz, portanto, ela deve ser usada junto com #pg_typeof
Daria

146

Você pode usar a função pg_typeof () , que também funciona bem para valores arbitrários.

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

isso retorna uma linha por registro na tabela. Não executá-lo se você tem milhões de registros
Saarang

3
Isso funciona perfeitamente se você precisar determinar o tipo de cálculo. por exemplo, SELECT pg_typeof( date_part( 'year', now() ) ) AS exprprovavelmente é diferente do que você esperaria.
Leo Orientis

o mais inteligente aqui é que pg_typeoffunciona para campos que saem de procedimentos armazenados, para os quais a tabela de back-end, se existir, é desconhecida / pouco clara. select state, qstart, pg_typeof(qstart) as ty_qstart from listconn(). information_schema não ajudaria muito aqui.
JL Peyret

40

Tente este pedido:

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';
21717 haitham

38

corra psql -Ee depois\d student_details


simples e útil
horoyoi o

11

Se você gosta da solução 'Mike Sherrill', mas não deseja usar o psql, usei esta consulta para obter as informações ausentes:

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'

com resultado:

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

8

As visualizações do esquema de informações e pg_typeof () retornam informações de tipo incompletas. Dessas respostas, psqlfornece as informações de tipo mais precisas. (O OP pode não precisar de informações tão precisas, mas deve conhecer as limitações.)

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

Usar psqle \d public.testmostrar corretamente o uso do tipo de dados test_domain, o comprimento das colunas varchar (n) e a precisão e a escala das colunas numéricas (p, s).

sandbox = # \ d public.test
             Tabela "public.test"
 Coluna | Tipo | Modificadores
--------- + ----------------------- + -----------
 test_id | test_domain |
 test_vc | caracteres variando (15) |
 test_n | numérico (15,3) |
 big_n | bigint |
 ip_addr | inet |

Esta consulta em uma visualização information_schema não mostra o uso de test_domaintodos. Ele também não informa os detalhes das colunas varchar (n) e 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';
nome_da_coluna | tipo de dados
------------- + -------------------
 test_id | personagem variando
 test_vc | personagem variando
 test_n | numérico
 big_n | bigint
 ip_addr | inet

Você pode obter todas essas informações ingressando em outras visualizações information_schema ou consultando diretamente as tabelas do sistema. psql -Epode ajudar com isso.

A função pg_typeof()mostra corretamente o uso de test_domain, mas não relata os detalhes das colunas varchar (n) e 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 | test_n | big_n | ip_addr
------------- + ------------------- + --------- + ------ - + ---------
 test_domain | caractere variando | numérico | bigint | inet

4

Obter o tipo de dados information_schemaé possível, mas não é conveniente (requer a junção de várias colunas a uma caseinstrução). Como alternativa, pode-se usar format_typea função interna para fazer isso, mas funciona em identificadores de tipo interno que são visíveis, pg_attributemas não dentro information_schema. Exemplo

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

Com base em https://gis.stackexchange.com/a/97834 .


1
Para a posteridade, com PG10 substituir b.relfilenodecomb.oid
tswaters
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.