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

And*_*eas 5 firebird utf-8 firebird2.5

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

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

ALTER DOMAIN D_CHAR100 TYPE VARCHAR(100) CHARACTER SET UTF8;
Run Code Online (Sandbox Code Playgroud)

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

如果我在网上搜索,有人说:

  • 通过临时字段和处理所有数据的解决方案(与大数据库有关的大量工作)

和其他人说:

  • 改变域或字段数据类型就足够了。

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

Pau*_*aul 3

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

\n\n

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

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

尝试一下这两个语句:

\n\n
select cast('\xc2\xbd' as varchar(10) character set ISO8859_1)\nfrom rdb$database\n\nselect cast('\xc2\xbd' as varchar(10) character set UTF8)\nfrom rdb$database\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

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

\n\n

还有两点需要注意:

\n\n
    \n
  1. 如果您复制数据,您将收到 #4 的错误。相反,您应该根据需要清理这些数据,并使用可以正确转换这些值的外部应用程序来执行此操作。ASCII 171 = UTF 189 = 1/2 个字符。

  2. \n
  3. 针对这些字段执行语句的任何应用程序代码仍然可能违反问题 #3 的 64KB 规则。您需要至少搜索所有较大的字段或语句,以确保不会遇到此问题。

  4. \n
\n