[powershell]Transact-sqlをパースする

Microsoft.SqlServer.Management.SqlParserを使ってT-SQLをパースする方法です。

#DLLロード
Add-Type -AssemblyName "Microsoft.SqlServer.Management.SqlParser, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"

#スキャナーの準備
$ParseOptions = New-Object Microsoft.SqlServer.Management.SqlParser.Parser.ParseOptions
$ParseOptions.BatchSeparator = 'GO'
$Parser = new-object Microsoft.SqlServer.Management.SqlParser.Parser.Scanner($ParseOptions)

#SQLの読み込み
$Sql = "Select * from table_a inner join table_b on table_a.sid=table_b.sid; go; update t_able set a1='a1';"
$Parser.SetSource($Sql,0)

#パース用変数の初期化
$Token=[Microsoft.SqlServer.Management.SqlParser.Parser.Tokens]::TOKEN_SET
$Start =0
$End = 0
$State =0 
$IsEndOfBatch = $false
$IsMatched = $false
$IsExecAutoParamHelp = $false
$EOF = [Microsoft.SqlServer.Management.SqlParser.Parser.Tokens]::EOF

#EOFまでトークンを順番に取得する
while(($Token = $Parser.GetNext([ref]$State ,[ref]$Start, [ref]$End, [ref]$IsMatched, [ref]$IsExecAutoParamHelp ))-ne $EOF) {
    try{
        ($TokenName =[Microsoft.SqlServer.Management.SqlParser.Parser.Tokens]$Token) | Out-Null
        $str = $Sql.Substring($Start,($end-$Start)+1)
        Write-Host "$TokenName : $str"
    }catch{
        $TokenName = $null
    }    
}

実行結果

TOKEN_SELECT : Select
TOKEN_FROM : from
TOKEN_ID : table_a
TOKEN_INNER : inner
TOKEN_JOIN : join
TOKEN_ID : table_b
TOKEN_ON : on
TOKEN_ID : table_a
TOKEN_ID : sid
TOKEN_ID : table_b
TOKEN_ID : sid
LEX_BATCH_SEPERATOR : go
TOKEN_UPDATE : update
TOKEN_ID : t_able
TOKEN_SET : set
TOKEN_ID : a1
TOKEN_STRING : 'a1'

参照した情報
* Scannerクラス
* Tokenクラス
* Tokens列挙体
* GetNextメソッド
* コードサンプル

コメントを残す