0

我正在开发一段 ETL,它通过标准 Postgres ODBC 驱动程序将数据从 Postgres 上的数据仓库复制到使用 UTF8 字符集并在 Linux 上运行的使用典型 Windows 字符集的 SQLServer。

我发现我的一些源数据包含无法翻译成目标字符集的 UTF8 字符,导致整个加载失败。

我可以使用 postgres 函数来转换来自数据库的数据吗?有没有其他方法可以解决这个问题?

PS BTW,为什么在一个表的数据流中遇到此错误会导致我的所有加载失败?

4

2 回答 2

1

我在这里做一些假设。

  1. 您正在尝试通过 ODBC 系统 DSN 使用 MS SQL 链接对象连接到 Postgress,并看到诸如“错误:编码“UTF8”的字符 0xc280 在“WIN1252”中没有等效项等错误;
  2. 某些表上的选择语句有效,而另一些则抛出此错误。

修复:使用支持 Unicode 的 ODBC 驱动程序。我正在使用 PostgreSQL Global Development Group 的 ODBC 驱动程序。转到配置 DSN/管理 DSN 并选择 Unicode 驱动程序。

尝试发布图像但系统不会接受 - 显然我需要有 10 个“声誉”才能发布。

祝你好运。

马杜

于 2013-10-04T20:02:48.950 回答
1

如果您的目标编码中不支持 UTF-8 编码字符,那么 PostgreSQL 无法在不破坏数据的情况下对其进行转换。它不会破坏数据,因此会报告错误。

regress=# CREATE TABLE encoding_test(data text);
CREATE TABLE
regress=# INSERT INTO encoding_test(data) VALUES ('退休慰問金省182億怎麼用? 藍中常委建議發消費券');
INSERT 0 1
regress=# SHOW client_encoding;
 client_encoding 
-----------------
 UTF8
(1 row)

regress=# SET client_encoding = 'Windows-1252';
SET
regress=# SELECT * FROM encoding_test ;
ERROR:  character 0xe98080 of encoding "UTF8" has no equivalent in "WIN1252"

至于为什么这会导致一切停止工作:当 Pg 引发错误时,会中止事务。同一事务中的未来语句将失败。这是设计使然,因为保持数据完整性很重要,并且在事务中,如果一个操作失败,则整个事务都应该失败。它减少了错误不会被注意到的机会,直到有人恢复表然后问“所以,....为什么这个表是空的?”。

您应该在这里做的是使用 PostgreSQL Unicode ODBC 驱动程序,或者使用 ANSI ODBC 驱动程序和 utf-8 client_encoding,然后将数据作为 Unicode 插入 SQL Server,并正确设置数据库以接受 Unicode。

如果您确实想通过将数据转换为 Windows 8 位代码页之一来销毁数据:PostgreSQL 没有转换模式,它用占位符替换不可转换的字符。当您确实想故意丢弃数据时,这有时会令人沮丧。我建议将您的 PostgreSQL 连接保持在 UTF-8 模式或(在 Windows 中)使用 Unicode ODBC 驱动程序,然后将字符串从 Unicode 转换为应用程序中所需的目标编码,并根据需要进行修改。

于 2012-10-24T23:32:42.000 回答