コンテンツにスキップ

スクリプト開発 / SQL 構築 DFF.SQL

DFF.SQL(...) は、パラメータ付き SQL を構築し、文字列連結によるユーザー入力の挿入を回避するために使用されます。ほとんどの SQL コネクターにはこの機能がすでに組み込まれており、conn.query(sql, sql_params=...) または conn.non_query(...) を直接呼び出すことができます。

SQL をデバッグ用に明示的にフォーマットする必要がある場合、または呼び出し側が最終的な SQL 文字列を受け取る必要がある場合にのみ、DFF.SQL(...) を単独で呼び出す必要があります。

パラメータとプレースホルダー

パラメータ 必須 / デフォルト値 説明
sql str 必須 パラメータプレースホルダーを含む SQL 文
sql_params list None プレースホルダーの順に指定する SQL パラメータ
プレースホルダー 意味 例の結果
? 値パラメータ。エスケープされ引用符が付加される 'user-001'
?? 識別子または SQL フラグメント。引用符なし users
1
2
3
4
5
sql = DFF.SQL(
    'SELECT * FROM ?? WHERE id = ?',
    ['users', 'user-001'],
)
# SELECT * FROM users WHERE id = 'user-001'

?? は信頼できない入力を保護しない

ユーザー入力は ? に入れる必要があります。テーブル名、フィールド名などの識別子は、許可リストまたは信頼できる設定に由来する場合にのみ ?? に入れることができ、f-string や文字列連結によって SQL 値を挿入してはなりません。

パラメータ展開

配列パラメータは自動的に複数の値に展開され、2 次元配列は複数行の値に展開されます:

配列展開
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
rows = db.query(
    'SELECT * FROM ?? WHERE status IN (?)',
    ['demo', ['error', 'warning']],
)
# SELECT * FROM demo WHERE status IN ('error', 'warning')

affected_rows = db.non_query(
    'INSERT INTO ?? (id, name) VALUES ?',
    ['demo', [[1, 'a'], [2, 'b']]],
)
# INSERT INTO demo (id, name) VALUES (1, 'a'), (2, 'b')

辞書パラメータは複数の代入式に展開されます:

辞書展開
1
2
3
4
5
affected_rows = db.non_query(
    'INSERT INTO ?? SET ?',
    ['demo', {'id': 1, 'name': 'a'}],
)
# INSERT INTO demo SET id = 1, name = 'a'

動的な書き込みまたは削除 SQL を実行する前に、対象テーブルとフィルタ条件を再確認してください。