我正在使用python并尝试使用
更新行db=sqlite3.connect('db')
cursor=db.execute('select * from infos where is_processed=0')
films=cursor.fetchall()
cursor.close()
db.close()
for film in films:
inputLayer=np.array([film[1],film[2],film[3]],dtype=float)
name=film[0]
#print inputLayer
NeuralNetwork3.nn(inputLayer,film[4])
sql="update infos set is_processed=1 where file_name='"+name+"'"
db = sqlite3.connect('db')
db.execute(sql)
db.commit()
db.close()
我得到:sqlite3.OperationalError:near" t":语法错误有什么问题? 注意它指向第34行; db.excute(sql)"并说在那一行是错误
答案 0 :(得分:2)
假设name
包含单引号,后跟t
,如
name = "don't look now"
sql = "update foo set is_processed=1 where bar='"+name+"'"
然后sql
等于
In [156]: sql
Out[156]: "update foo set is_processed=1 where bar='don't look now'"
和sqlite3会认为条件为where bar='don'
,后跟语法错误t look now'
。 sqlite3
然后提出
sqlite3.OperationalError: near "t": syntax error
这是为什么你应该always use parametrized SQL的一个例子。要避免此问题(并保护您的代码免受SQL注入攻击),请使用参数化SQL并将值的序列(或,取决于paramstyle,映射)作为cursor.execute
的第二个参数传递:
sql = "update foo set is_processed=1 where bar=?"
cursor.execute(sql, [name])
当你传递参数(例如[name]
)作为第二个参数时
cursor.execute
,sqlite3将为您提供单引号。
根据Python Database API,当您将parameters
作为第二个参数传递给cursor.execute
时(我的重点):
模块将使用参数对象的
__getitem__
方法进行映射 位置(整数)或名称(字符串)到参数值。这个 允许将序列和映射用作输入。术语绑定是指将输入值绑定到数据库的过程 执行缓冲区。 实际上,这意味着输入值是 直接用作操作中的值。不应要求客户 到"逃避"该值可以使用 - 该值应该等于 实际的数据库值
这是一个可运行的玩具示例,可帮助您查看问题以及如何使用参数化SQL来避免问题:
import sqlite3
with sqlite3.connect(':memory:') as conn:
cursor = conn.cursor()
cursor.execute('''CREATE TABLE foo
(id INTEGER PRIMARY KEY AUTOINCREMENT,
bar TEXT,
is_processed BOOL)''')
name = "don't look now"
sql = "update foo set is_processed=1 where bar='"+name+"'"
print(sql)
cursor.execute(sql)
# comment out `cursor.execute(sql)` above and compare with
# sql = "update foo set is_processed=1 where bar=?"
# cursor.execute(sql, [name])