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

MySQL存储过程中JSON_TABLE首次运行正常,后续执行失效求助

问题

在MySQL 8.0.12环境下,两个包含JSON_TABLE的存储过程出现异常:首次执行结果正常,但后续执行返回null且无任何报错;重新编辑并保存存储过程后,首次执行又恢复正常,但后续执行依旧失效。将存储过程内的SQL语句直接放到查询窗口中,却可以反复正常运行,已确认问题与JSON_TABLE的使用相关。

涉及的存储过程代码如下:

CREATE DEFINER=`username`@`%` PROCEDURE `sp_filter_values_add`(_dashboard_filter_id int(11))
BEGIN

insert into us_ui_dashboard_filter_values (dashboard_filter_id,  
                    section_id, 
                    section_item_id, 
                    filter_value, 
                    filter_value_text )
        
        select  dt.dashboard_filter_id, 
                x1.section_id, 
                x1.section_item_id, 
                x1.filter_value, 
                x1.filter_value_text
        from    us_ui_dashboard_filter dt,
            json_table( dt.filter_json, '$[*]' columns (
                section_id int(11) PATH '$.section_id',
                section_item_id int(11) PATH '$.section_item_id',
                filter_value int(11) PATH '$.filter_value',
                filter_value_text int(11) PATH '$.filter_value_text'
                                )
                ) x1   
        WHERE dt.dashboard_filter_id = _dashboard_filter_id; 
END
解决方向与替代方案

1. 强制JSON重新解析,绕过缓存

修改JSON_TABLE的输入参数,对dt.filter_json做显式的JSON类型转换,避免优化器缓存旧的解析结果:

json_table( CAST(dt.filter_json AS JSON), '$[*]' columns (
    section_id int(11) PATH '$.section_id',
    section_item_id int(11) PATH '$.section_item_id',
    filter_value int(11) PATH '$.filter_value',
    filter_value_text int(11) PATH '$.filter_value_text'
) ) x1

2. 关闭派生表合并优化

在存储过程的BEGIN之后添加语句,临时关闭当前会话的派生表合并优化,防止优化器错误缓存JSON_TABLE的执行逻辑:

SET SESSION optimizer_switch='derived_merge=off';

注意:该设置仅对当前会话有效,不会影响全局配置。

3. 升级MySQL版本

MySQL 8.0.12属于早期版本,存在JSON_TABLE在存储过程中执行计划缓存的已知bug,后续版本(如8.0.18及以上)已修复该问题。升级到稳定的高版本可彻底解决此异常。

4. 替代方案:拆分逻辑

如果暂时无法升级或修改优化器配置,可以将JSON_TABLE的解析逻辑拆分为临时表操作:

  1. 先将目标行的filter_json字段值取出,存入变量
  2. 再用JSON_TABLE解析变量中的JSON数据,插入目标表
    示例代码:
CREATE DEFINER=`username`@`%` PROCEDURE `sp_filter_values_add`(_dashboard_filter_id int(11))
BEGIN
    DECLARE _filter_json JSON;
    -- 取出目标JSON数据
    SELECT filter_json INTO _filter_json FROM us_ui_dashboard_filter WHERE dashboard_filter_id = _dashboard_filter_id;
    
    insert into us_ui_dashboard_filter_values (dashboard_filter_id,  
                        section_id, 
                        section_item_id, 
                        filter_value, 
                        filter_value_text )
            select  _dashboard_filter_id, 
                    x1.section_id, 
                    x1.section_item_id, 
                    x1.filter_value, 
                    x1.filter_value_text
            from    json_table( _filter_json, '$[*]' columns (
                        section_id int(11) PATH '$.section_id',
                        section_item_id int(11) PATH '$.section_item_id',
                        filter_value int(11) PATH '$.filter_value',
                        filter_value_text int(11) PATH '$.filter_value_text'
                                        )
                    ) x1; 
END

内容的提问来源于stack exchange,提问作者Lexius

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 11:30:57