我正在开发一段 ETL,它通过标准 Postgres ODBC 驱动程序将数据从 Postgres 上的数据仓库复制到使用 UTF8 字符集并在 Linux 上运行的使用典型 Windows 字符集的 SQLServer。
我发现我的一些源数据包含无法翻译成目标字符集的 UTF8 字符,导致整个加载失败。
我可以使用 postgres 函数来转换来自数据库的数据吗?有没有其他方法可以解决这个问题?
PS BTW,为什么在一个表的数据流中遇到此错误会导致我的所有加载失败?
我正在开发一段 ETL,它通过标准 Postgres ODBC 驱动程序将数据从 Postgres 上的数据仓库复制到使用 UTF8 字符集并在 Linux 上运行的使用典型 Windows 字符集的 SQLServer。
我发现我的一些源数据包含无法翻译成目标字符集的 UTF8 字符,导致整个加载失败。
我可以使用 postgres 函数来转换来自数据库的数据吗?有没有其他方法可以解决这个问题?
PS BTW,为什么在一个表的数据流中遇到此错误会导致我的所有加载失败?
我在这里做一些假设。
修复:使用支持 Unicode 的 ODBC 驱动程序。我正在使用 PostgreSQL Global Development Group 的 ODBC 驱动程序。转到配置 DSN/管理 DSN 并选择 Unicode 驱动程序。
尝试发布图像但系统不会接受 - 显然我需要有 10 个“声誉”才能发布。
祝你好运。
马杜
如果您的目标编码中不支持 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 转换为应用程序中所需的目标编码,并根据需要进行修改。