エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

WITH句てんこもりのSQLをデバッグする

巨大なSQLの出力が意図と違っていたり違っているかもしれないとき、どこから確認しようか頭を抱えてしまうことってありますよね。せめて多段階で作られているたくさんのCTE (WITH句)、これらが一つずつどんな表を出力しているのか簡単にのぞけたら手がかりもあるのだけれど⋯

今回はそれをわりと現実的な手間でできるようにする小技です。エムスリーエンジニアリングループUnit1(製薬プロモーション)/Unit9(治験臨床研究支援)エンジニアの三浦[記事一覧 ]です。

魔法の一行

SQLの最後に

-- */

という無意味なコメント行を付けておいてください。ひと目見て分かる通り、まったく無意味です。ところがこれがあるだけで、デバッグのときにこんなことができるようになります――

デバッグを実現する一行

次のようなCTEの大行列があるとします。おしりにはすでに魔法の一行が入っています。

WITH
  cte1 AS (SELECT * FROM ... )
, cte2 AS (SELECT * FROM cte1 ... )
, cte3 AS (SELECT * FROM cte2 ... )
, cte4 AS (SELECT * FROM cte3 ... )
   ︙
SELECT ...
-- */

ここで、cte3の出力をのぞきたくなったとしましょう。そうしたら、cte3の定義の直後にこう書きます。

SELECT * FROM cte3 /*

最後にブロックコメント開きが入っていますね。これは、末尾の魔法の一行と呼応します。つまり、全体としてはこうなるので

WITH
  cte1 AS (SELECT * FROM ... )
, cte2 AS (SELECT * FROM cte1 ... )
, cte3 AS (SELECT * FROM cte2 ... )
SELECT * FROM cte3 /*
, cte4 AS (SELECT * FROM cte3 ... )

SELECT ...
-- */

コメント部分を無視するとこうだということになるのです。のぞける!

WITH
  cte1 AS (SELECT * FROM ... )
, cte2 AS (SELECT * FROM cte1 ... )
, cte3 AS (SELECT * FROM cte2 ... )
SELECT * FROM cte3

出力をのぞき終わったら、今のデバッグ行の頭に -- を付けてコメントアウトしてしまえば⋯

WITH
  cte1 AS (SELECT * FROM ... )
, cte2 AS (SELECT * FROM cte1 ... )
, cte3 AS (SELECT * FROM cte2 ... )
-- SELECT * FROM cte3 /*
, cte4 AS (SELECT * FROM cte3 ... )
   ︙
SELECT ...
-- */

はい、このようにもとのSQLに戻りました。出力観察を一行で埋め込んだりそれを2文字でOFFれる、これが末尾の魔法の一行の力だってわけです。

別に一行で制御できなくたってCTEの動きを確認する方法はいくらでもあります。しかし調査するからにはコード全体を行ったり来たりして調べることになるのにそのたびにガシガシ書き換えが必要だったりすると「とてもやっていられない」、ゆえに調査が進まないことはありますよね。人間ですもの。それを「やればまあできる」に変えると手を付けられるようになる、そうやって量が質に転化することは我々が日頃感じていることでありましょう。

We are hiring

しんどいことをしんどくなくする技術、語り合いませんか。ご興味あったらこちらのページからどうぞ。応募を前提にしないカジュアル面談もやっています。

jobs.m3.com