Python MySQL语句返回错误

3 投票
3 回答
8428 浏览
提问于 2025-04-11 20:08

嘿,我对这些东西很陌生,所以请原谅我的无知 :)

import os
import MySQLdb
import time

db = MySQLdb.connect(host="localhost", user="root", passwd="********", db="workspace")
cursor = db.cursor()

tailoutputfile = os.popen('tail -f syslog.log')
while 1:
        x = tailoutputfile.readline()  
        if len(x)==0:
                break
        y = x.split()
        if y[2] == 'BAD':
                timestring = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
                cursor.execute("INSERT INTO releases (date, cat, name) values (timestring, y[4], y[7]")
        if y[2] == 'GOOD':
                print y[4] + '\t' + y[7]

我运行程序时,出现了这个错误信息

user@machine:~/$ python reader.py
Traceback (most recent call last):
  File "reader.py", line 17, in ?
    cursor.execute("INSERT INTO releases (date, cat, name) values (timestring, y[4], y[7]")
  File "/usr/lib/python2.4/site-packages/MySQLdb/cursors.py", line 163, in execute
    self.errorhandler(self, exc, value)
  File "/usr/lib/python2.4/site-packages/MySQLdb/connections.py", line 35, in defaulterrorhandler
    raise errorclass, errorvalue
_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to                                                              your MySQL server version for the right syntax to use near '[4], y[7]' at line 1")
user@machine:~/$

所以我猜这个错误肯定是来自SQL语句

cursor.execute("INSERT INTO releases (date, cat, name) values (timestring, y[4], y[7]")

这里是y[4]和y[7]的一个例子。

YES      Mail.Sent.To.User:user@work.com.11.2.2008:23.17

这个错误是因为我在尝试把这些值插入数据库之前应该先对它们进行处理吗?还是说我完全理解错了??

任何帮助都非常感谢!提前谢谢你们。

3 个回答

1

绝对不要在SQL中直接拼接字符串,因为这样不安全。更好的做法是:

cursor.execute('INSERT INTO releases (date, cat, name) VALUES (%s, %s, %s)', (timestring, y[4], y[7]))

这样做可以自动处理掉一些不允许的符号,比如双引号、单引号等。

4
 cursor.execute("INSERT INTO releases (date, cat, name) values (timestring, y[4], y[7]")

应该是

 cursor.execute("INSERT INTO releases (date, cat, name) values (timestring, '%s', '%s')" % (y[4], y[7]))

调试这种问题的最好办法是把查询放到一个变量里,然后使用这个变量:

query = "INSERT INTO releases (date, cat, name) values (timestring, '%s', '%s')" % (y[4], y[7])
print query
cursor.execute(query)

这个打印语句会让问题变得非常明显。

如果你经常使用列表变量,这可能会让人感到困惑,建议只使用一次列表,然后把变量放到一个字典里。这样虽然输入的内容会多一些,但更容易理解和管理发生了什么。

10

正如所提到的,你没有把Python变量的值复制到查询中,而只是复制了它们的名字,这对MySQL来说是没有意义的。

不过,直接把字符串拼接在一起的方法:

cursor.execute("INSERT INTO releases (date, cat, name) VALUES ('%s', '%s', '%s')" % (timestring, y[4], y[7]))

是很危险的,绝对不应该使用。如果这些字符串中有像'或者\这样的特殊字符,就会导致SQL注入,这可能会让你的系统面临安全风险。也许在你的应用中这种情况不会发生,但这仍然是一种非常糟糕的做法,初学者的SQL教程真的应该停止使用这种方法。

使用MySQLdb的解决方案是让数据库API层来处理参数值的插入和转义,而不是自己去拼接这些值:

cursor.execute('INSERT INTO releases (date, cat, name) VALUES (%s, %s, %s)', (timestring, y[4], y[7]))

撰写回答