utf-8 - 将 Firebird 字段/域从 ISO8859_1 转换为 UTF8

标签 utf-8 firebird firebird2.5

我通过谷歌做了一些研究,但找不到正确的答案。

我有一个 Firebird 数据库,我总是使用自己的域作为我的表字段。所有这些域都是用字符集 ISO8859_1 定义的。现在我想把它改成UTF8。
如果我在 IBExpert 中尝试此操作,它会给我带来以下代码:

ALTER DOMAIN D_CHAR100 TYPE VARCHAR(100) CHARACTER SET UTF8;

此更新有效。但它真的有效吗?所有字符都正确转换了吗,我现在是否已将我的字段更改为“真正的”UTF8??还是在内部保留为 ISO08859_1?

如果我在网上搜索,有人说:
  • 通过临时字段和处理所有数据的解决方案(大量使用大型数据库的工作)

  • 和其他人说:
  • 改变域或字段数据类型就足够了。

  • 什么是对的?什么可能出错?我们有很多客户,我想通过脚本转换数据库。

    最佳答案

    更改字段不会更改该字段内的任何数据。它将为您暴露许多问题。执行此操作的最佳方法是复制数据,但是您还有更多工作要做。

    以下是您将遇到的一些问题:

  • 任何使用此字段的存储过程/触发器都必须更新以使用较新的变量。
  • varchar(100) 字段在 ASCII 中最多可能占用 100 个字节,但在 UTF 中最多占用 400 个字节。因此,您的新 UTF 字段的大小最大为 8191。因此,无法转换超过此大小的任何 varchar 或 char 字段。
  • 即使将 varchar(100) 字段从 ASCII 转换为 UTF,您仍然可以破坏选择语句,因为 Firebird 对行有 64KB 的限制。您将这些字段的数据大小增加了四倍。
  • 如果您有超过 127 个 ASCII 值的任何字符,则结果列将不可选。像这样的字符将包括二分之一字符:½。它的值是 171,当被告知是 UTF8 时会中断。

  • 试试这两个语句:
    select cast('½' as varchar(10) character set ISO8859_1)
    from rdb$database
    
    select cast('½' as varchar(10) character set UTF8)
    from rdb$database
    

    第一个有效,第二个无效。

    最后,简单地更改字段将暴露上述四个问题,但是直到遇到它们你才会知道它们存在,在复杂的数据库中可能直到生产级用户遇到它们才知道它们存在。同时复制数据将为您自己带来更多的工作,但将使您能够正确处理上述所有项目。

    还有两点需要注意:
  • 如果您复制数据,您将收到 #4 的错误。相反,您应该根据需要清理这些数据,并使用可以正确转换这些值的外部应用程序执行此操作。 ASCII 171 = UTF 189 = 1/2 字符。
  • 任何针对这些字段执行语句的应用程序代码仍可能违反问题 #3 的 64KB 规则。您至少需要搜索所有较大的字段或语句,以确保不会遇到此问题。
  • 关于utf-8 - 将 Firebird 字段/域从 ISO8859_1 转换为 UTF8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22632768/

    相关文章:

    Java JDBC 类型转换(Firebird/Jaybird): check value/type compatibility before using getter or updater ResultSet method?

    c# - 使用 Entity Framework 插入时有条件地设置 Identity 字段

    firebird - 将 LAN 上的事件与 SuperClassic 结合使用?

    sql - 如何连接表并根据条件选择重复项

    visual-studio-2010 - 无法将 Firebird DDEX .NET 提供程序集成与 Visual Studio 2010 配合使用

    mysql - MySQL 中奇怪的分隔十六进制 - 需要转换为 UTF8

    json - 如何在 Perl 中将简单的哈希转换为 json?

    sql - 删除多条记录后如何优化表

    python - 如何在urllib2请求中发送utf-8内容?

    python - 在 Python 中将 CSV 转换为 UTF-8