我目前正在使用mysql-connector-python包在Flask上执行数据库操作。一直运行得很好,直到突然之间变量似乎不再正常工作为止。我的代码在这里:
@bp.route('/addcart', methods=('OPTIONS', 'POST'))
def addcart():
...
userID = session.get("user_id")
reqDict = request.get_json()
itemCode = str(reqDict['itemCode'])
itemAmt = reqDict['itemAmt']
if userID is not None:
db = get_db()
cursor = db.cursor()
query = ('SELECT %s FROM cartdata WHERE id = %s')
cursor.execute(query, (itemCode, userID))
currentNum = cursor.fetchone()[0]
if currentNum is None:
stmt = ('UPDATE cartdata SET %s = 1 WHERE id = %s')
cursor.execute(stmt, (itemCode, userID))
else:
currentNum = int(currentNum) + int(itemAmt)
stmt = ('UPDATE cartdata SET %s = %s WHERE id = %s')
cursor.execute(stmt, (itemCode, currentNum, userID))
....
由于某种原因,我似乎在itemCode变量上遇到了麻烦。当我正确使用它时,例如在执行“查询”或“ stmt”时,它不起作用。通常情况下,我会说
“您的SQL语法有误;请查看 对应于您的MySQL服务器版本以使用正确的语法 靠近“ p1” = 1 WHERE id = 21'”。
但是,如果我这样做:
query = ('SELECT ' + itemCode + ' FROM cartdata WHERE id = %s')
...
stmt = ('UPDATE cartdata SET '+ itemCode +' = 1 WHERE id = %s')
...
它可以按预期正常工作。
编辑:我已经检查了后端,并且显然UPDATE语句实际上并未更新任何内容。所以现在我完全不知所措。
我不明白为什么连接器现在突然因变量而中断。我已经检查了此变量及其类型,但是它们是预期的类型。任何见解都会有所帮助。
我的'cartdata'表结构如下所示:
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| p1 | int(8) | YES | | NULL | |
| p2 | int(8) | YES | | NULL | |
| p3 | int(8) | YES | | NULL | |
| p4 | int(8) | YES | | NULL | |
| p5 | int(8) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
答案 0 :(得分:1)
这是因为,当MySQL连接器将变量注入SQL语句时,它将根据其类型设置其格式。
您实际上可以在收到的错误消息中看到它:
"p1' = 1 WHERE id = 21'"
^
因此,您的SQL查询可能如下所示:
SELECT 'p1' FROM cartdata WHERE id = someId
哪个在语法上是无效的SQL ...
您的第二个选择似乎还可以。顺便说一句,根据用户的输入来调整要选择的列似乎很奇怪。我强烈建议您使用有效的方法来验证该值。
您不能使用%s
作为列名,因为这会在SQL查询中注入字符串值,并且会导致SQL语法无效(列名不是字符串值)。 / p>
如上所述:
SET %s = ...
生成:
SET 'colName' = ...
这无效,因为您正尝试将一个值影响为另一个值...
这与尝试在python中执行以下操作相同:
'foo' = 'bar'
或
'foo' = 4
设置值(使用%s
)或过滤值(使用SET colName = %s
)时,可以使用WHERE colName = %s
,因为列colName
中的值类型实际上是字符串。
如上所述:
WHERE colName = %s
生成:
WHERE colName = 'fooBar'
之所以有效,是因为您过滤了等于字符串fooBar
的值。
顺便说一句,您可能想检查一下
SELECT %s FROM cartdata WHERE id = %s
因此给您。这可能会导致问题...实际上,MySQL不会告诉您任何信息,但您得到的结果可能恰好是itemCode
的值。 (这是有效的SQL SELECT 'hello'
,只返回'hello'
)。