Skip to content

エスケープと動的参照

パラメータが SQL 内のどの位置に置かれるかによって、エスケープの扱いが変わります。この仕組みは SQL インジェクション対策に加え、テーブル名やカラム名などの動的な識別子生成にも使えます。

通常のコンテキストでの文字列パラメータ

パラメータは文字列としてエスケープされて展開されます。エスケープは、選択中のコネクションの SQL 文法に従います。

sql
-- パラメータ値が user's "data" の場合
WHERE name = {{str_param}}         -> WHERE name = 'user\'s \"data\"'

-- パラメータ値が O'Reilly's "Book" の場合
SELECT name = {{company}}          -> SELECT name = 'O\'Reilly\'s \"Book\"'

引用符付きコンテキストでの文字列パラメータ

パラメータがシングルクォート・ダブルクォート・バックティックなどの引用符内にある場合、外側の引用符を壊さないように中身だけがエスケープされます。エスケープはコネクションの SQL 文法に従います。

次は BigQuery コネクションの例です。

sql
-- ダブルクォート内("と'の両方をエスケープ)
-- パラメータ値が user"s 'data' の場合
SELECT "{{str_param}}" as alias    -> SELECT "user\"s \'data\'" as alias

-- シングルクォート内("'の両方をエスケープ)
-- パラメータ値が user"s 'data' の場合
SELECT '{{str_param}}' as alias    -> SELECT 'user\"s \'data\'' as alias

-- バックティック内(`のみをエスケープ)
-- パラメータ値が user"s 'data` の場合
SELECT `{{str_param}}` as alias    -> SELECT `user"s 'data\`` as alias

日付パラメータの特別処理

  • 通常のコンテキストでは、日付は YYYY-MM-DD 形式の文字列として展開されます
  • BigQuery コネクションでは、バックティック内に置いた日付は YYYYMMDD(ハイフンなし)に展開されます
sql
-- BigQuery コネクションの例

-- 通常の日付パラメータ
SELECT {{date_param}} as normal         -> SELECT '2024-10-02' as normal

-- 引用符内の日付は同じエスケープルールに従う
SELECT '{{date_param}}' as single_quote -> SELECT '2024-10-02' as single_quote
SELECT "{{date_param}}" as double_quote -> SELECT "2024-10-02" as double_quote

-- 特殊ケース: BigQuery でのテーブル名生成
SELECT * FROM `table_{{date_param}}`    -> SELECT * FROM `table_20241002`

数値・真偽値パラメータ

数値・真偽値パラメータはエスケープされず、そのまま展開されます。

動的な参照の生成

パラメータを引用符内に置くと、テーブル名やカラム名などの識別子を動的に生成できます。

sql
-- 動的なテーブル名
SELECT * FROM `table_{{table_suffix}}` -> SELECT * FROM `table_sales_2024`

-- 動的なフィールド選択
SELECT "column_{{field_type}}"         -> SELECT "column_revenue"

WARNING

外側の引用符に応じて構文が壊れないようエスケープされます。一方で 文字列パラメータには任意の文字列を指定できます。SQL の書き方次第では、意図しないテーブルやカラムを参照してしまう可能性があります。動的な識別子生成では、プレフィックスやサフィックスを固定する、想定外の値では SQL が失敗する書き方にする、などの対策を検討してください。