Hiển thị các loại do người dùng xác định và các chi tiết của chúng


12

Tôi đã tạo một vài UDT mới trong PostgreSQL. Tuy nhiên, bây giờ tôi có hai vấn đề:

  1. Làm thế nào để xem UDT nào đã được xác định?
  2. Làm thế nào để xem các cột được xác định trong các UDT này?

Thật không may, tôi không thể tìm thấy bất cứ điều gì trong tài liệu PostgreSQL.

Câu trả lời:


17

Điều này có giúp bạn bắt đầu không?

SELECT n.nspname AS schema,
        pg_catalog.format_type ( t.oid, NULL ) AS name,
        t.typname AS internal_name,
        CASE
            WHEN t.typrelid != 0
            THEN CAST ( 'tuple' AS pg_catalog.text )
            WHEN t.typlen < 0
            THEN CAST ( 'var' AS pg_catalog.text )
            ELSE CAST ( t.typlen AS pg_catalog.text )
        END AS size,
        pg_catalog.array_to_string (
            ARRAY( SELECT e.enumlabel
                    FROM pg_catalog.pg_enum e
                    WHERE e.enumtypid = t.oid
                    ORDER BY e.oid ), E'\n'
            ) AS elements,
        pg_catalog.obj_description ( t.oid, 'pg_type' ) AS description
    FROM pg_catalog.pg_type t
    LEFT JOIN pg_catalog.pg_namespace n
        ON n.oid = t.typnamespace
    WHERE ( t.typrelid = 0
            OR ( SELECT c.relkind = 'c'
                    FROM pg_catalog.pg_class c
                    WHERE c.oid = t.typrelid
                )
        )
        AND NOT EXISTS
            ( SELECT 1
                FROM pg_catalog.pg_type el
                WHERE el.oid = t.typelem
                    AND el.typarray = t.oid
            )
        AND n.nspname <> 'pg_catalog'
        AND n.nspname <> 'information_schema'
        AND pg_catalog.pg_type_is_visible ( t.oid )
    ORDER BY 1, 2;

Trong psql, bạn có thể \set ECHO_HIDDEN ontạo psql hiển thị cho bạn các truy vấn được sử dụng để tạo đầu ra của các \d...lệnh. Tôi đã thấy các truy vấn này rất hữu ích như một điểm khởi đầu khi đào siêu dữ liệu ra khỏi cơ sở dữ liệu.

Cập nhật: 2019-12-16

Đối với các loại hỗn hợp, siêu dữ liệu cột có thể được xác định bằng cách sử dụng một số thứ như sau:

WITH types AS (
    SELECT n.nspname,
            pg_catalog.format_type ( t.oid, NULL ) AS obj_name,
            CASE
                WHEN t.typrelid != 0 THEN CAST ( 'tuple' AS pg_catalog.text )
                WHEN t.typlen < 0 THEN CAST ( 'var' AS pg_catalog.text )
                ELSE CAST ( t.typlen AS pg_catalog.text )
                END AS obj_type,
            coalesce ( pg_catalog.obj_description ( t.oid, 'pg_type' ), '' ) AS description
        FROM pg_catalog.pg_type t
        JOIN pg_catalog.pg_namespace n
            ON n.oid = t.typnamespace
        WHERE ( t.typrelid = 0
                OR ( SELECT c.relkind = 'c'
                        FROM pg_catalog.pg_class c
                        WHERE c.oid = t.typrelid ) )
            AND NOT EXISTS (
                    SELECT 1
                        FROM pg_catalog.pg_type el
                        WHERE el.oid = t.typelem
                        AND el.typarray = t.oid )
            AND n.nspname <> 'pg_catalog'
            AND n.nspname <> 'information_schema'
            AND n.nspname !~ '^pg_toast'
),
cols AS (
    SELECT n.nspname::text AS schema_name,
            pg_catalog.format_type ( t.oid, NULL ) AS obj_name,
            a.attname::text AS column_name,
            pg_catalog.format_type ( a.atttypid, a.atttypmod ) AS data_type,
            a.attnotnull AS is_required,
            a.attnum AS ordinal_position,
            pg_catalog.col_description ( a.attrelid, a.attnum ) AS description
        FROM pg_catalog.pg_attribute a
        JOIN pg_catalog.pg_type t
            ON a.attrelid = t.typrelid
        JOIN pg_catalog.pg_namespace n
            ON ( n.oid = t.typnamespace )
        JOIN types
            ON ( types.nspname = n.nspname
                AND types.obj_name = pg_catalog.format_type ( t.oid, NULL ) )
        WHERE a.attnum > 0
            AND NOT a.attisdropped
)
SELECT cols.schema_name,
        cols.obj_name,
        cols.column_name,
        cols.data_type,
        cols.ordinal_position,
        cols.is_required,
        coalesce ( cols.description, '' ) AS description
    FROM cols
    ORDER BY cols.schema_name,
            cols.obj_name,
            cols.ordinal_position ;

3
Mẹo này với ECHO_HIDDEN là vô giá.
dezso

1
@dezso: Bạn nhận được cùng psql -E.
Erwin Brandstetter

Cảm ơn rất nhiều cho mã và các giải thích. Chỉ có một điều: ý của bạn là gì bởi các lệnh của ứng dụng?
hải quân

1
\?trong psql hoặc đọc hướng dẫn ở đây để có được một danh sách các meta-lệnh cộng với lời giải thích. \d(& bạn bè) mô tả các đối tượng của cơ sở dữ liệu. Trong nội bộ, hầu hết các lệnh meta được thực thi dưới dạng SQL đối với danh mục hệ thống, cũng có thể được hiển thị với các tùy chọn được đề cập.
Erwin Brandstetter

1
Đẹp, nhưng nó chỉ hiển thị một dòng cho mỗi loại, giống như \ dT + trong psql. Còn thông tin về cách tạo loại, giống như pgAdmin hiển thị nó (xem câu trả lời tiếp theo), nhưng không sử dụng pgAdmin?
Holger Jakobs

13

Bạn có thể sử dụng pgAdmin GUI tiêu chuẩn :

các loại trong pgAdmin

Đảm bảo các loại được bật trong trình duyệt đối tượng ( Tùy chọn - Trình duyệt - Hiển thị )

Ở bên trái, bạn thấy các loại do người dùng định nghĩa trong lược đồ đã chọn (câu hỏi 1. ).

Bên SQL panephải có tập lệnh SQL được thiết kế ngược cho loại đã chọn (câu hỏi 2. ).
Thêm chi tiết trong khung ở trên, như Dependentsvv


Ngoài ra, sử dụng bảng điều khiển tương tác tiêu chuẩn psql :

  1. \dT để có được một danh sách các loại do người dùng định nghĩa.
  2. \d type_name để có được danh sách định nghĩa cột cho loại đã cho.

Hướng dẫn sử dụng:

\d[S+] [ pattern ]

Đối với mỗi mối quan hệ (bảng, dạng xem, dạng xem cụ thể, chỉ mục, chuỗi hoặc bảng ngoại) hoặc loại hỗn hợp khớp với mẫu , hiển thị tất cả các cột, loại của chúng, [...]

Nhấn mạnh đậm của tôi. Lệnh này cũng hoạt động cho các kiểu hỗn hợp vì ít nhất là Postgres 9.1.

Và:

\dT[S+] [ pattern ]

Liệt kê các loại dữ liệu. Nếu mẫu được chỉ định, chỉ các loại có tên khớp với mẫu được liệt kê. Nếu +được gắn vào tên lệnh, mỗi loại được liệt kê với tên và kích thước bên trong của nó, các giá trị được phép của nó nếu đó là một enumloại và các quyền liên quan của nó. Theo mặc định, chỉ các đối tượng do người dùng tạo được hiển thị; cung cấp một mẫu hoặc công cụ Ssửa đổi để bao gồm các đối tượng hệ thống.


1
Làm thế nào để có được thông tin này mà không cần sử dụng pgAdmin?
Holger Jakobs

1
@HolgerJakobs: Tôi đã thêm một giải pháp thay thế với psql ở trên.
Erwin Brandstetter

1
\ dT đưa ra danh sách các loại, \ dT type_name không cung cấp cho các cột, \ d type_name hiển thị "không tìm thấy bất kỳ mối quan hệ nào có tên" ... ". Nếu loại đó có do một bảng cùng tên, thì đó là hoạt động, nhưng một loại được tạo bởi "CREATE TYPE" không hiển thị các cột của nó.
Holger Jakobs

@HolgerJakobs: Tôi biết điều này hoạt động như quảng cáo, và tôi đã thử nghiệm trước khi đăng. Đó là, trong Postgres thời hiện đại ( chính xác là psql ). Bạn phải sử dụng một phiên bản lỗi thời của psql. Xem các bit được thêm ở trên.
Erwin Brandstetter

3
Tôi đã nhận được thông báo tương tự, nhưng \ dT + type_name đã hoạt động. (phiên bản 9.5)
Spike

1

Hãy thử thực thi mã này:

SELECT
    pg_type.typname, 
     pg_enum.enumlabel
FROM
    pg_type 
JOIN
    pg_enum ON pg_enum.enumtypid = pg_type.oid;

1
Giải thích thêm thường được coi là thích hợp cho lý do tại sao nên sử dụng mã.
James Jenkins

Tôi không có kết quả từ truy vấn này. Không chắc dữ liệu được cho là trông như thế nào.
jDub9

1

Đây là một thay thế rất đơn giản , nhưng đủ cho các trường hợp sử dụng đơn giản. Khi loại của cột là UDT, chúng tôi sử dụng udt_namecột từ information_schema.columnsbảng.

select column_name, case 
        when (data_type = 'USER-DEFINED') then udt_name 
        else data_type 
    end as data_type
from information_schema.columns 
where table_schema = 'altimetria' and table_name = 'cnivel';

Kết quả ( geometrylà một UDT):

 column_name  |    data_type     
--------------+------------------
 ogc_fid      | integer
 wkb_geometry | geometry
 id_cnivel    | bigint
 cod_cart     | bigint
 cod_fam      | bigint
 cod_sub      | integer
 z            | double precision
 shape_len    | double precision
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.