Jey*_*eyJ 0 oracle postgresql utf-8 oracle-fdw
继续我的上一篇文章- “将 oracle 迁移到 postgresql 编码 \xe2\x80\x9cUTF8\xe2\x80\x9d 的字节序列无效:0x00”
\n我正在尝试将远程 Oracle 表中的数据插入到本地 PostgreSQL 表中(通过 oracle_fdw 扩展)。我的 Oracle 表有一个名为 street 的列,它具有有效的字符串值,有时还有下一个无效(在 PostgreSQL 中)字符串:\' \'(空格)。
\n当我尝试复制列值时,我收到上面和上一篇文章中提到的错误。我明白在将 oracle 数据插入到 PostgreSQL 之前我需要更改它。我必须即时执行此操作,因此我尝试在 PostgreSQL 中搜索 oracle 解码函数。我找到了两个解决方案,并且都使用了它们,但出现了相同的错误:
\n1.使用带有大小写的选择:
\nmydb=>select *,(case when v.street=\' \' then null END) from customer_prod v;\nERROR: invalid byte sequence for encoding "UTF8": 0x00\nCONTEXT: converting column "street" for foreign table scan of \n "customer_prod", row 254148\nRun Code Online (Sandbox Code Playgroud)\n2.使用orafce扩展中的解码函数:
\nmydb=>select decode(street,\' \',null) from customer_prod;\nERROR: invalid byte sequence for encoding "UTF8": 0x00\nRun Code Online (Sandbox Code Playgroud)\n所以,我仍然收到错误。我该如何解决这个问题?
\n当值从 Oracle 传输到 PostgreSQL 时会发生错误,因此后处理不会阻止该错误。
\n\n为了演示,让我们创建一个显示该问题的 Oracle 表:
\n\nCREATE TABLE nulltest(\n id number(5) CONSTRAINT nulltest_pkey PRIMARY KEY,\n val varchar2(10 CHAR)\n);\n\nINSERT INTO nulltest VALUES (1, \'sch\xc3\xb6n\');\nINSERT INTO nulltest VALUES (2, \'b\xc3\xb6\' || CHR(0) || \'se\');\nINSERT INTO nulltest VALUES (3, \'egal\');\n\nCOMMIT;\nRun Code Online (Sandbox Code Playgroud)\n\n让我们在 PostgreSQL 中为其创建一个外部表:
\n\nCREATE FOREIGN TABLE nulltest (\n id integer OPTIONS (key \'true\') NOT NULL,\n val varchar(10)\n) SERVER oracle\n OPTIONS (table \'NULLTEST\');\n\nSELECT * FROM nulltest;\n\nERROR: invalid byte sequence for encoding "UTF8": 0x00\nCONTEXT: converting column "val" for foreign table scan of "nulltest", row 2\nRun Code Online (Sandbox Code Playgroud)\n\n现在最简单的事情是创建一个过滤掉零字符的外表:
\n\nCREATE FOREIGN TABLE filter_nulltest (\n id integer OPTIONS (key \'true\') NOT NULL,\n val varchar(10)\n) SERVER oracle\n OPTIONS (table \'(SELECT id, replace(val, CHR(0), NULL) FROM nulltest)\');\n\nSELECT * FROM filter_nulltest;\n\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 id \xe2\x94\x82 val \xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n\xe2\x94\x82 1 \xe2\x94\x82 sch\xc3\xb6n \xe2\x94\x82\n\xe2\x94\x82 2 \xe2\x94\x82 b\xc3\xb6se \xe2\x94\x82\n\xe2\x94\x82 3 \xe2\x94\x82 egal \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n(3 rows)\nRun Code Online (Sandbox Code Playgroud)\n\n另一个效率较低的选项是创建一个函数来捕获并向您报告错误行,以便您可以在 Oracle 端修复它们:
\n\nCREATE OR REPLACE FUNCTION get_nulltest() RETURNS SETOF nulltest\n LANGUAGE plpgsql AS\n$$DECLARE\n v_id integer;\n n nulltest;\nBEGIN\n FOR v_id IN SELECT id FROM nulltest\n LOOP\n BEGIN\n SELECT nulltest.* INTO n\n FROM nulltest\n WHERE id = v_id;\n RETURN NEXT n;\n EXCEPTION\n WHEN OTHERS THEN\n RAISE NOTICE \'Caught error % for id=%: %\', SQLSTATE, v_id, SQLERRM;\n END;\n END LOOP;\nEND;$$;\n\nSELECT * FROM get_nulltest();\n\nNOTICE: Caught error 22021 for id=2: invalid byte sequence for encoding "UTF8": 0x00\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xac\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 id \xe2\x94\x82 val \xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xbc\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n\xe2\x94\x82 1 \xe2\x94\x82 sch\xc3\xb6n \xe2\x94\x82\n\xe2\x94\x82 3 \xe2\x94\x82 egal \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xb4\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n(2 rows)\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1332 次 |
| 最近记录: |