在查询中插入表名称将得到sqlite3.OperationalError:在“?”附近:语法错误
我想动态选择要在SQL查询中使用的表,但是我一直在获取错误,但是我试图对此进行格式化。也尝试%s
代替?
。
有什么建议?
group_food = (group, food)
group_food_new = (group, food, 1)
with con:
cur = con.cursor()
tmp = cur.execute("SELECT COUNT(Name) FROM (?) WHERE Name=?", group_food)
if tmp == 0:
cur.execute("INSERT INTO ? VALUES(?, ?)", group_food_new)
else:
times_before = cur.execute("SELECT Times FROM ? WHERE Name=?", group_food)
group_food_update = (group, (times_before +1), food)
cur.execute("UPDATE ? SET Times=? WHERE Name=?", group_food_update)
-
您不能将SQL参数用作SQL对象中的占位符。使用SQL参数的 原因之一 是对值进行转义,以使数据库永远不会将内容误认为数据库对象。
您必须分别插值数据库对象;通过将任何
"
双引号参数加倍来转义您的标识符并使用cur.execute('SELECT COUNT(Name) FROM "{}" WHERE Name=?'.format(group.replace('"', '""')), (food,))
和
cur.execute('INSERT INTO "{}" VALUES(?, ?)'.format(group.replace('"', '""')), (food, 1))
和
cur.execute('UPDATE "{}" SET Times=? WHERE Name=?'.format(group.replace('"', '""')), (times_before + 1, food))
在
".."
双引号是有正确丹麦的标识,即使该标识也是一个有效的关键字;"
名称中的任何现有字符必须加倍;这也有助于取消对SQL注入尝试的混淆。但是,如果对象名称是用户来源的,则必须对对象名称进行自己的(严格)验证,以防止此处的SQL注入攻击。在这种情况下,请始终针对现有对象验证它们。
您应该真正考虑使用像SQLAlchemy这样的项目来生成SQL。它可以帮助验证对象名称,并严格保护您免受SQL注入风险。它可以预先加载您的表定义,以便知道哪些名称是合法的:
from sqlalchemy import create_engine, func, select, MetaData engine = create_engine('sqlite:////path/to/database') meta = MetaData() meta.reflect(bind=engine) conn = engine.connect() group_table = meta.tables[group] # can only find existing tables count_statement = select([func.count(group_table.c.Name)], group_table.c.Name == food) count, = conn.execute(count_statement).fetchone() if count: # etc.