เลือกประเภทข้อมูลของฟิลด์เป็น postgres


165

ฉันจะรับประเภทข้อมูลของฟิลด์เฉพาะจากตารางเป็น postgres ได้อย่างไร ตัวอย่างเช่นฉันมีตารางต่อไปนี้ student_details (จำนวนเต็ม stu_id, stu_name varchar (30), tim_damp join_date);

ในการนี้ใช้ชื่อฟิลด์ / หรือวิธีอื่นฉันต้องได้รับประเภทข้อมูลของฟิลด์เฉพาะ มีความเป็นไปได้ไหม?


1
ยังถามและตอบstackoverflow.com/q/20194806/65458
Piotr Findeisen

คำตอบ:


173

คุณจะได้รับประเภทข้อมูลจากinformation_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 อาจต้องใช้โดเมน
Mike Catrill 'Cat Recall'

1
สิ่งนี้จะไม่ให้ประเภทอาเรย์ของคุณดังนั้นจึงต้องใช้พร้อมกับpg_typeof
Daria

146

คุณสามารถใช้ฟังก์ชัน pg_typeof ()ซึ่งทำงานได้ดีสำหรับค่าที่กำหนดเอง

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

สิ่งนี้จะส่งคืนแถวต่อระเบียนในตาราง อย่าเรียกใช้งานถ้าคุณมีบันทึกนับล้าน
Saarang

3
มันจะทำงานได้อย่างสวยงามหากคุณต้องการทราบชนิดของการคำนวณ เช่นSELECT pg_typeof( date_part( 'year', now() ) ) AS exprอาจแตกต่างจากที่คุณคาดหวัง
Leo Orientis

สิ่งที่ฉลาดนี่คือการpg_typeofทำงานสำหรับเขตข้อมูลที่ออกมาจากขั้นตอนการจัดเก็บซึ่งตารางแบ็กเอนด์ถ้ามันยังมีอยู่ไม่เป็นที่รู้จัก / ไม่ชัดเจน select state, qstart, pg_typeof(qstart) as ty_qstart from listconn(). information_schema คงไม่ช่วยอะไรมากที่นี่
JL Peyret

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

มุมมอง schema ข้อมูลและ pg_typeof () ส่งคืนข้อมูลประเภทที่ไม่สมบูรณ์ จากคำตอบเหล่านี้psqlให้ข้อมูลประเภทที่แม่นยำที่สุด (OP อาจไม่ต้องการข้อมูลที่แม่นยำ แต่ควรรู้ข้อ จำกัด )

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)

sandbox = # \ d public.test
             ตาราง "public.test"
 คอลัมน์ | ประเภท | การปรับเปลี่ยน
--------- + ----------------------- + -----------
 test_id | test_domain |
 test_vc | ตัวละครแตกต่างกัน (15) |
 test_n | ตัวเลข (15,3) |
 big_n | bigint |
 ip_addr | inet |

แบบสอบถามนี้เทียบกับมุมมอง data_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';
column_name | ประเภทข้อมูล
------------- + -------------------
 test_id | ตัวละครแตกต่างกันไป
 test_vc | ตัวละครแตกต่างกันไป
 test_n | เป็นตัวเลข
 big_n | bigint
 ip_addr | inet

คุณอาจได้รับข้อมูลทั้งหมดโดยเข้าร่วมมุมมอง data_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 | inet

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.