动态 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 语句的主要内容,如果未能解决你的问题,请参考以下文章

mysql批量修改字段动态内容的sql语句怎么写

PHP - 为 mysql 生成动态 IF 语句

MySQL基础----动态SQL语句

PostgreSQL 动态SQL语句怎么写

带有 sql 转义的动态 mysql 查询是不是与准备好的语句一样安全?

MySQL存储过程中实现执行动态SQL语句