动态 mySQL 语句
Posted
技术标签:
【中文标题】动态 mySQL 语句【英文标题】:Dynamic mySQL Statement 【发布时间】:2021-07-12 23:15:00 【问题描述】:我正在尝试创建一个动态的 mysql 更新语句。如果字符串中有某些字符,我的更新将失败。
import mysql.connector as sql
import MySQLdb
#Values are taken from a wxGrid.
key_id = str("'") + str(self.GetCellValue(event.GetRow(),1)) + str("'") #Cell column with unique ID
target_col = str(self.GetColLabelValue(event.GetCol())) #Column being updated
key_col = str(self.GetColLabelValue(1)) #Unique ID column
nVal = str("'")+self.GetCellValue(event.GetRow(),event.GetCol()) + str("'") #Updated value
sql_update = f"""Update tbl set target_col = nVal where key_col = key_id"""
self.cursor.execute(sql_update)
我的密钥列始终包含电子邮件地址或整数。所以如果key_id = test@email.com
,更新成功,如果key_id = t'est@email.com
,更新失败。我该如何解决这个问题?
【问题讨论】:
使用来自用户输入的文字构建整个 SQL 字符串会带来很高的data loss 风险。您需要使用准备好的语句和绑定变量,这不仅仅是文本替换,而是数据。 同意。也许您可以在提交值之前评估字符串并进行清理或异常处理.. 【参考方案1】:您可以使用查询参数来解决此问题。停止将字符串连接到 SQL 查询中。使用占位符,然后将单独列表参数中的值传递给execute()
。
sql_update = f"""Update tbl set target_col = %s where key_col = %s"""
self.cursor.execute(sql_update, (nVal, key_id,))
查询参数仅适用于在查询中使用文字值的情况,例如带引号的字符串文字或数字文字。
您不能将查询参数用于表名或列名等标识符。但我希望您的标识符不太可能包含'
字符!
同样,您不能将查询参数用于表达式或 SQL 关键字或值列表,例如对于IN()
谓词。一个查询参数 = 一个标量值。
另见:
MySQL parameterized queries https://dev.mysql.com/doc/connector-python/en/connector-python-example-cursor-transaction.html 几乎所有其他 Python SQL 教程。【讨论】:
【参考方案2】:改用execute
函数。
不推荐的解决方案:单引号文字的解决方法是用转义字符替换;就在查询key_id.replace("'", "\'")
之前。您可能必须为每个特殊字符(如 %、 、 _ 和 [)执行此操作。
【讨论】:
以上是关于动态 mySQL 语句的主要内容,如果未能解决你的问题,请参考以下文章