跳轉至

腳本開發 / 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 值。

參數展開

數組參數會自動展開為多個值,二維數組會展開為多行值:

數組展開
 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 前,應再次確認目標表和過濾條件。