3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

簡単なテーブル定義を出力するSQL(postgresql版)

Last updated at Posted at 2019-03-08

テーブル定義出力するSQL

SELECT
    sut.relname as tablename,
    pd.description as table_comment,
    att.attnum AS num,
    att.attname AS columnname,
    com.description AS column_comment,
    typ.typname AS COL_TYPE,
    CASE typ.typname WHEN 'varchar' THEN att.atttypmod - 4 WHEN 'bpchar' THEN
    att.atttypmod - 4 WHEN 'numeric' THEN att.atttypmod / 65536 WHEN 'date'
    THEN att.attlen WHEN 'timestamp' THEN att.attlen END AS COL_LENGTH,
    CASE att.attnotnull WHEN 't' THEN 'NOT NULL' WHEN 'f' THEN 'NULL' END AS
    NOTNULL,
    def.adsrc as default
FROM 
    (((pg_attribute att
    -- pg_descriptionと1回目のLEFT JOIN。各カラムに対応するコメント。
     LEFT JOIN pg_description com ON att.attnum = com.objsubid AND att.attrelid = com.objoid)
    -- pg_attrdef
     LEFT JOIN pg_attrdef def ON att.attrelid= def.adrelid AND att.attnum = def.adnum))
    -- pg_descriptionと2回目のLEFT JOIN。こちらはテーブル用コメント。
     LEFT JOIN pg_description pd on att.attrelid = pd.objoid AND pd.objsubid = 0 ,
    --ユーザーが定義したテーブル
     pg_stat_user_tables sut,
    --pg_type
     pg_type typ
WHERE
    att.attrelid = sut.relid AND 
    att.atttypid = typ.oid AND
    att.attnum > 0 AND
    sut.relname IN (
    SELECT
        c.relname
    FROM
        pg_namespace AS n JOIN pg_class AS c ON (n.oid = c.relnamespace)
    WHERE
        c.relkind = 'r' AND 
        c.relname not like 'pg_%' AND 
        c.relname not like 'sql_%'
        --必要に応じて条件を追記
    )
ORDER BY sut.relname, att.attnum

ポイント

システムカタログを見よう

システムカタログにだいたいのことが書いてあるので、利用バージョンのシステムカタログを読もう。
9.6版のドキュメントは下記。
https://www.postgresql.jp/document/9.6/html/catalogs.html

システムカタログもただのテーブルなので、必要な情報が取れるように結合などしてあげればよい。

oid(オブジェクト識別子)

システムカタログもただのテーブルだが、結合するときに「oid」という特殊な属性を使うので、この点だけ注意。

また、oid型の列は、reg****** でキャスト可能。
オブジェクト識別子の型の一欄は、下記URL参照。
https://www.postgresql.jp/document/9.6/html/datatype-oid.html

どのoidがどのreg*****型にキャスト可能なのかは、上の表とシステムカタログのドキュメントを見て都度判断。
(読めばだいたい分かる)

キャストすると何が起こるのかは、以下のようなSQLを叩いてみれば大体わかると思う。

SELECT 
 relnamespace,
 relnamespace::regnamespace as hoge,
 reltype,
 reltype::regtype as piyo,
 relowner,
 relowner::regrole as moge
FROM 
 pg_class

また、where句の条件などに利用することも可能。

SELECT 
 *
FROM 
 pg_class 
WHERE 
 relnamespace = 'public'::regnamespace 

ただ、以下のSQLはエラーになる。
(なんで駄目なのかは追いかけなかった)

SELECT 
 *
FROM 
 pg_class 
WHERE 
 relnamespace::regnamespace = 'public'

デフォルト値

https://www.postgresql.jp/document/9.6/html/catalog-pg-attrdef.html
に記載されている通り、pg_get_exprを使ったadbinフィールドの逆コンパイルをしてる。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?