Python脚本调用MySQL存储过程报ERROR 1064语法错误如何解决
问题根因
这个报错由两个问题共同导致:
callproc方法传参格式错误:mysql.connector的cursor.callproc()不支持直接在存储过程名称中加库名.过程名的点分格式。驱动内部会基于传入的过程名生成临时用户变量传递参数,写path.proc1时会生成@path.proc1_arg1这类带点的非法变量名,直接触发SQL 1064语法错误,和报错提示中.proc1_arg1附近语法错误完全对应。- 存储过程定义缺失入参:存储过程SQL中用了
ods_code_param变量做查询条件,但存储过程头部的参数列表根本没有声明这个入参,只定义了4个入参,和Python代码中传入的5个参数数量不匹配。在Workbench能运行是因为之前会话可能手动给@ods_code_param这个用户变量赋过值,属于不严谨的巧合情况,存储过程本身定义存在缺陷。
修复步骤
1. 修正存储过程定义
补全缺失的ods_code_param入参,修正后的存储过程代码如下:
CREATE PROCEDURE `proc1`( IN ods_code_param VARCHAR(255), -- 补全缺失的ODS编码入参,字段类型可根据实际表结构调整 IN weeks_history_param int, IN additional_weeks_param int, IN historic_run_param int, IN cv_folds_param int ) BEGIN -- 锚定最近的周日 set @latest_sun = DATE_SUB(DATE(NOW()), INTERVAL DAYOFWEEK(NOW())-1 DAY); select * from customer_prescribing.manual_prescription_data where ODS_Code = ods_code_param and Date between date_sub(@latest_sun, interval weeks_history_param + additional_weeks_param + historic_run_param + cv_folds_param week) and date_sub(@latest_sun, interval historic_run_param week); END
2. 修正Python调用代码
连接数据库时直接把DBNAME配置为存储过程所在的数据库名,调用callproc时只传存储过程名,不要带库名前缀:
import os import mysql.connector def data_ingestion(): conn = None cursor = None try: # 确保DBNAME填写的是proc1所属的数据库名 conn = mysql.connector.connect(host=ENDPOINT, user=USER, passwd=token, port=PORT, database=DBNAME) cursor = conn.cursor() # 参数顺序和存储过程定义的入参顺序一一对应即可 args = ("FF", 2, 2, 20, 3) # 不要写path.proc1,直接写过程名 result_args = cursor.callproc('proc1', args) for result in cursor.stored_results(): print(result.fetchall()) conn.commit() except mysql.connector.Error as error: print("Failed to execute stored procedure: {}".format(error)) finally: if conn and conn.is_connected(): if cursor: cursor.close() conn.close() print("MySQL connection is closed") if __name__ == "__main__": data_ingestion()
补充:如果确实需要跨库调用存储过程,不要在过程名里加库前缀,在建立连接后先执行
cursor.execute("USE 存储过程所属库名;")切换到对应库,再调用callproc('proc1', args)即可。
内容的提问来源于stack exchange,提问作者Andrei Tulbure
相关产品推荐
相关产品推荐

