我试图通过提供从此类方法中获取的参数来格式化python中的SQL查询
public void rowProcessorSwitched(RowProcessor from, RowProcessor to) {
if(from == inventoryLineProcessor){ // stopped processing inventory lines and will process some other row.
List<InventoryLine> inventoryLines = inventoryLineProcessor.getBeans();
//now assign a copy of this list to the last InventoryHeader you have
}
}
运行此代码时,出现以下错误(python 2.6)
query = "select * from employees where employee_name like '%s%'" % (name)
我也在命令行中尝试过以找出问题所在
ValueError: unsupported format character ''' (0x27) at index 886
当我不立即在单引号内添加%时,%s起作用,但是即使转义,我在之后添加%时也会中断。有没有解决办法,没有这个我就不能在SQL查询中替换变量。
答案 0 :(得分:3)
这就是SQL注入漏洞的产生方式。 SQL注入将使入侵者可以读取私有数据,甚至可以修改数据。永远不要将原始字符串传递到SQL查询中,除非您确保它没有特殊字符,例如'
,%
和\
。实际上,最好使用经过良好测试的函数为您完成此任务。
您会认为:
query = "select * from employees where employee_name like '%s%%'" % (name)
# (two `%%` at the end)
解决了您的问题,但是如果以某种方式name == "%' or '' like '"
(或类似的方式),查询突然变为:
"select * from employees where employee_name like '%' or '' like '%'"
将匹配所有员工。更糟糕的是,就您而言,name = ''
也是一场噩梦。首先,我认为在此类查询中使用like
并不是一个好主意。
有关安全格式化的一些信息,您可以阅读sql-injection标签下的堆栈溢出问题,例如Protecting against SQL injection in python。每个数据库系统都提供自己的存储过程接口,请使用它。
答案 1 :(得分:2)
虽然您的问题通常是询问在python中格式化字符串的正确方法,但对于您的特定用例(这是一个sql查询),您应该确保正确地转义了字符串。
这对于(1)停止sql注入攻击很重要,(2)当变量字符串中带有引号时也很有用。
例如,对于名称为O'Conner
的任何人,您当前的查询都会错误。
相反,请利用您的库的参数化方法进行查询。
您没有说出您使用的是哪个sql库,因此我将以MySQLdb为例。
1)基本示例(不带'%'通配符):
name = "O'Conner"
query = (
"SELECT *"
" FROM employees"
" WHERE employee_name = %s" # notice the lack of quotes around %s
)
params = (name,)
cursor.execute(query, params)
2)由于您使用通配符,因此需要更加明确:
query = (
"SELECT *"
" FROM employees"
" WHERE employee_name LIKE '{}%'" # must specify the quotes
"".format(
MySQLdb.escape_string(name).replace('%', '\\%').replace('_', '\\_')
)
)
cursor.execute(query)
(当您为cursor.execute
提供params参数时,它在幕后使用MySQLdb.escape_string
。它还处理带引号的换行。请注意,情况1中的%s是 not < / em>与情况2相反的典型python%s-阅读以上链接中的文档以了解更多信息。)
答案 2 :(得分:1)
尝试
query = "select * from employees where employee_name like '%{}%'".format(name)
如果您使用的是python 3.6,则也可以使用f-string,如下所示
query = f"select * from employees where employee_name like '%{name}%'"