繁体   English   中英

在python中使用变量进行SQL查询

[英]SQL query with variables in python

我正在编写一个程序,该程序是小学教师设置的测验的用户界面。 我正在尝试使用用户在上一页中键入的数据的此查询。 它正在数据库中寻找与用户名和测验编号匹配的人员。 这样老师可以看到学生在某些测验中的表现如何。

这是我的代码。

dbDatabase = sqlite3.connect('c:\\xampp\\cgi-bin\\MakingATable.db')
cuDatabase = dbDatabase.cursor()

Fieldstorage = cgi.FieldStorage() #what you typed in on the webpage

Quizno = Fieldstorage.getvalue("quizno")
UserID = Fieldstorage.getvalue("username")

#print (Quizno)
#print (UserID)

cuDatabase.execute ("""
    SELECT Result
    FROM resultstable
    WHERE QuizID = '""" + str(Quizno) + """
    AND UserID = '""" + UserID + "'")

for (row) in cuDatabase:
    print (row)

dbDatabase.commit()
cuDatabase.close()

这是我运行网页时收到的错误消息:

     40         FROM resultstable
     41         WHERE QuizID = '""" + str(Quizno) + """
=>   42         AND UserID = '""" + UserID + "'")
     43 
     44     for (row) in cuDatabase:
AND undefined, UserID = 'HuPa1'


OperationalError: near "HuPa1": syntax error 
      args = ('near "HuPa1": syntax error',) 
      with_traceback = <built-in method with_traceback of OperationalError object>

我还应该使用OR而不是AND以便如果用户尚未完成该测验,它将显示用户所做的任何测验。 还是这样,如果有很多人完成了一个测验,那么老师会看到所有人,例如,完成测验1的所有人?

您应该使用SQL参数:

cuDatabase.execute ("""
    SELECT Result
    FROM resultstable
    WHERE QuizID = ?
    AND UserID = ?""", (Quizno, UserID))

? 占位符将替换为您的值,并自动将其引起引用以防止SQL注入攻击(和操作错误)。

引用sqlite3模块文档

通常,您的SQL操作将需要使用Python变量中的值。 您不应该使用Python的字符串操作来汇编查询,因为这样做是不安全的。 它使您的程序容易受到SQL注入攻击的影响(有关可能出现问题的幽默示例,请参见http://xkcd.com/327/ )。

而是使用DB-API的参数替换。 ? 作为要使用值的位置的占位符,然后提供值的元组作为游标的execute()方法的第二个参数。 (其他数据库模块可以使用其他占位符,例如%s:1 。)

如果该查询未返回结果,请使用单独的查询向数据库询问其他测验。 如果您使用OR而不是AND ,则您将同时获得其他用户已经完成的测验结果以及 用户已完成的所有事情。

最好的解决方案是使用准备好的语句:

cuDatabase.execute("SELECT Result FROM resultstable WHERE QuizID=? AND UserID=?", Quizno, UserID)

在准备语句模式下,所有变量均被查询文本中的问号替换,并且是execute()参数。 但并非所有数据库或数据库驱动程序都支持它。 有时,您不必使用问号,而必须使用%s (PostgreSQL驱动程序之一可以这种方式)。

更糟糕的是,可行的解决方案是使用Python %运算符,但是使用此解决方案,您将必须使用自己的quote()函数来转义可能出现在数据中的危险字符(防止SQL注入):

cuDatabase.execute("SELECT Result FROM resultstable WHERE QuizID='%s' AND UserID='%s'" % (quote(Quizno), quote(UserID)))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM