なか日記

一度きりの人生、楽しく生きよう。

Oracleのテーブル定義をファイル出力する(簡易版)

2つのスキーマに作成されているテーブルの定義が異なってないか確認したかったので、descコマンドの結果をファイル出力するスクリプトを作成してみました。

単にOracleとPowerShellのパイプラインとヒアドキュメントがステキ! - なか日記で書いた事を使ってみたかっただけという話もありますが・・・

スキーマ毎にフォルダを作成するので、そのフォルダごと比較してあげれば片方にしか存在しないテーブルや存在するけど定義が異なるテーブルを確認できるという感じです。

ちなみに、ODP.Net及び、SQL*Plusが使える(OracleClientがインストールされている)環境じゃないと動きません。

# Oracleの定義(descの結果)をテーブル単位にファイル出力する
# 出力先:カレントディレクトリに「入力された[ユーザID]」でディレクトリを作成して出力する

[System.Reflection.Assembly]::LoadWithPartialName("Oracle.DataAccess") | Out-Null

function GetUserTables {
param($uid, $pass, $svc)
    $connstr = "User ID=$uid;Password=$pass;Data Source=$svc"
    $conn = New-Object Oracle.DataAccess.Client.OracleConnection($connstr)

    $conn.Open()
    $cmd = New-Object Oracle.DataAccess.Client.OracleCommand

    $cmd.Connection = $conn
    $cmd.CommandText = "select TABLE_NAME from USER_TABLES order by TABLE_NAME"

    $reader = $cmd.ExecuteReader()
    while ($reader.Read())
    {
        $reader[0].ToString()
    }
}

function OutputDefiniton {
param($uid, $pass, $svc, $talbes)

    if (!(Test-Path $uid)) { mkdir $uid | Out-Null }
    $talbes | %{
        $tableName=$_
        "spool $uid\${tableName}.def"
        "desc $tableName"
        "spool off"
    } | sqlplus -S $uid/$pass@$svc | Out-Null
}

$uid = Read-Host "UserID:"
$pass = Read-Host "Password:"
$svc = Read-Host "ServiceName:"

$talbes = GetUserTables $uid $pass $svc

OutputDefiniton $uid $pass $svc $talbes

USER_TABLESを参照してテーブルの一覧を取得し、テーブル単位にdescコマンドの結果をファイルに出力しています。ファイル出力はSQL*Plusのspool機能に丸投げ。

SQL*Plus使わずに、USER_TAB_COLUMNSを参照して各テーブルの項目定義を出力するという方法もありますが、目的を満たせる一番楽な方法で片付けちゃいました。

それにしても、PowerShellのシンタックスハイライトはまだですかね?