我正在尝试将列表中的某些值传递给insert语句,并认为它会很简单,但我发现自己浪费了太多时间:
请有人解释一下这里出了什么问题吗?
cursor=db.cursor()
cursor.execute(" INSERT INTO a (a,b) VALUES (%s,%s)", ('abc', 'abc'))
db.commit()
cursor.close()
output = ('abc','abc')
output_insert = str(output)
cursor=db.cursor()
sql = '" INSERT INTO a (a,b) VALUES (%s,%s)",' + output_insert
cursor.execute(sql)
db.commit()
cursor.close()
如果我打印了sencond语句,我可以看到它与第一个失败的语句相同:
print sql
"插入(a,b)值(%s,%s)",(' abc',' abc')
同样如下:
"插入(a,b)值(%s,%s)",(' abc',' abc')
返回的错误是:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 174, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, 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 \'" INSERT INTO a (a,b) VALUES (%s,%s)",(\'abc\', \'abc\')\' at line 1')
谢谢!
答案 0 :(得分:1)
不要使用字符串插值或字符串格式来创建SQL查询。您正在使代码容易受到SQL injection攻击并获得类型转换和引用处理问题(因为您可以已经看到)。
相反,参数化您的查询。查询参数应作为单独的参数传递给execute()
:
output = ('abc','abc')
sql = """
INSERT INTO
a
(a, b)
VALUES
(%s, %s)"""
cursor.execute(sql, output)
答案 1 :(得分:-1)
如果您打印{mys}的sql
:
" INSERT INTO a (a,b) VALUES (%s,%s)",('abc', 'abc')
它不是MySQL的正确sql,所以你有错误。
或者您可以使用字符串格式方法格式化sql,例如:
cursor=db.cursor()
vars_sql = ('abc', 'abc')
sql_format = "INSERT INTO a (a,b) VALUES ('{0}','{1}')"
real_sql = sql_format.format(*vars_sql)
# print out see if sql is correct
print real_sql
# not use format string avoid dangerous
cursor.execute("INSERT INTO a (a,b) VALUES ('%s','%s')", ('abc', 'abc'))
db.commit()
cursor.close()
通过这种方式,您可以打印出真正的sql并在MySQL中执行以查看sql是否有任何问题。