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

调用带命名参数的MySQL 8存储过程时排序规则冲突问题解决

解决MySQL 8存储过程调用时的排序规则冲突错误

问题场景

创建了带多个命名参数的MySQL 8存储过程,调用时触发排序规则冲突错误:

[HY000][1267] Illegal mix of collations (utf8mb4_unicode_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,IMPLICIT) for operation '='

已尝试重建数据库并设为utf8mb4_unicode_ci、修改@@local.collation_server后重建存储过程等操作,但仍报错。

存储过程创建代码:

create definer = lardev@localhost procedure sp_getFilteredProductsWithDiscounts(IN in_status varchar(1), IN in_discountPriceAllowed tinyint unsigned, IN in_in_stock varchar(1), IN in_stock_qty mediumint, IN in_discounts_qty mediumint)
BEGIN
SELECT products.id, products.title, products.sale_price,
    GROUP_CONCAT(CONCAT(discounts.name, ': ', discounts.min_qty, ': ', discounts.max_qty, ': ', discounts.percent)) AS discount_info
FROM products
    LEFT JOIN discount_product ON discount_product.product_id = products.id
    LEFT JOIN discounts on discounts.id = discount_product.discount_id
    WHERE ( products.status = in_status OR ISNULL(in_status) ) AND
      ( products.discount_price_allowed = in_discountPriceAllowed OR ISNULL(in_discountPriceAllowed)) AND
      ( products.in_stock = 1 OR ISNULL(in_in_stock) ) AND
      ( products.stock_qty >= in_stock_qty OR ISNULL(in_stock_qty) ) AND
      ( in_discounts_qty BETWEEN discounts.min_qty  AND discounts.max_qty OR ISNULL(in_discounts_qty))
    GROUP BY products.id, products.title, products.sale_price;
END;

调用语句:

CALL sp_getFilteredProductsWithDiscounts(@in_status := 'A', @in_discountPriceAllowed := 1, @in_in_stock := 1, @in_stock_qty := 2, @in_discounts_qty := 3 );

解决方法

冲突根源是字符串类型的存储过程参数(in_status、in_in_stock)继承了MySQL 8默认的utf8mb4_0900_ai_ci排序规则,和表字段的utf8mb4_unicode_ci不匹配,可通过以下方式解决:

1. 显式指定存储过程参数的排序规则

修改存储过程定义,给字符串参数加上COLLATE utf8mb4_unicode_ci,确保和表字段排序规则一致:

create definer = lardev@localhost procedure sp_getFilteredProductsWithDiscounts(
    IN in_status varchar(1) COLLATE utf8mb4_unicode_ci, 
    IN in_discountPriceAllowed tinyint unsigned, 
    IN in_in_stock varchar(1) COLLATE utf8mb4_unicode_ci, 
    IN in_stock_qty mediumint, 
    IN in_discounts_qty mediumint
)
BEGIN
SELECT products.id, products.title, products.sale_price,
    GROUP_CONCAT(CONCAT(discounts.name, ': ', discounts.min_qty, ': ', discounts.max_qty, ': ', discounts.percent)) AS discount_info
FROM products
    LEFT JOIN discount_product ON discount_product.product_id = products.id
    LEFT JOIN discounts on discounts.id = discount_product.discount_id
    WHERE ( products.status = in_status OR ISNULL(in_status) ) AND
      ( products.discount_price_allowed = in_discountPriceAllowed OR ISNULL(in_discountPriceAllowed)) AND
      ( products.in_stock = 1 OR ISNULL(in_in_stock) ) AND
      ( products.stock_qty >= in_stock_qty OR ISNULL(in_stock_qty) ) AND
      ( in_discounts_qty BETWEEN discounts.min_qty  AND discounts.max_qty OR ISNULL(in_discounts_qty))
    GROUP BY products.id, products.title, products.sale_price;
END;

2. 调用时给参数指定排序规则

如果不想修改存储过程,可在调用时为字符串参数显式指定排序规则:

CALL sp_getFilteredProductsWithDiscounts(
    @in_status := 'A' COLLATE utf8mb4_unicode_ci, 
    @in_discountPriceAllowed := 1, 
    @in_in_stock := '1' COLLATE utf8mb4_unicode_ci, 
    @in_stock_qty := 2, 
    @in_discounts_qty := 3 
);

3. 全局统一排序规则

修改MySQL配置文件(my.cnf/my.ini),设置全局默认排序规则:

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

保存后重启MySQL服务,然后重新创建存储过程,确保所有表、字段的排序规则也统一为utf8mb4_unicode_ci。

验证

完成上述操作后,重新调用存储过程,即可解决排序规则冲突问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 06:12:02