@Chrisの回答に基づいて構築されています。
SELECT a.attnum
,a.attname AS name
,format_type(a.atttypid, a.atttypmod) AS typ
,a.attnotnull AS notnull
,coalesce(p.indisprimary, FALSE) AS primary_key
,f.adsrc AS default_val
,d.description AS col_comment
FROM pg_attribute a
LEFT JOIN pg_index p ON p.indrelid = a.attrelid AND a.attnum = ANY(p.indkey)
LEFT JOIN pg_description d ON d.objoid = a.attrelid AND d.objsubid = a.attnum
LEFT JOIN pg_attrdef f ON f.adrelid = a.attrelid AND f.adnum = a.attnum
WHERE a.attnum > 0
AND NOT a.attisdropped
AND a.attrelid = 'schema.tbl'::regclass -- table may be schema-qualified
ORDER BY a.attnum;
しかし:
テーブル名はデータベース内で一意ではないため、システム カタログでも一意ではありません。名前をスキーマ修飾する必要がある場合があります。
条件として使用a.attrelid = 'tbl'::regclass
します。このようにmyschema.mytbl
して、名前として渡し、曖昧さをなくすことができます。この場合、参加する必要はまったくありませんpg_class
。
また、可視性は自動的にチェックされregclass
、必要はありませんpg_table_is_visible()
。
主キーは複数の列にまたがることができます。pg_index
on に参加することでこれを処理しa.attnum = ANY(p.indkey)
ます。は、カタログでのみ使用されるの特殊なケースである
indkey
タイプです。int2vecor
int2[]
psql -E
このクラスの問題に役立ちます。
互換性
このような特殊なクエリは、メジャー バージョンの更新後に壊れる可能性があります。Postgres は、カタログ テーブルが安定していることを保証しません。基本的な要素が変更されることはほとんどありませんが、クエリがより複雑で専門的なものになればなるほど、その可能性は高くなります。代わりに情報スキーマを使用できます。これは標準化されていますが、比較的低速です。