Python执行MySQL多语句计算外汇交叉汇率报错,如何解决?
问题原因与解决方案
问题根源
你执行的SQL语句包含多条用分号分隔的指令(SET + SELECT组合),而mysql.connector的execute()方法默认不允许一次性执行多条语句——这是出于SQL注入防护的设计。当你未显式声明允许多语句执行时,就会抛出InterfaceError: Use multi=True when executing multiple statements错误。
另外你的代码还有两个小问题:
- 循环变量重复使用了
x,会导致外层循环的变量被内层覆盖; - 用字符串格式化拼接SQL存在SQL注入风险,不建议直接这么写。
解决方案
1. 显式指定multi=True执行多语句
修改execute()方法,添加multi=True参数,同时注意遍历多语句的结果集:
# 建议把变量名dict改成更有意义的名字,比如pair_mapping pair_mapping = {'a' : ['f','g'] , 'b' : ['f','k'] , 'c' : ['h','l'] , 'd': ['h','i'] , 'e': ['b','k'] } for new_pair, base_pairs in pair_mapping.items(): sql = f""" SET @Rate1 = (SELECT `Rate` FROM `param_forex` WHERE `Ticker` LIKE '{base_pairs[0]}'); SET @Rate2 = (SELECT `Rate` FROM `param_forex` WHERE `Ticker` LIKE '{base_pairs[1]}'); SET @Rate3 = @Rate1 / @Rate2; SELECT @Rate3; """ # 执行多语句必须指定multi=True results = mycursor.execute(sql, multi=True) # 遍历每个语句的执行结果 for res in results: # 只处理有返回数据的结果(即最后的SELECT语句) if res.with_rows: for row in res: print(f"货币对{new_pair}的计算汇率: {row[0]}")
2. 优化:用参数化查询避免SQL注入
上面的字符串拼接写法存在注入风险,建议改用参数化查询:
pair_mapping = {'a' : ['f','g'] , 'b' : ['f','k'] , 'c' : ['h','l'] , 'd': ['h','i'] , 'e': ['b','k'] } for new_pair, base_pairs in pair_mapping.items(): sql = """ SET @Rate1 = (SELECT `Rate` FROM `param_forex` WHERE `Ticker` LIKE %s); SET @Rate2 = (SELECT `Rate` FROM `param_forex` WHERE `Ticker` LIKE %s); SET @Rate3 = @Rate1 / @Rate2; SELECT @Rate3; """ # 传入参数,避免SQL注入 results = mycursor.execute(sql, (base_pairs[0], base_pairs[1]), multi=True) for res in results: if res.with_rows: row = res.fetchone() print(f"货币对{new_pair}的计算汇率: {row[0]}")
3. 更高效:合并为单条SQL语句
其实不需要拆分多条SET语句,可以直接在一个SELECT里完成计算,这样无需multi=True,代码更简洁高效:
pair_mapping = {'a' : ['f','g'] , 'b' : ['f','k'] , 'c' : ['h','l'] , 'd': ['h','i'] , 'e': ['b','k'] } for new_pair, base_pairs in pair_mapping.items(): sql = """ SELECT (SELECT `Rate` FROM `param_forex` WHERE `Ticker` LIKE %s) / (SELECT `Rate` FROM `param_forex` WHERE `Ticker` LIKE %s) AS CalculatedRate; """ mycursor.execute(sql, (base_pairs[0], base_pairs[1])) row = mycursor.fetchone() print(f"货币对{new_pair}的计算汇率: {row[0]}")
内容的提问来源于stack exchange,提问作者Mat
相关产品推荐
相关产品推荐

