1

问题

我使用带有变量 @myVar 的本机函数 FIND_IN_SET 作为字符串列表,例如:

FIND_IN_SET(col, @myVar)

如果我从直接值设置 @myVar

SET @myVAr = 'one,two,three';
... FIND_IN_SET(col, @myVar)

=> 效果很好

如果我从一个函数中设置@myVar,该函数从表的一列返回连接值

SET @myVAr = '';
SELECT @myVAr := getStringOfValues();
... FIND_IN_SET(col, @myVar)

=> 我得到Erreur SQL (1267) : Illegal mix of collat​​ions (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation 'find_in_set'

那么,我要摆脱这个错误吗?

请务必注意,我不想更改表格的排序规则。我希望我可以更改变量的排序规则,使其与我的列的排序规则相匹配,但我不能在初始化期间使用关键字“COLLATE”强制它:

SET @myVar= '' COLLATE utf8_unicode_ci;

=> 我得到Erreur SQL (1253) : COLLATION 'utf8_unicode_ci' is not valid for CHARACTER SET 'utf8mb4'


有用信息

我所有的表及其列都有排序规则 utf8_unicode_ci

SHOW VARIABLES LIKE '%char%'

character_set_client = utf8mb4

character_set_connection = utf8mb4

character_set_database = utf8

character_set_filesystem = 二进制

character_set_results = utf8mb4

character_set_server = latin1

character_set_system = utf8

SHOW VARIABLES LIKE 'coll%'

collat​​ion_connection = utf8mb4_general_ci

collat​​ion_database = utf8_general_ci

collat​​ion_server = latin1_swedish_ci

SHOW CREATE FUNCTION getStringOfValues

character_set_client = utf8mb4

collat​​ion_connection = utf8m4_general_ci

数据库排序规则 = utf8_general_ci


SQL 代码(匿名和简化版)

-- Function to return as a string the result from a SELECT in my_table_1
DELIMITER $$
CREATE FUNCTION getStringOfValues()
    RETURNS TEXT

    -- Variables to build the string of values
    DECLARE curr_value VARCHAR(255) DEFAULT '';
    DECLARE string_of_values TEXT DEFAULT '';

    -- Variables to enter and exit the loop over values
    DECLARE done INT DEFAULT 0;
    DECLARE my_cursor CURSOR FOR SELECT col FROM my_table_1;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    OPEN my_cursor;
        my_loop:LOOP
            FETCH my_cursor INTO curr_value;
            IF done THEN
              LEAVE my_loop;
            ELSE
                SET string_of_values = CONCAT(curr_value, ',', string_of_values);
            END IF;
        END LOOP;
    CLOSE my_cursor;

    -- Remove the trailing comma and quote the string. Result in something like 'one,two,three'
    RETURN QUOTE(TRIM(TRAILING ',' FROM string_of_values));
$$
DELIMITER ;

SET @myVAr = 'one,two,three';
-- The statement below will WORK
SELECT * FROM my_table_2 WHERE FIND_IN_SET(col, @myVAr);

SELECT @myVAr := getStringOfValues();
-- The statement below will NOT WORK as there is a 'Illegal mix of collations'
SELECT * FROM my_table_2 WHERE FIND_IN_SET(col, @myVAr);
4

0 回答 0