如何将 SQL 参数与 IN 子句一起用于 pyodbc 的可变数量的值?
How to use SQL parameters with IN clause for a variable number of values with pyodbc?
我有一个值列表,我想在 IN
子句中使用 pyodbc 执行的 SQL(SQL 服务器)语句。示例:
files = ['file1', 'file2', ...] # this list can have a variable number of elements
con = pyodbc.connect(...)
# What I'd like to do
result = con.cursor().execute('SELECT * FROM sometable WHERE file_name IN (?)', files)
然而,当我执行上面的语句时,出现如下错误:
ProgrammingError: ('The SQL contains 1 parameter markers, but 18 parameters were supplied', 'HY000')
我可以使用如下方式生成可变参数字符串:
params = ','.join(['?']*len(files))
query = 'SELECT * FROM sometable WHERE file_name IN ({})'.format(params)
result = con.cursor().execute(query, files)
但是如果我理解正确的话,这样做会使我面临 SQL 注射的风险。有没有办法安全地完成此操作?
您可以使用 JSON 将列表传递给 SQL 服务器。 EG
import numpy as np
import pandas as pd
import pyodbc
import json
files = ['file1', 'file2', 'file3'] # this list can have a variable number of elements
json_files = json.dumps(files)
print(json_files)
conn = pyodbc.connect('Driver={Sql Server};'
'Server=localhost;'
'Database=tempdb;'
'Trusted_Connection=yes;')
cursor = conn.cursor()
cursor.execute("create table #sometable(id int, file_name varchar(255)); insert into #sometable(id,file_name) values (1,'file2')")
# What I'd like to do
result = cursor.execute('SELECT * FROM #sometable WHERE file_name IN (select value from openjson(?))', json_files)
rows = cursor.fetchall()
print(rows)
doing so would put me at risk for SQL injection
不,不会,因为您可以完全控制要注入 SQL 命令文本的内容(即以逗号分隔的问号字符串)。只要您的列表包含的项目不超过大约 2100 个,您的方法就可以了。
我有一个值列表,我想在 IN
子句中使用 pyodbc 执行的 SQL(SQL 服务器)语句。示例:
files = ['file1', 'file2', ...] # this list can have a variable number of elements
con = pyodbc.connect(...)
# What I'd like to do
result = con.cursor().execute('SELECT * FROM sometable WHERE file_name IN (?)', files)
然而,当我执行上面的语句时,出现如下错误:
ProgrammingError: ('The SQL contains 1 parameter markers, but 18 parameters were supplied', 'HY000')
我可以使用如下方式生成可变参数字符串:
params = ','.join(['?']*len(files))
query = 'SELECT * FROM sometable WHERE file_name IN ({})'.format(params)
result = con.cursor().execute(query, files)
但是如果我理解正确的话,这样做会使我面临 SQL 注射的风险。有没有办法安全地完成此操作?
您可以使用 JSON 将列表传递给 SQL 服务器。 EG
import numpy as np
import pandas as pd
import pyodbc
import json
files = ['file1', 'file2', 'file3'] # this list can have a variable number of elements
json_files = json.dumps(files)
print(json_files)
conn = pyodbc.connect('Driver={Sql Server};'
'Server=localhost;'
'Database=tempdb;'
'Trusted_Connection=yes;')
cursor = conn.cursor()
cursor.execute("create table #sometable(id int, file_name varchar(255)); insert into #sometable(id,file_name) values (1,'file2')")
# What I'd like to do
result = cursor.execute('SELECT * FROM #sometable WHERE file_name IN (select value from openjson(?))', json_files)
rows = cursor.fetchall()
print(rows)
doing so would put me at risk for SQL injection
不,不会,因为您可以完全控制要注入 SQL 命令文本的内容(即以逗号分隔的问号字符串)。只要您的列表包含的项目不超过大约 2100 个,您的方法就可以了。