【各DB】指定したテーブルのカラム名、カラムコメント、型名、プライマリーキーなどを一括取得

VBAでカラム情報を一括取得する必要があったので、メモ。
副問い合わせ使いまくりなので、時間あるときにJOINなどに置き換えたい・・。
'データベース名'、'テーブル名'はその該当名に置き換えで！

```postgres:PostgreSQL用カラム名取得SQL
SELECT relname AS table_name         -- テーブル名
     , attname AS field              -- カラム名
     , CASE WHEN attname IN 
     ( SELECT ccu.column_name AS COLUMN_NAME 
         FROM information_schema.table_constraints tc 
            , information_schema.constraint_column_usage ccu 
        WHERE tc.table_catalog = 'データベース名' 
          AND tc.table_name = 'テーブル名' 
          AND tc.constraint_type = 'PRIMARY KEY' 
          AND tc.table_catalog = ccu.table_catalog 
          AND tc.table_schema = ccu.table_schema 
          AND tc.table_name = ccu.table_name 
          AND tc.constraint_name = ccu.constraint_name 
     ) 
            THEN 'PRI' 
            ELSE NULL 
       END AS key                    -- プライマリーキー
     , typname AS Type               -- 型名
     , CASE typname 
            WHEN 'int2' 
            THEN '2' 
            WHEN 'int4' 
            THEN '4' 
            WHEN 'int8' 
            THEN '8' 
            WHEN 'float4' 
            THEN '4' 
            WHEN 'float8' 
            THEN '8' 
            WHEN 'serial4' 
            THEN '4' 
            WHEN 'serial8' 
            THEN '8' 
            WHEN 'timestamp' 
            THEN 14 
            WHEN 'numeric' 
            THEN ( atttypmod - 4 ) / 65536 
            ELSE atttypmod - 4 
       END AS Type_Length            -- 型の長さ
     , CASE attnotnull 
            WHEN 't' 
            THEN 'YES' 
            ELSE 'NO' 
       END AS Null                   -- NOT NULL制約
     , RES.COLUMN_COMMENT AS Comment -- カラムコメント
  FROM 
     ( pg_type 
        INNER JOIN pg_attribute 
           ON pg_type.oid = pg_attribute.atttypid 
        INNER JOIN pg_class 
           ON pg_class.oid = pg_attribute.attrelid 
     ) 
  LEFT JOIN 
     ( SELECT psat.relname AS TABLE_NAME 
            , pa.attname AS COLUMN_NAME 
            , pd.description AS COLUMN_COMMENT 
         FROM pg_stat_all_tables psat 
            , pg_description pd 
            , pg_attribute pa 
        WHERE psat.schemaname = 
            ( SELECT schemaname 
                FROM pg_stat_user_tables 
               WHERE relname = 'テーブル名' 
            ) 
          AND psat.relname = 'テーブル名' 
          AND psat.relid = pd.objoid 
          AND pd.objsubid <> 0 
          AND pd.objoid = pa.attrelid 
          AND pd.objsubid = pa.attnum 
        ORDER BY 
              pd.objsubid 
     ) AS RES 
    ON RES.COLUMN_NAME = pg_attribute.attname 
 WHERE relkind = 'r' 
   AND relname = 'テーブル名' 
   AND attnum > 0 
 ORDER BY 
       attnum;
```

これ系のカラム名情報取得はMySQLが一番簡単だった。
ということでおまけにMySQL用とせっかく作ったのでOracle用も。

```mysql:MySQL用カラム名取得SQL
SHOW FULL COLUMNS FROM テーブル名;
```

MySQLのこのシンプルさよ。

```sql:Oracle用カラム名取得SQL
SELECT T.TABLE_NAME AS table_name -- テーブル名
     , C.COLUMN_ID 
     , C.COLUMN_NAME AS Field     -- カラム名
     , CASE WHEN PK.COLUMN_POSITION IS NOT NULL 
            THEN PK.COLUMN_POSITION 
            ELSE NULL 
       END AS Key                 -- プライマリーキー
     , C.DATA_TYPE AS Type        -- 型名
     , CASE WHEN C.DATA_PRECISION IS NOT NULL 
            THEN '(' || C.DATA_PRECISION || '.' || C.DATA_SCALE || ')' 
            ELSE TO_CHAR(C.DATA_LENGTH) 
       END AS Type_length         -- 型の長さ
     , C.NULLABLE AS Null         -- NOT NULL制約
     , C.DATA_DEFAULT AS DEFAULT  -- デフォルト値
     , TC.COMMENTS AS Comment     -- カラムコメント
  FROM USER_TABLES T 
 INNER JOIN USER_TAB_COMMENTS TC 
    ON 
     ( T.TABLE_NAME = TC.TABLE_NAME 
     ) 
 INNER JOIN USER_TAB_COLUMNS C 
    ON 
     ( T.TABLE_NAME = C.TABLE_NAME 
     ) 
 INNER JOIN USER_COL_COMMENTS CC 
    ON 
     ( T.TABLE_NAME = CC.TABLE_NAME 
          AND C.COLUMN_NAME = CC.COLUMN_NAME 
     ) 
  LEFT JOIN 
     ( SELECT IND.INDEX_NAME 
            , CONST.TABLE_NAME 
            , IND.COLUMN_NAME 
            , IND.COLUMN_POSITION 
         FROM USER_IND_COLUMNS IND 
        INNER JOIN USER_CONSTRAINTS CONST 
           ON 
            ( IND.INDEX_NAME = CONST.CONSTRAINT_NAME 
                 AND CONSTRAINT_TYPE = 'P' 
            ) 
     ) PK 
    ON 
     ( T.TABLE_NAME = PK.TABLE_NAME 
          AND C.COLUMN_NAME = PK.COLUMN_NAME 
     ) 
 WHERE T.TABLE_NAME LIKE 'テーブル名' 
 ORDER BY 
       T.TABLE_NAME 
     , C.COLUMN_ID;
```

対してOracleは結構重たいです。


参考元：
PostgreSQLにてテーブルやカラムの各種情報を取得するSQL (テーブル一覧, カラム一覧, プライマリーキー情報取得, テーブルのコメントを取得, カラムのコメントを取得)
http://devlights.hatenablog.com/entry/20080226/p1