跳转至

脚本开发 / 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 前,应再次确认目标表和过滤条件。