前提
- 対象
MicrosoftのTSQL(Transact-SQL) - 環境
Microsoft Windows - ツール
- SQL構文解析プログラム
- TSQLScriptDomParser
https://github.com/GCer-Hidenori/TSQLScriptDomParser - ANTSQLParser
https://github.com/GCer-Hidenori/ANTSQLParser
- TSQLScriptDomParser
- XSLT変換
- SAXON: The XSLT and XQuery Processor
http://saxon.sourceforge.net/
- SAXON: The XSLT and XQuery Processor
SELECT文からのテーブル名の取得
TSQLScriptDomParser
fromのテーブル名の一覧を取得
- 実行例
sqlparser -o xml -i -s "select * from db1.schema1.tab1" > out.xml
query -s:out.xml -qs://node[@class='FromClause']/children[@type='TableReferences']/node[@class='NamedTableReference']/children[@type='SchemaObject']/node[@class='SchemaObjectName']/children[@type='BaseIdentifier']/node !indent=true
- 出力例
<?xml version="1.0" encoding="UTF-8"?>
<node token="tab1"
class="Identifier"
value="tab1"
QuoteType="NotQuoted"/>
- 解釈
テーブルの数だけnode要素が出力される。
node要素のvalue属性がテーブル名。
DB名/スキーマ名も取得する
- 実行例
sqlparser -o xml -i -s "select * from db1.schema1.tab1" > out.xml
query -s:out.xml -qs://node[@class='FromClause']/children[@type='TableReferences']/node[@class='NamedTableReference']/children[@type='SchemaObject']/node[@class='SchemaObjectName'] !indent=yes
- 出力例
<?xml version="1.0" encoding="UTF-8"?>
<node token="db1.schema1.tab1" class="SchemaObjectName" value="">
<children type="DatabaseIdentifier">
<node token="db1"
class="Identifier"
value="db1"
QuoteType="NotQuoted"/>
</children>
<children type="SchemaIdentifier">
<node token="schema1"
class="Identifier"
value="schema1"
QuoteType="NotQuoted"/>
</children>
<children type="BaseIdentifier">
<node token="tab1"
class="Identifier"
value="tab1"
QuoteType="NotQuoted"/>
</children>
<children type="Identifiers">
<node token="db1"
class="Identifier"
value="db1"
QuoteType="NotQuoted"/>
<node token="schema1"
class="Identifier"
value="schema1"
QuoteType="NotQuoted"/>
<node token="tab1"
class="Identifier"
value="tab1"
QuoteType="NotQuoted"/>
</children>
</node>
- 解釈
項目 | 値 |
---|---|
サーバ名 | /node/children[@type='ServerIdentifier']/node のvalue属性 |
データベース名 | /node/children[@type='DatabaseIdentifier']/node のvalue属性 |
スキーマ名 | /node/children[@type='SchemaIdentifier']/node のvalue属性 |
テーブル名 | /node/children[@type='BaseIdentifier']/node のvalue属性 |
joinのテーブル名の一覧を取得
- 実行例
sqlparser -o xml -i -s "select * from db1.schema1.tab1 join db2.schema2.tab2 on tab1.id=tab2.id" > out.xml
query -s:out.xml "-qs://node[@class='QualifiedJoin']/children[@type='FirstTableReference' or @type='SecondTableReference']/node[@class='NamedTableReference']/children[@type='SchemaObject']/node[@class='SchemaObjectName']" !indent=true
- 出力例
<?xml version="1.0" encoding="UTF-8"?>
<node token="db1.schema1.tab1" class="SchemaObjectName" value="">
<children type="DatabaseIdentifier">
<node token="db1"
class="Identifier"
value="db1"
QuoteType="NotQuoted"/>
</children>
<children type="SchemaIdentifier">
<node token="schema1"
class="Identifier"
value="schema1"
QuoteType="NotQuoted"/>
</children>
<children type="BaseIdentifier">
<node token="tab1"
class="Identifier"
value="tab1"
QuoteType="NotQuoted"/>
</children>
<children type="Identifiers">
<node token="db1"
class="Identifier"
value="db1"
QuoteType="NotQuoted"/>
<node token="schema1"
class="Identifier"
value="schema1"
QuoteType="NotQuoted"/>
<node token="tab1"
class="Identifier"
value="tab1"
QuoteType="NotQuoted"/>
</children>
</node>
<node token="db2.schema2.tab2" class="SchemaObjectName" value="">
<children type="DatabaseIdentifier">
<node token="db2"
class="Identifier"
value="db2"
QuoteType="NotQuoted"/>
</children>
<children type="SchemaIdentifier">
<node token="schema2"
class="Identifier"
value="schema2"
QuoteType="NotQuoted"/>
</children>
<children type="BaseIdentifier">
<node token="tab2"
class="Identifier"
value="tab2"
QuoteType="NotQuoted"/>
</children>
<children type="Identifiers">
<node token="db2"
class="Identifier"
value="db2"
QuoteType="NotQuoted"/>
<node token="schema2"
class="Identifier"
value="schema2"
QuoteType="NotQuoted"/>
<node token="tab2"
class="Identifier"
value="tab2"
QuoteType="NotQuoted"/>
</children>
</node>
- 解釈
項目 | 値 |
---|---|
サーバ名 | /node/children[@type='ServerIdentifier']/node のvalue属性 |
データベース名 | /node/children[@type='DatabaseIdentifier']/node のvalue属性 |
スキーマ名 | /node/children[@type='SchemaIdentifier']/node のvalue属性 |
テーブル名 | /node/children[@type='BaseIdentifier']/node のvalue属性 |
副問合せで使われるSELECT文からのテーブル名の取得
同じ実行方法で、同じ方法で解釈。
注意
with句や副問合せでのaliasもテーブル名として扱われる。
ANTSQLParser
from/joinのテーブル名の一覧を取得
- 実行例
sqlparser -o xml -i -s "select * from db1.schema1.tab1" > out.xml
query -s:out.xml -qs://node[@rule='table_source']/node[@rule='table_source_item_joined']/node[@rule='table_source_item']/node[@rule='table_name_with_hint']/node[@rule='schema_object_name']/node[@rule='table_name']/node[@rule='id']/node[@rule='simple_id']/node[@token='ID'] !indent=true
- 出力例
<?xml version="1.0" encoding="UTF-8"?>
<node token="ID" rule="" value="tab1"/>
- 解釈
テーブルの数だけnode要素が出力される。
node要素のvalue属性がテーブル名。
DB名/スキーマ名も取得する
- 実行例
sqlparser -o xml -i -s "select * from db1.schema1.tab1" > out.xml
query -s:out.xml -qs://node[@rule='table_source']/node[@rule='table_source_item_joined']/node[@rule='table_source_item']/node[@rule='table_name_with_hint']/node[@rule='schema_object_name'] !indent=true
- 出力例
<?xml version="1.0" encoding="UTF-8"?>
<node token="" rule="schema_object_name" value="db1.schema1.tab1">
<node token="" rule="database_name" value="db1">
<node token="" rule="id" value="db1">
<node token="" rule="simple_id" value="db1">
<node token="ID" rule="" value="db1"/>
</node>
</node>
</node>
<node token="'.'" rule="" value="."/>
<node token="" rule="schema_name" value="schema1">
<node token="" rule="id" value="schema1">
<node token="" rule="simple_id" value="schema1">
<node token="ID" rule="" value="schema1"/>
</node>
</node>
</node>
<node token="'.'" rule="" value="."/>
<node token="" rule="table_name" value="tab1">
<node token="" rule="id" value="tab1">
<node token="" rule="simple_id" value="tab1">
<node token="ID" rule="" value="tab1"/>
</node>
</node>
</node>
</node>
- 解釈
項目 | 値 |
---|---|
サーバ名 | /node/node[@rule='server_name']//node[@token='ID']のvalue属性 |
データベース名 | /node/node[@rule='database_name']//node[@token='ID']のvalue属性 |
スキーマ名 | /node/node[@rule='schema_name']//node[@token='ID']のvalue属性 |
テーブル名 | /node/node[@rule='table_name']//node[@token='ID']のvalue属性 |
副問合せで使われるSELECT文からのテーブル名の取得
同じ実行方法で、同じ方法で解釈。
注意
with句や副問合せでのaliasもテーブル名として扱われる。
ツールの簡単な説明
-
TSQLScriptDomParser
MicrosoftのMicrosoft SQL Server 2016 Service Pack 2 Feature Packに入っているMicrosoft SQL Server 2016 SP2 Transact-SQL ScriptDomをベースに作成。
SQL Server 2019等の最新の構文には対応していない。
構文の仕様はMicrosoftのライブラリのリファレンスを参照。 -
ANTSQLParser
antlr4のTSQLの構文のサンプルをベースに作成。
SQL Server 2019等の最新の構文には、作者が対応させたもの以外は対応していない。
ベースから引き継いだ細かな不具合が多くある。
ただし文法ファイル( TSqlParser.g4 TSqlLexer.g4 )が有るので仕様が明瞭。