我试图在Python中使用带有预处理语句的SQL。 Python没有自己的机制,所以我尝试直接使用SQL:
sql = "PREPARE stmt FROM ' INSERT INTO {} (date, time, tag, power) VALUES (?, ?, ?, ?)'".format(self.db_scan_table)
self.cursor.execute(sql)
然后,在循环中:
sql = "EXECUTE stmt USING \'{}\', \'{}\', {}, {};".format(d, t, tag, power)
self.cursor.execute(sql)
在循环中我得到:
MySQL Error [1064]: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''2014-12-25', '12:31:46', 88000000, -6.64' at line 1
发生了什么?
答案 0 :(得分:7)
在http://zetcode.com/db/mysqlpython/中解释了在Python中使用带有MySQL的预准备语句 - 在Prepared statements
的页面中查看。
在你的情况下,那将是,例如:
sql = ('INSERT INTO {} (date, time, tag, power) VALUES '
'(%s, %s, %s, %s)'.format(self.db_scan_table))
以及稍后,“在循环中”,如你所说:
self.cursor.execute(sql, (d, t, tag, power))
没有进一步的字符串格式化 - MySQLdb
模块代表您执行准备和执行部分(并且可以缓存事物以避免不必要地重复工作等)。
根据你提到的“循环”的性质,请考虑一次调用.execute_many
(使用一系列元组作为第二个参数)可能取代整个循环(除非您需要在该循环内进行更多处理,而不仅仅是将数据插入数据库)。
补充:现在更好的替代方案可能是使用mysql自己的Connector/Python
以及prepare=True
工厂中的显式.cursor()
选项 - 请参阅http://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursorprepared.html。这使得您可以使用特定的游标来准备哪些语句(根据mysql.com页面,“比使用PREPARE和EXECUTE”二进制协议更有效),另一个用于更好未准备的语句; “明确比隐含更好”是在“禅宗的Python”中的所有原则之后(import this
从交互式提示阅读所有这些原则)。 mysqldb
隐式地做事(似乎当前的开源版本不使用预准备语句)不能像Connector/Python
更明确的架构一样好之一。
答案 1 :(得分:2)
Python支持预准备语句:
sql = "INSERT INTO {} (date, time, tag, power) VALUES (%s, %s, %s, %s);"
sql = sql.format(self.db_scan_table)
self.cursor.execute(sql, (d, t, tag, power))
(您应确保self.db_scan_table
不易受SQL注入攻击)
这假定您的paramstyle
为'format'
,should be for MySQL。
答案 2 :(得分:0)
import mysql.connector
db_con=mysql.connector.connect(host='',
database='',
user='',
password='')
cursor = db_con.cursor(prepared=True,)
#cursor = db_con.cursor(prepared=True)#IT MAY HAVE PROBLEM
sql = """INSERT INTO table (xy,zy) VALUES (%s, %s)"""
input=(1,2)
cursor.execute(sql , input)
db_con.commit()
选择STMT
sql = """SELECT * FROM TABLE WHERE XY=%s ORDER BY id DESC LIMIT 1 """
ID=1
input=(ID,)
#input=(ID)# IT MAY HAS PROBLEM
cursor.execute(sql, input)
data = cursor.fetchall()
rowsNumber=cursor.rowcount