sqlite3.OperationalError: close "t": 语法错误是什么意思

Dim*_*try 0 python sqlite

我正在使用 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()
Run Code Online (Sandbox Code Playgroud)

我得到:sqlite3.OperationalError:靠近“t”:语法错误出了什么问题?注意它指向“db.excute(sql)”行并表示该行是错误

unu*_*tbu 5

假设name包含一个单引号,后跟一个t,如

\n\n
name = "don\'t look now"\nsql = "update foo set is_processed=1 where bar=\'"+name+"\'"\n
Run Code Online (Sandbox Code Playgroud)\n\n

那么就sql等于

\n\n
In [156]: sql\nOut[156]: "update foo set is_processed=1 where bar=\'don\'t look now\'"\n
Run Code Online (Sandbox Code Playgroud)\n\n

sqlite3 会认为条件where bar=\'don\'后面有语法错误,t look now\'sqlite3然后加注

\n\n
sqlite3.OperationalError: near "t": syntax error\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是为什么您应该始终使用参数化 SQL的示例。为了避免此问题(并保护您的代码免受 SQL 注入攻击),请使用参数化 SQL 并将值序列(或者,根据参数样式,映射)作为第二个参数传递给cursor.execute

\n\n
sql = "update foo set is_processed=1 where bar=?"\ncursor.execute(sql, [name])\n
Run Code Online (Sandbox Code Playgroud)\n\n

当您将参数(例如[name])作为第二个参数传递给 \n 时cursor.execute,sqlite3 将为您转义单引号。

\n\n
\n\n

根据Python Database API,当您parameters作为第二个参数传递给cursor.execute(我的重点)时:

\n\n
\n

该模块将使用__getitem__参数对象的方法将位置(整数)或名称(字符串)映射到参数值。这允许序列和映射都用作输入。

\n\n

术语“绑定”是指将输入值绑定到数据库执行缓冲区的过程。实际上,这意味着输入值直接用作运算中的值。不应要求客户端\n 对值进行“转义”以便可以使用\xe2\x80\x94 该值应等于\n 实际数据库值

\n
\n\n
\n\n

下面是一个可运行的玩具示例,可帮助您了解该问题以及如何使用参数化 SQL 来避免该问题:

\n\n
import sqlite3\n\nwith sqlite3.connect(\':memory:\') as conn:\n    cursor = conn.cursor()\n    cursor.execute(\'\'\'CREATE TABLE foo\n                 (id INTEGER PRIMARY KEY AUTOINCREMENT,\n                  bar TEXT,\n                  is_processed BOOL)\'\'\')\n    name = "don\'t look now"\n\n    sql = "update foo set is_processed=1 where bar=\'"+name+"\'"\n    print(sql)\n    cursor.execute(sql)\n\n    # comment out `cursor.execute(sql)` above and compare with\n    # sql = "update foo set is_processed=1 where bar=?"\n    # cursor.execute(sql, [name])\n
Run Code Online (Sandbox Code Playgroud)\n