Python实现含单引号值的SQL Insert语句及MySQL转MSSQL插入问题
解决MySQL迁移MSSQL时含单引号字段的Insert异常问题
兄弟,你这问题太典型了——直接拼接SQL语句的时候,字段里的单引号会把SQL的字符串边界搞乱,数据库引擎直接懵圈,自然就报错了。给你两种解决办法,优先用第一种,既安全又省心:
方案一:用参数化查询(强烈推荐)
别再手动拼SQL和字段值了!用数据库驱动自带的参数占位符,驱动会自动帮你处理单引号、特殊字符这些破事,还能防SQL注入,一举两得。
给你改改你的代码示例,照着来就行:
import pymssql import mysql.connector # 连接MSSQL mssql_conn = pymssql.connect(host='XXX', user='XXX', password='XXX', database='XXX') mssql_cursor = mssql_conn.cursor() # 连接MySQL mysql_conn = mysql.connector.connect(user='root', password='XXX', database='XXX') mysql_cursor = mysql_conn.cursor(dictionary=True) # 查出来的结果是字典,按字段名取数更方便 # 先获取MSSQL目标表的最大ID,过滤要迁移的增量数据(完善你的原逻辑) get_max_id_sql = "SELECT Max(ID) FROM XXX;" # 替换为你的目标表名 mssql_cursor.execute(get_max_id_sql) max_id_row = mssql_cursor.fetchone() max_id = max_id_row[0] if max_id_row[0] is not None else 0 # 处理空值情况 # 从MySQL捞取大于max_id的数据 fetch_data_sql = "SELECT ID, 字段1, 字段2 FROM XXX WHERE ID > %s;" # 替换为你的源表名 mysql_cursor.execute(fetch_data_sql, (max_id,)) data_rows = mysql_cursor.fetchall() # 参数化插入MSSQL,不用管单引号的事 insert_sql = "INSERT INTO XXX (ID, 字段1, 字段2) VALUES (%s, %s, %s);" # 替换为目标表名 for row in data_rows: # 直接把值丢进参数元组,驱动自动转义特殊字符 mssql_cursor.execute(insert_sql, (row['ID'], row['字段1'], row['字段2'])) # 提交事务,收尾关闭连接 mssql_conn.commit() mysql_cursor.close() mysql_conn.close() mssql_cursor.close() mssql_conn.close()
划重点:
- pymssql和mysql.connector都支持
%s作为参数占位符,不用改成MSSQL的@变量或者? - 绝对不要把字段值直接拼进SQL字符串里,把值放到
execute方法的第二个参数元组中即可 - 用
dictionary=True让MySQL返回字典格式的结果,按字段名取值比按索引更靠谱,不容易出错
方案二:手动转义单引号(万不得已才用)
要是实在没法用参数化查询,那只能手动把字段里的单引号替换成两个单引号——MSSQL里就是用两个单引号表示一个真实的单引号。示例如下:
# 比如从MySQL拿到的字段值是content raw_content = row['content'] # 转义单引号:把'变成'' escaped_content = raw_content.replace("'", "''") # 再拼接SQL(注意:这种方法存在SQL注入风险,别用于处理用户输入的不可信数据!) insert_sql = f"INSERT INTO XXX (content) VALUES ('{escaped_content}');" mssql_cursor.execute(insert_sql)
注意:
这种方法只是临时救急的方案,若字段值是不可信的用户输入,很容易被SQL注入攻击,所以能不用就不用。
最后记得迁移完成后要核对数据,确保带单引号的内容在MSSQL里和MySQL存储的完全一致哈!
内容的提问来源于stack exchange,提问作者Lemon
相关产品推荐
相关产品推荐

