如何在 MySQL 中将字符串修剪为某个字节长度?

问题描述

我有一个包含 253 个字符的字符串,但由于某些字符长于一个字节(在本例中,它包含多个零宽度空格)而占用了 261 个字节。

我想将此字符串插入到 VARCHAR(255) 表中的 utf8mb4 列中,但它抛出此错误:

INSERT INTO mytable(mycolumn) VALUES("This string contains 253 ​characters which should ​fit inside of a varchar(255) column,but because ​of the zero width spaces,it takes up more than 255 bytes and therefore throws an error when you try to insert it into the table and that makes me ​sad.")

/*Error 1406: Data too long for column*/

以下是两个长度函数输出的示例:

/* Returns 253 */
SELECT CHAR_LENGTH("This string contains 253 ​characters which should ​fit inside of a varchar(255) column,it takes up more than 255 bytes and therefore throws an error when you try to insert it into the table and that makes me ​sad.");

/* Returns 261 */
SELECT LENGTH("This string contains 253 ​characters which should ​fit inside of a varchar(255) column,it takes up more than 255 bytes and therefore throws an error when you try to insert it into the table and that makes me ​sad.");

为了解决这个问题,我需要修剪足够的字符以使字符串在字节限制内。

不幸的是,LEFT() 函数似乎不适合于此:

/* Still returns 261 because it counts characters,not bytes */
SELECT LENGTH(LEFT("This string contains 253 ​characters which should ​fit inside of a varchar(255) column,it takes up more than 255 bytes and therefore throws an error when you try to insert it into the table and that makes me ​sad.",255));

那么,我该如何修剪字符串?

解决方法

一种解决方法是使用另一种语言提前处理字符串。

例如,以下是 Python 中的可行解决方案:

def trim_string_to_x_bytes(string,max_bytes,character_encoding):
    string = string[:max_bytes]
    
    while (len(string.encode(character_encoding)) > max_bytes):
        string = string[:-1]
    
    return string

long_string = "This string contains 253 ​characters which should ​fit inside of a varchar(255) column,but because ​of the zero width spaces,it takes up more than 255 bytes and therefore throws an error when you try to insert it into the table and that makes me ​sad."

long_string = trim_string_to_x_bytes(long_string,255,'utf8')

cursor.execute("INSERT INTO mytable(mycolumn) VALUES(%s)",(long_string,))

也就是说,如果存在纯 MySQL 解决方案会更好。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...