2011年11月6日日曜日

◆SQLServer テーブル定義をCSV出力

複数のDBの中にあるテーブル定義を纏めてCSVに出力したいという要望があり、探せば何処かにありそうな気もしたが、SQLServerを扱う勉強に調度良さそうなので作ってみた。

とりあえず以下のような選択リストを表示してDBを選択させることにした。

image

ソースは以下のとおり。

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070

param(
 
$OutPath=[environment]::GetFolderPath("desktop"),
  $Instance=".\sqlexpress"
)
function Main
{
 
$outDBPath = ""
  $TrueSign = " " * 5 + "○"
  #DB一覧を表示
  . ChoiceDB
 
 
#選択されたDBを抽出
  @($objDBs)[($DBNumbers | %{(--$_)})] |
    %
{
       
. CreateDBFolder $_.name  #DB名でフォルダーを作る
        $_.Tables |
 
       
%
{
           
$tableFullName =      #Table名をそのままファイル名に
              Join-Path $outDBPath ($_.name + ".csv"
)
           
$_.Columns | select name,datatype,
              @{ #Lengthプロパティ
                  name="Length"
                  expression=
{
                   
if($_.datatype.name -match 'char'
){
                     
$_.datatype.
MaximumLength
                    }
                  }
               }
,
              @{ #Nullableプロパティ
                  name="Nullable"
                  expression={if($_.Nullable){$TrueSign
}}
               }
,
              @{ #PrimaryKeyプロパティ
                  name="PrimaryKey"
                  expression={if($_.InPrimaryKey){$TrueSign
}}
               } 
| . OutCSV
         }
     }             
}


function ChoiceDB
()
{
 
[void][Reflection.Assembly]::
LoadWithPartialName(
                                     
"Microsoft.SqlServer.Smo"
) 
 
$server =
 
 
New-Object Microsoft.SqlServer.Management.Smo.Server($Instance
)
 
$server.ConnectionContext.LoginSecure = $true
 
 
$i=0
  Write-Host "以下の中から対象のDBを選択して下さい。" -NoNewline
  Write-Host "(複数指定時はカンマ区切り)"  -ForegroundColor Yellow
  $server.Databases |
 
   
?{-not $_.IsSystemObject} | tee -Variable objDBs |
 
   
fw {(++$script:i).ToString() + ":" + $_.
name} 
 
[int[]]$DBNumbers = (Read-Host "DB Number " ) -split ","
  if(-not $DBNumbers){exit
}
}


function CreateDBFolder($dbname
)
{
 
$outDBPath = Join-Path $OutPath $dbname
  if(-not (Test-Path $outDBPath))  {mkdir $outDBPath | Out-Null
}
}


function OutCSV
()
{
 
$input |
 
   
Export-Csv -Path $tableFullName -NoType -Encoding "Default"
 
}


. 
Main
Write-host
 "Complete" -ForegroundColor

選択されたDB名でフォルダーを作り、そこにテーブルと同じ名前でCSVファイルを出力している。

SQLServerへのアクセスにはSMOを使った。
認証はとりあえずWindows認証を指定している。

出力したCSVをEXCELで開くとこんな感じ。

image

EXCELに直接出したいというニーズもありそうだが、今回はサーバーで実行するのを想定しているため、EXCELがインストールされていなくても大丈夫なようにCSVで良しとした。
一応、CSV出力の箇所はOutCSVというFunctionにしたので、ここをOutExcelとかにして置き換えればすぐに変更もできるのではないだろうか。

エラー処理を組み込んでいないので指定を間違えないようにする(^^;

0 件のコメント:

コメントを投稿