oracle - 使用 oracle-fdw 将海量表从 Oracle 导入 PostgreSQL 返回 ORA-01406
问题描述
我从事一个项目,将数据从 Oracle 数据库传输到 PostgreSQL 数据库,以使用 bash 和 SQL 脚本创建数据仓库。为了访问 Oracle 数据库,我使用 PostgreSQL 扩展 oracle-fdw。
我的一个脚本从一个巨大的表中导入数据(~ 100 000 000 新行/天)。该表是分区的,每个分区包含 1 天的数据。我用来导入数据的查询如下所示:
INSERT INTO postgre_target_table (some_fields)
SELECT some_aggregated_fields -- (~150 fields)
FROM oracle_source_table
WHERE partition_id = :v_partition_id AND some_others_filters
GROUP BY primary_key;
在 DEV 服务器上,查询工作正常(此服务器上的数据少得多),但在 PREPROD 中,它返回错误ORA-01406: fetched column value was truncated
。
在一些帖子中,人们说输出字段可能太小,但如果我尝试发送一个没有 INSERT 或 GROUP BY 的简单 SELECT 查询,我会遇到同样的错误。
我在另一篇文章中发现的另一个想法是创建一个 Oracle 侧视图,但在我的查询中,我使用了多个无法在视图中使用的参数。
我发现的最后一个想法是创建一个 Oracle 存储过程,用聚合数据填充表,然后从该表中导入数据,但 Oracle 数据库很关键,我的客户更喜欢避免在其上添加更多数据。
现在,我开始认为没有解决方案,而且不好......
PostgreSQL 版本:12.4 / Oracle 版本:11.2
更新
看来我的问题比我想象的要复杂。
应用 Laurenz Albe 给出的修改后,查询在 PGAdmin 上正确运行,但当我使用psql
命令时问题仍然出现。此外,另一个查询似乎也有同样的问题。这个另一个查询不使用与第一个查询相同的源表,它使用 4 个没有任何分区的连接表。这些查询之间的共同点是结构。
我在原始帖子中省略指定的细节是这两个查询的目的是透视表。他们看起来像这样:
SELECT osr.id,
MIN(CASE osr.category
WHEN 123 THEN
1
END) AS field1,
MIN(CASE osr.category
WHEN 264 THEN
1
END) AS field2,
MIN(CASE osr.category
WHEN 975 THEN
1
END) AS field3,
...
FROM oracle_source_table osr
WHERE osr.category IN (123, 264, 975, ...)
GROUP BY osr.id;
现在我已经详细说明了查询的样子,我可以在不更改 max_long 的值的情况下为您提供第二个查询的一些结果(此查询比第一个查询轻):
- 有时它可以工作(~10%),有时它在 PGadmin 上失败(~90%),但它从不使用
psql
命令 - 如果我删除
WHERE
,它总是有效的
我不明白为什么要删除WHERE
更改的内容,此子句中使用的字段是介于 0 和 2500 之间的NUMBER(6, 0)并且仍在SELECT
子句中使用...哦,在此使用的 4 个 Oracle 表中查询,没有LONG数据类型,只使用NUMBER数据类型。
在我的 20 个查询中,只有这两个有问题,它们的结构相似,我不相信巧合。
解决方案
不要绝望!
将max_long
外部表上的选项设置得足够大,以适应所有超大数据。
该文档有详细信息:
- max_long(可选,默认为“32767”)
Oracle 表中任何 LONG、LONG RAW 和 XMLTYPE 列的最大长度。可能的值是 1 到 1073741823 之间的整数(PostgreSQL 中一个字节的最大大小)。此内存量将至少分配两次,因此较大的值将消耗大量内存。
如果max_long小于检索到的最长值的长度,您将收到错误消息
ORA-01406: fetched column value was truncated
例子:
ALTER FOREIGN TABLE my_tab OPTIONS (ADD max_long '1000000');
推荐阅读
- c# - 如何编写谓词函数
- gmail - 是否可以从 gmail api 创建过滤器以将消息标记到已发送文件夹
- html - 图片不适合页面,需要另外高于所有内容
- c# - gridview 下拉列表值问题
- r - 在数据框中查找 ID 并从另一个数据框中绘制值
- javascript - Redux:将用于非平坦状态的 `reducres` 与避免创建大量 reducer 相结合
- html - CSS 3 行,第一行固定大小,最后一行固定大小,居中休息
- javascript - 如何使用多个按钮 Popper.js 触发相同的弹出窗口?
- swift - `_?` 在 Swift 中是什么意思?
- r - 使用 dplyr 标记和计算值之间的间隙