SQLToolsプラグイン(その7・SQL内でテンプレートタグを使う)

SQLToolsプラグインでは、テンプレートタグ内で、Movable Typeのテンプレートタグを使うことができます。
状況に応じてSQLの組み方を動的に変えるようなことができます。

1.利用できるテンプレートタグ/変数

SQL内では、インデックステンプレートで使えるテンプレートタグなら、すべて使えるはずです。
特に、MTIfタグを使って、条件に応じてSQLの組み方を変えることを想定しています。

また、SQLを呼び出したテンプレートで設定されている変数も、SQLの中で使うことができます。
例えば、メインページのインデックステンプレートの中で、MTSQLObjectsタグを使って、SQLを実行するとします。
この場合、そのSQLの中では、メインページのインデックステンプレートで設定した変数を使うことができます。

ただし、SQL側で変数を設定したり書き換えたりしても、その実行元のテンプレートには反映しません。

2.事例

例えば、「いくつかのカテゴリのどれかに属する記事を、公開日時順に出力する」ということを考えてみます。
カテゴリのIDを、配列変数cat_idsで表すものとします。
また、cat_idsの内容が空になる(=カテゴリを指定しない)場合もあり、その時はすべての記事を出力したいとします。

cat_idsに1つ以上の値が入っている場合は、以下のSQLを実行します。

SELECT DISTINCT entry_id
FROM mt_entry, mt_placement
WHERE entry_class = 'entry'
AND entry_blog_id = ?
AND entry_status = 2
AND entry_id = placement_entry_id
AND placement_category_id IN (?)
ORDER BY entry_authored_on DESC

一方、cat_idsに値がない場合は、以下のSQLを実行します。

SELECT DISTINCT entry_id
FROM mt_entry
WHERE entry_class = 'entry'
AND entry_blog_id = ?
AND entry_status = 2
ORDER BY entry_authored_on DESC

両者の違いは、以下の2点です。

  • カテゴリを指定する際には、FROM句に「, mt_category」が必要
  • カテゴリを指定する際には、WHERE句に「AND entry_id = placement_entry_id AND placement_category_id IN (?)」が必要

そこで、変数cat_idsに値があるかどうかに応じて、MTIfタグを使って上記の2つを追加するかどうかを判断し、SQLを作り分けるようにします。
具体的には以下のようなSQLを登録しておきます。

SELECT DISTINCT entry_id
FROM mt_entry<mt:If name="cat_ids">, mt_placement</mt:If>
WHERE entry_class = 'entry'
AND entry_blog_id = ?
AND entry_status = 2
<mt:If name="cat_ids">
AND entry_id = placement_entry_id
AND placement_category_id IN (?)
</mt:If>
ORDER BY entry_authored_on DESC

3.注意点

SQLの組み方を動的に変える場合、組み方によってはSQLインジェクションが発生する可能性があります。
SQLの内容をよく考慮する必要があります。