脚本开发 / SQL 构造 DFF.SQL
使用 DFF.SQL(...)
可以方便地生成动态 SQL 语句,避免手工拼接 SQL 导致 SQL 注入问题。
参数 |
类型 |
必须 / 默认值 |
说明 |
sql |
str |
必须 |
SQL 语句,可包含参数占位符。
? 表示需要转义的参数;
?? 表示不需要转义的参数 |
sql_params |
list |
None |
SQL 参数 |
绝大多数 SQL 类连接器已内置此功能
绝大多数通过 DFF.CONN(...) 创建的,SQL 类的连接器操作对象都已经内置了此功能,可以直接使用
直接使用 conn.query(sql, sql_params)
即可,不用单独调用此方法。
此方法主要用于方便 DEBUG SQL 语句,通过 print(...)
观察实际执行的 SQL 语句
示例 |
---|
| sql = 'SELECT * FROM ?? WHERE id = ?'
sql_params = [ 'users', 'user-001' ]
print(DFF.SQL(sql, sql_params))
|
示例输出 |
---|
| SELECT * FROM users WHERE id = 'user-001'
|
参数展开
为了方便动态 SQL 的生成,本方法会根据 sql_params
中的值类型,进行参数展开。
允许用户将不确定数量的内容打包作为一个参数传入,由系统自动展开。
使用时,针对某个参数占位符填入数组或数组即可,如:
数组展开式
参数为数组的,会自动展开为如下形式:
示例 1 |
---|
| sql = 'SELECT * FROM ?? WHERE status IN (?)'
sql_params = [
# 对应第一个参数占位符 ??
'demo',
# 对应第二个参数占位符 ?,参数值为数组,自动展开为多个值
[ 'error', 'warning' ]
]
result = db.query(sql, sql_params=sql_params)
|
实际执行的 SQL |
---|
| SELECT * FROM demo WHERE status IN ('error', 'warning')
|
参数为数组,且其元素也为数组的,会自动进行二层展开为如下形式:
二维数组参数展开 |
---|
| (p1_1, p1_2, p1_3, ...), (p2_1, p2_2, p2_3, ...), (p3_1, p3_2, p3_3, ...), ...`.
|
示例 2 |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13 | sql = 'INSERT INTO ?? (id, name, value) VALUES ?'
sql_params = [
# 对应第一个参数占位符 ??
'demo',
# 对应第二个参数占位符 ?,参数值为数组,自动展开为多个值(即多条数据库记录)
[
# 参数值数组内元素依然为数组,自动继续展开(即每条数据库记录的多个字段)
[ 1, 'zhang3', 100 ],
[ 1, 'li4', 200 ],
]
]
effected_rows = db.non_query(sql, sql_params=sql_params)
|
实际执行的 SQL |
---|
| INSERT INTO demo (id, name, value) VALUES (1, 'zhang3', 100), (1, 'li4', 200)
|
字典展开式
示例 |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13 | sql = 'INSERT INTO ?? SET ?'
sql_params = [
# 对应第一个参数占位符 ??
'demo',
# 对应第二个参数占位符 ?,字典自动展开为多个赋值语法
{
'id' : 1,
'name' : 'zhang3',
'value': 100,
}
]
effected_rows = db.non_query(sql, sql_params=sql_params)
|
实际执行的 SQL |
---|
| INSERT INTO demo SET id = 1, name = 'zhang3', value = 100
|