You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python脚本调用MySQL存储过程报ERROR 1064语法错误如何解决

问题根因

这个报错由两个问题共同导致:

  1. callproc方法传参格式错误:mysql.connector的cursor.callproc()不支持直接在存储过程名称中加库名.过程名的点分格式。驱动内部会基于传入的过程名生成临时用户变量传递参数,写path.proc1时会生成@path.proc1_arg1这类带点的非法变量名,直接触发SQL 1064语法错误,和报错提示中.proc1_arg1附近语法错误完全对应。
  2. 存储过程定义缺失入参:存储过程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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 13:06:21