รับชนิดข้อมูลของแต่ละคอลัมน์จากตาราง PostGIS


9

ฉันต้องการรับชนิดข้อมูลคอลัมน์ของคอลัมน์ทั้งหมดในตารางรวมถึงชนิดรูปทรงเรขาคณิต สิ่งที่ฉันอยากรู้คือถ้ามีฟังก์ชั่นหรือ SQL ที่ให้อะไรเช่นนี้:

column_name | data_type
------------+--------------
gid         | integer
descr       | character varying(32)
class       | character varying(10)
area        | double precision
geom        | geometry(Polygon,3763)

จากคำตอบเล็ก ๆ น้อย ๆ เกี่ยวกับstackexchangeและgis.stackexchangeฉันรู้ว่าฉันสามารถรับข้อมูลบางอย่างได้ด้วยแบบสอบถามต่อไปนี้:

SELECT 
    g.column_name,
    g.data_type,
    g.character_maximum_length,
    g.udt_name,
    f.type,
    f.srid
FROM 
     information_schema.columns as g JOIN
     geometry_columns AS f 
         ON (g.table_schema = f.f_table_schema and g.table_name = f.f_table_name )
WHERE
    table_schema = 'my_schema_name' and
    table_name = 'my_table_name'

ผลลัพธ์:

column_name | data_type         | character_maximum_length | udt_name | type    | srid
------------+-------------------+--------------------------+----------+---------+------
gid         | integer           |                          |          |         |
descr       | character varying | 32                       |          |         |
class       | character varying | 10                       |          |         |
area        | double precision  |                          |
geom        | USER-DEFINED      |                          | geometry | Polygon | 3763

แต่มีวิธีการปฏิบัติที่เหมาะสมกว่าในการดึงข้อมูลในรูปแบบที่ฉันต้องการหรือไม่ หรือฉันต้องป้อน "โลก" ของCASE WHENโครงสร้างและการต่อสายอักขระเพื่อรวบรวมแอตทริบิวต์คอลัมน์ทั้งหมดในคอลัมน์เดียวในรูปแบบนั้น

ความกลัวของฉันคือถ้าประเภทข้อมูลที่ไม่คาดหวังทำให้ฉันประหลาดใจโดยต้องการแอตทริบิวต์อื่นจากตาราง information_schema.columns เช่นในตารางตัวอย่างก่อนหน้านี้ฉันไม่ได้ใช้numeric (15,2)ชนิดข้อมูลใด ๆที่จะต้องใช้คุณลักษณะอื่น (numeric_precision และ numeric_scale) เพื่อแยกวิเคราะห์โดย CASE WHEN

คำตอบ:


14

ทฤษฎีนี้ถึงแม้ว่าคุณจะพบว่ามันซับซ้อนมากแน่นอน

  • ทุกตาราง (เลือก * จาก pg_class) มีคอลัมน์
  • ทุกคอลัมน์ (เลือก * จาก pg_attribute) เป็นทางเลือกที่มีหมายเลข "typmod"
  • สำหรับประเภทที่มี typmod (เลือก * จาก pg_type) จะมีฟังก์ชั่น "typmodout"
  • การรันฟังก์ชัน typmod out บนหมายเลข typmod จะส่งคืนสตริงที่สามารถต่อกันกับชื่อประเภทเพื่อจัดทำประเภทของลายเซ็นที่ผู้ใช้งานอ่านได้ซึ่งคุณคุ้นเคย (เลือก 'ตัวเลข' || numerictypmodout (786441)) (เลือกภูมิศาสตร์ (1107460))

แต่เฮ้ psql สร้างสตริงที่คุณต้องการถ้าเราดูว่ามันสร้าง SQL อะไรบางทีคำตอบก็อยู่ตรงนั้น

แน่นอนว่ามีฟังก์ชั่นเวทย์มนตร์ที่ใช้พิมพ์และพิมพ์ดีดและส่งคืนสตริงมายากล

select a.attname, format_type(a.atttypid, a.atttypmod) from pg_attribute a where attname = 'geog';

ด้วยการเข้าร่วม pg_class คุณควรจะได้รับข้อมูลนี้ต่อตาราง


ฉันไม่ได้รับผลลัพธ์ใด ๆwhere attname = 'geog'แต่= 'geom'ใช้งานได้ สิ่งนี้ให้ผลลัพธ์ที่ดีสำหรับค่า MultiPolygon, Point และ MultiPoint แต่ฉันไม่เห็นอะไรเลยสำหรับประเภท Line หรือ MultiLine มีการพิจารณารูปหลายเหลี่ยมเหล่านั้นหรือไม่
mhkeller

7

มันสามารถใช้แบบสอบถาม SQL ง่าย ๆ

SELECT * from information_schema.columns where table_name='mytablename'


1
มันใช้งานได้ดี! และนี่คือเคล็ดลับ: ผลลัพธ์อาจมีความยาวดังนั้นคุณอาจต้องการเปิดใช้งานการแสดงผลแบบขยายบนคอนโซลของคุณ: \pset pagerเพื่อปิดหน้าจากนั้น\xเปิดใช้งานการแสดงผลแบบขยาย
modulitos

7

ด้วยความช่วยเหลือของพอลแรมซีย์ฉันทำอย่างนี้:

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 b.relname = 'my_table_name' and a.attstattarget = -1;

UPDATE

ในขณะเดียวกันฉันได้สร้างฟังก์ชั่นเพื่อขอประเภทข้อมูลคอลัมน์บางประเภท

CREATE OR REPLACE FUNCTION "vsr_get_data_type"(_t regclass, _c text)
  RETURNS text AS
$body$
DECLARE
    _schema text;
    _table text;
    data_type text;
BEGIN
-- Prepare names to use in index and trigger names
IF _t::text LIKE '%.%' THEN
    _schema := regexp_replace (split_part(_t::text, '.', 1),'"','','g');
    _table := regexp_replace (split_part(_t::text, '.', 2),'"','','g');
    ELSE
        _schema := 'public';
        _table := regexp_replace(_t::text,'"','','g');
    END IF;

    data_type := 
    (
        SELECT format_type(a.atttypid, a.atttypmod)
        FROM pg_attribute a 
        JOIN pg_class b ON (a.attrelid = b.oid)
        JOIN pg_namespace c ON (c.oid = b.relnamespace)
        WHERE
            b.relname = _table AND
            c.nspname = _schema AND
            a.attname = _c
     );

    RETURN data_type;
END
$body$ LANGUAGE plpgsql;

การใช้งานคือ:

SELECT vsr_get_data_type('schema_name.table_name','column_name')

-1

หากคุณต้องการตรวจสอบประเภทรูปทรงเรขาคณิตคุณสามารถตรวจสอบ 'udt_name' ใน 'INFORMATION_SCHEMA.COLUMNS' และใช้มัน!:

select column_name,udt_name, data_type, character_maximum_length from INFORMATION_SCHEMA.COLUMNS where table_name =g

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