Edited at

TransactSql.ScriptDomを使ってTransact-SQLのコーディング規約をチェックする

More than 5 years have passed since last update.


JOINをしているのにテーブル名を書いていない場所を見つける

テーブル名の宣言無しに列名が使われるとわかりづらいため、

「joinを行ったらテーブル名を書かなくてはならない」というコーディング規約が現場にある。

しかし、この規約違反を目でチェックするのが面倒なので自動化する。

つまり、


good.sql

SELECT

book.title
FROM
book
INNER JOIN shelf ON boo.id_shelf = shelf.id
WHERE
shelf.name = 'mine'

というのを、


bad.sql

SELECT

title
FROM
book
INNER JOIN shelf ON boo.id_shelf = shelf.id
WHERE
shelf.name = 'mine'

のように書いている場所を発見したい。(下のSELECT句にはbookが抜けている)


道具の用意

静的にTransact-SQLを解析するのは自分の力ではできそうになかったので、ライブラリを使用した。

使用したのは、Microsoftが提供しているTransact-SQLのパーサー兼ジェネレータ

TransactSql.ScriptDom

使い方はT-SQL の パーサーとジェネレーター(ScriptDom)の紹介が参考になる。

これはVisitorを使用していて、動きに合わせて全ての部分に行けるのでパース結果から静的な解析が楽にできる。

が、ドキュメントが皆無なので、どんな時に何のメソッドが呼ばれるのかは実験する必要がある。


解析する

目的は「joinを行ったのにテーブル名を書いていない場所を見つける」こと

テーブルの列名が宣言されるべき場所はSELECT, WHERE, ORDERなど色々あるが、パースした結果では共通してExplicitVisit(ColumnReferenceExpression)が呼ばれている。

そのため、


  • SELECT,INSERT,UPDATE,DELETE文内でExplicitVisit(..)が呼ばれている

  • 宣言されている列名にテーブル名がついていない

  • JOINが呼ばれている

以上を満たせば「joinがあるのにテーブル名が宣言されていない」ということがわかる。

これを利用して、T-SQL文字列から規約違反を発見することが出来る。

実際に使用しているプログラムはGithubにおいている。

SQLChecker内が実際にT-SQLをチェックしている部分