Виберіть тип даних поля в постгресах


165

Як я можу отримати тип даних певного поля з таблиці в постгресах? Наприклад, у мене є наступна таблиця, students_details (stu_id integer, stu_name varchar (30), joined_date timetamp);

Використовуючи ім’я поля / чи будь-яким іншим способом, мені потрібно отримати тип даних конкретного поля. Чи є можливість?


1
Також запитували та відповіли stackoverflow.com/q/20194806/65458
Piotr Findeisen

Відповіді:


173

Ви можете отримати типи даних за допомогою data_schema (тут посилаються 8,4 документа, але це не нова функція):

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

Так просто і приємно! Тепер я можу замінити поточний запит, який я виявив, що це 310 символів (без імені таблиці), 4 об'єднання таблиці, не відомі схеми, дорогі, що дає "int4" та інші як типи замість цілих. Дякую!
десь

2
PostgreSQL дозволяє мати однакове ім’я таблиці (навіть ідентичну таблицю) у кількох схемах. Надійний спосіб записати, що пункт WHERE враховує таку можливість: where table_catalog = ? and table_schema = ? and table_name = ?;Але цей перегляд information_schema не враховує, що DDL, можливо, використовував домени .
Майк Шеррілл 'Відкликання котів'

1
Це не дасть вам тип масиву, тому його потрібно використовувати разом зpg_typeof
Дар'я,

146

Ви можете використовувати функцію pg_typeof () , яка також добре працює для довільних значень.

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

це повертає рядок на запис у таблиці. Не запускайте його, якщо у вас мільйони записів
Сааранг,

3
Це прекрасно працює, якщо вам потрібно визначити тип розрахунку. наприклад, SELECT pg_typeof( date_part( 'year', now() ) ) AS exprмабуть, відрізняється від того, що ви очікували.
Лев

розумним тут є те, що pg_typeofпрацює для полів, що виходять із збережених процедур, для яких резервна таблиця, якщо вона навіть існує, невідома / незрозуміла. select state, qstart, pg_typeof(qstart) as ty_qstart from listconn(). information_schema тут не дуже допоможе.
Дж. Л. Пейрет

40

Спробуйте цей запит:

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

біжи psql -Eі тоді\d student_details


простий і корисний
horoyoi o

11

Якщо вам подобається рішення "Mike Sherrill", але ви не хочете використовувати psql, я використовував цей запит, щоб отримати інформацію про відсутність:

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'

з результатом:

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

8

Перегляди інформаційної схеми та pg_typeof () повертають неповну інформацію про тип. З цих відповідей psqlдає найбільш точну інформацію про тип. (ОП може не потребувати такої точної інформації, але повинна знати обмеження.)

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

Використовуючи psqlта \d public.testправильно показує використання типу даних test_domain, довжини стовпців varchar (n) та точності та шкали числових (p, s) стовпців.

пісочниця = # \ d public.test
             Таблиця "public.test"
 Стовпець | Тип | Модифікатори
--------- + ----------------------- + -----------
 test_id | test_domain |
 test_vc | характер варіюється (15) |
 test_n | числовий (15,3) |
 big_n | bigint |
 ip_addr | inet |

Цей запит проти перегляду information_schema взагалі не показує використання test_domain. Він також не повідомляє подробиці varchar (n) та числових (p, s) стовпців.

select column_name, data_type 
from information_schema.columns 
where table_catalog = 'sandbox'
  and table_schema = 'public'
  and table_name = 'test';
ім'я стовпця | тип даних
------------- + -------------------
 test_id | характер різний
 test_vc | характер різний
 test_n | числовий
 big_n | bigint
 ip_addr | інет

Ви могли б бути в змозі отримати все цю інформацію шляху приєднання до іншого виду information_schema, або шляхом запиту системних таблиць безпосередньо. psql -Eможе допомогти у цьому.

Функція pg_typeof()коректно показує використання test_domain, але не повідомляє про деталі стовпців varchar (n) та числових (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 | характер, що змінюється | числовий | bigint | інет

4

Витягнення типу даних information_schemaможливе, але не зручно (вимагає з'єднання декількох стовпців із caseзаявою). Для цього можна використовувати format_typeвбудовану функцію, але вона працює на внутрішніх ідентифікаторах типу, які видно в, pg_attributeале не в information_schema. Приклад

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

На основі https://gis.stackexchange.com/a/97834 .


1
Для нащадків з pg10 замініть b.relfilenodeнаb.oid
tswaters
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.