[英]“Unknown column in 'where clause'” when executing stored procedure from python
我正在尝试使用 python 在 mysql 中创建和执行存储过程。
我从中读取的表格如下所示:
这是用于创建 proc 的命令,运行良好:
new_conn = engine.raw_connection()
mycursor = new_conn.cursor()
mycursor.execute('''CREATE PROCEDURE getAvgPerCity
(
IN city VARCHAR(64),
IN des_table VARCHAR(255)
)
BEGIN
SET @Sql = CONCAT('INSERT INTO ',des_table,'(location,avg_value,insert_time)
select location,avg_per_city, NOW() AS insert_time from
(
select location,avg(total) as avg_per_city from
(
select location,date(risetime) as dt_day,count(*) as total
from
orbital_data
group by location,dt_day
) as q1
group by location) as q2
WHERE location = ',city,';');
PREPARE stmt FROM @Sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END ''')
然后,我调用该程序:
args = ['Haifa', 'city_stats_Haifa']
mycursor.callproc('getAvgPerCity', args)
然后代码崩溃并出现以下错误:
<MySQLdb._exceptions.OperationalError:(1054,“'where 子句'中的未知列'Haifa'”)>
所有列名都是原始名称,没有别名。 我究竟做错了什么?
如评论中所述,您在 SQL 中缺少城市周围的报价。 但不是添加引号,您应该使语句带一个参数,以避免 SQL 注入。
new_conn = engine.raw_connection()
mycursor = new_conn.cursor()
mycursor.execute('''
CREATE PROCEDURE getAvgPerCity
(
IN city VARCHAR(64),
IN des_table VARCHAR(255)
)
BEGIN
SET @city = city;
SET @Sql = CONCAT('INSERT INTO `',des_table,'` (location,avg_value,insert_time)
select location,avg_per_city, NOW() AS insert_time from (
select location,avg(total) as avg_per_city from (
select location,date(risetime) as dt_day,count(*) as total
from orbital_data
group by location,dt_day
) as q1
group by location) as q2
WHERE location = ?;');
PREPARE stmt FROM @Sql;
EXECUTE stmt USING @city;
DEALLOCATE PREPARE stmt;
END ''')
不幸的是,您不能为表名使用占位符。 你能做的最好的就是在它周围加上反引号,以防它包含特殊字符。
在城市名称周围使用双引号
new_conn = engine.raw_connection()
mycursor = new_conn.cursor()
mycursor.execute('''CREATE PROCEDURE getAvgPerCity
(
IN city VARCHAR(64),
IN des_table VARCHAR(255)
)
BEGIN
SET @Sql = CONCAT('INSERT INTO `',des_table,'`(location,avg_value,insert_time)
select location,avg_per_city, NOW() AS insert_time from
(
select location,avg(total) as avg_per_city from
(
select location,date(risetime) as dt_day,count(*) as total
from
orbital_data
group by location,dt_day
) as q1
group by location) as q2
WHERE location = "',city,'";');
PREPARE stmt FROM @Sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END ''')
如果未检查城市名称,这可能是 sql 注入的入口点,因此您可以使用带有 oarameters 的准备语句
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.