继续我的last post -“将oracle迁移到postgresql无效字节序列以编码”UTF8“:0x00”
我正在尝试从远程PostgreSQL表(通过oracle_fdw扩展)插入本地Oracle表数据。我的Oracle表有一个名为street的列,它有有效的字符串值,有时还有下一个无效的字符串(在PostgreSQL中):‘’(空格)。
当我试图复制列值时,我得到了前面和最后一篇文章中提到的错误。我知道,在将oracle数据插入到PostgreSQL之前,我需要更改它。我必须在飞行中完成,所以我尝试在PostgreSQL中搜索甲骨文解码功能。我找到了两种解决方案,并同时使用了这两种方法,但我得到了相同的错误:
1.使用select和case:
mydb=>select *,(case when v.street=' ' then null END) from customer_prod v;
ERROR: invalid byte sequence for encoding "UTF8": 0x00
CONTEXT: converting column "street" for foreign table scan of
"customer_prod", row 2541482.使用orafce扩展部分的解码功能:
mydb=>select decode(street,' ',null) from customer_prod;
ERROR: invalid byte sequence for encoding "UTF8": 0x00所以,我还在搞错。我怎样才能解决这个问题?
发布于 2017-07-25 09:15:14
当值从Oracle传递到PostgreSQL时会发生错误,因此后处理不会防止错误发生。
为了演示起见,让我们创建一个Oracle表来展示这个问题:
CREATE TABLE nulltest(
id number(5) CONSTRAINT nulltest_pkey PRIMARY KEY,
val varchar2(10 CHAR)
);
INSERT INTO nulltest VALUES (1, 'schön');
INSERT INTO nulltest VALUES (2, 'bö' || CHR(0) || 'se');
INSERT INTO nulltest VALUES (3, 'egal');
COMMIT;让我们在PostgreSQL中为它创建一个外部表:
CREATE FOREIGN TABLE nulltest (
id integer OPTIONS (key 'true') NOT NULL,
val varchar(10)
) SERVER oracle
OPTIONS (table 'NULLTEST');
SELECT * FROM nulltest;
ERROR: invalid byte sequence for encoding "UTF8": 0x00
CONTEXT: converting column "val" for foreign table scan of "nulltest", row 2现在,最简单的方法是创建一个外部表,该表过滤掉零字符:
CREATE FOREIGN TABLE filter_nulltest (
id integer OPTIONS (key 'true') NOT NULL,
val varchar(10)
) SERVER oracle
OPTIONS (table '(SELECT id, replace(val, CHR(0), NULL) FROM nulltest)');
SELECT * FROM filter_nulltest;
┌────┬───────┐
│ id │ val │
├────┼───────┤
│ 1 │ schön │
│ 2 │ böse │
│ 3 │ egal │
└────┴───────┘
(3 rows)另一个效率较低的选项是创建一个函数,该函数捕获并向您报告坏行,以便您可以在Oracle端修复它们:
CREATE OR REPLACE FUNCTION get_nulltest() RETURNS SETOF nulltest
LANGUAGE plpgsql AS
$$DECLARE
v_id integer;
n nulltest;
BEGIN
FOR v_id IN SELECT id FROM nulltest
LOOP
BEGIN
SELECT nulltest.* INTO n
FROM nulltest
WHERE id = v_id;
RETURN NEXT n;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'Caught error % for id=%: %', SQLSTATE, v_id, SQLERRM;
END;
END LOOP;
END;$$;
SELECT * FROM get_nulltest();
NOTICE: Caught error 22021 for id=2: invalid byte sequence for encoding "UTF8": 0x00
┌────┬───────┐
│ id │ val │
├────┼───────┤
│ 1 │ schön │
│ 3 │ egal │
└────┴───────┘
(2 rows)https://stackoverflow.com/questions/45297296
复制相似问题