我制作的程序是小学教师设置的用户界面。我正在尝试使用上一页上用户输入的数据的查询。它正在寻找数据库中与用户名和测验号相匹配的人。这是老师可以看到学生在某些问题上的表现。
这是我的代码。
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?
答案 0 :(得分:3)
您应该使用SQL参数:
cuDatabase.execute ("""
SELECT Result
FROM resultstable
WHERE QuizID = ?
AND UserID = ?""", (Quizno, UserID))
?
占位符将被您的值替换,自动引用以防止SQL注入攻击(以及操作错误)。
引用sqlite3
module documentation:
通常,您的SQL操作需要使用Python变量中的值。你不应该使用Python的字符串操作来组装你的查询,因为这样做是不安全的;它使您的程序容易受到SQL注入攻击(请参阅http://xkcd.com/327/以获取可能出错的幽默示例)。
相反,请使用DB-API的参数替换。将
?
作为占位符放在要使用值的位置,然后提供值元组作为游标execute()
方法的第二个参数。 (其他数据库模块可能使用不同的占位符,例如%s
或:1
。)
如果此查询未返回结果,请使用单独的查询向数据库询问其他测验;如果您使用OR
而不是AND
,则会获得其他用户已完成的quizz结果,和任何此< / em>用户已完成。
答案 1 :(得分:0)
最好的解决方案是使用预备声明:
cuDatabase.execute("SELECT Result FROM resultstable WHERE QuizID=? AND UserID=?", Quizno, UserID)
在预准备语句模式下,所有变量都被查询文本中的问号替换,并且是execute()
的参数。但并非所有数据库或db驱动程序都支持它。有时候你需要使用%s
(PostgreSQL驱动程序中的一个以这种方式工作)而不是问号。
更糟糕,但工作解决方案是使用Python %
运算符,但是使用此解决方案,您将不得不使用自己的quote()
函数来逃避可能出现在数据中的危险字符(防止SQL注入):
cuDatabase.execute("SELECT Result FROM resultstable WHERE QuizID='%s' AND UserID='%s'" % (quote(Quizno), quote(UserID)))