【问题标题】:Passing in Variables in Python to SQL Query将 Python 中的变量传递给 SQL 查询
【发布时间】:2019-11-03 12:50:17
【问题描述】:

当我运行下面的 SQL 查询时,我收到错误 print(db.execute("SELECT * FROM (?);"), (tableName)) sqlite3.OperationalError:靠近“?”:语法错误

db = sqlite3.Connection(":memory:")
db.execute("CREATE TABLE Students(name);")
tableName = "Students"
var1 = "Jon"
var2 = "Steve"
var3 = "Chuckie"
db.execute("INSERT INTO Students VALUES (?), (?), (?)", (var1, var2, var3))
print(db.execute("SELECT * FROM (?);"), (tableName))

将参数传递给 SQL 查询的正确方法是什么?

【问题讨论】:

  • 您不能参数化表名。如果您尝试连接/插入查询字符串,这是可能的,但如果没有正确引用,则会导致 SQL 注入。
  • 我需要参数化表名,那么最好的方法是什么? @LukaszSzozda

标签: python sql


【解决方案1】:

您不能在 SQL 中动态绑定对象名称,只能绑定值。对于这种行为,您将不得不求助于字符串操作:

queryTemplate = 'SELECT * FROM %s'
tableName = 'Students'
query = queryTemplate % tableName

print(query)

编辑:
为了解决评论中的问题——是的,这种技术确实更容易受到 SQL 注入攻击。在这种情况下防止 SQL 注入的常见做法是使用允许表的白名单。

例如:

allowedTables = ['students', 'teachers']
if tableName not in allowedTables:
    raise ValueError('Wrong table')

【讨论】:

  • Students; DROP TABLE ...; --
  • 如何防范这种 SQL 注入?
  • @laddie_03 可能是通过使用某种白名单。请参阅我编辑的答案以获得简单的实现
  • python 字符串函数 .format() 是否适用于 SQL 查询?
  • 我们还在使用模运算符进行字符串插值吗? consensus years ago 是使用str.format。事实上,即使是 Python 的PEP 3101 也这么建议!这就像在 SQL 中使用implicit over explicit join,ANSI-1992 推荐了当前标准。
【解决方案2】:

在元组中传递值,

query = ("INSERT INTO  billed_items(item_name,billed_qty,price,item_bill_series) VALUES(?,?,?,?)")
c.execute(query,((name),(no),(price),(series))
conn.commit()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-10
    • 2019-02-16
    • 1970-01-01
    • 1970-01-01
    • 2020-04-03
    • 2022-08-15
    • 1970-01-01
    相关资源
    最近更新 更多