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