【问题标题】:Selecting strings from a column where some are utf8 encoded and others are not从其中一些是 utf8 编码而另一些不是的列中选择字符串
【发布时间】:2019-08-03 04:19:17
【问题描述】:

数据是国家/地区细分的名称。有些已存储为 utf8,有些则不是。 例如,它们在我的表中是这样的:

statename

Bocas del Toro
Chiriquí
Coclé
Colón
Darién
Veraguas
Panamá Oeste
Emberá
Kuna Yala
Ngöbe-Buglé

这个问题/答案让我非常接近解决方案: How to fix double-encoded UTF8 characters (in an utf-8 table)

如果我使用: CONVERT(CAST(CONVERT(statename USING latin1) AS BINARY) USING utf8):

statename

Bocas del Toro
Chiriquí
Coclé
Col
Dari
Veraguas
Panam
Emberá
Kuna Yala
Ng

例如,存储为“é”的字符,只是结束字符串。

该答案中提供的变体,

SELECT CASE
    WHEN CONVERT( CAST( CONVERT( statename USING latin1 ) AS BINARY ) USING utf8 ) IS NULL
        THEN statename
    ELSE CONVERT( CAST( CONVERT( statename USING latin1 ) AS BINARY ) USING utf8 )
END
FROM 

返回了相同的结果,虽然我什至不确定我在这个选择中正确地实现了它。

在这种情况下我不允许对这些数据进行标准化,所以我想选择它并获取

Bocas del Toro
Chiriquí
Coclé
Colón
Darién
Veraguas
Panamá Oeste
Emberá
Kuna Yala
Ngöbe-Buglé

这可能吗?

【问题讨论】:

  • 您确定表中的(拉丁)字符串尚未被截断吗?
  • 是的,我确实可以访问该表,并且它们在此处显示为“Ngöbe-Buglé”,例如。
  • 你的服务器版本是多少?它似乎适用于 5.7 但不适用于 5.6 - db-fiddle.com/f/2zp8NAior1JKo3HzbmYoei/0
  • 服务器版本是5.1.73 :(
  • 在执行语句之前尝试更改 sql_mode:set session sql_mode = concat('STRICT_TRANS_TABLES,', @@sql_mode);

标签: mysql utf-8


【解决方案1】:

这似乎是SQL_MODE 的问题。为了使转换失败并返回 NULL - STRICT_TRANS_TABLES 必须设置模式。您可以使用

进行设置
SET SESSION sql_mode = CONCAT('STRICT_TRANS_TABLES,', @@sql_mode);

如果您不想在同一会话中中断其他“工作”查询,则应在获得结果后将其重置:

SET @old_sql_mode = @@sql_mode;
SET SESSION sql_mode = CONCAT('STRICT_TRANS_TABLES,', @@sql_mode);

SELECT COALESCE(
  CONVERT( CAST( CONVERT( statename USING latin1 ) AS BINARY ) USING utf8 ), statename
) as statename
FROM yourTable;

SET SESSION sql_mode = @old_sql_mode;

DB Fiddle demo

注意:我已将您的查询稍作更改以使用 COALESCE() 而不是 CASE 语句,因此您无需复制转换代码。

【讨论】:

    猜你喜欢
    • 2013-12-03
    • 2012-02-04
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 2014-06-21
    • 2021-05-18
    • 1970-01-01
    • 2018-06-08
    相关资源
    最近更新 更多