Oracle:无法将数据从max_string_size=扩展到max_string_size=标准数据库



我们有一个Oracle 12.1数据库,其中MAX_STRING_SIZE已设置为EXTENDED,从而可以使用VARCHAR2(32767)列。我们通过物化视图和数据库链接将数据复制到Oracle 11.2数据库。三年来,一切都在平稳运行,直到我们删除并重新创建mview(在dev中(,得到一个错误

ORA-00910: specified length too long for its datatype

最小测试用例在源数据库上有一个表(12.1(。请注意,实际值非常短,不要使用声明的长度。因此,这只是关于声明,而不是关于数据:

CREATE TABLE sematest (
vc_char VARCHAR2(4000 CHAR),
vc_byte VARCHAR2(4000 BYTE)
);
INSERT INTO sematest VALUES ('char','byte');

列定义为:

SELECT column_name,data_type,data_length,char_length,char_used 
FROM user_tab_columns 
WHERE table_name = 'SEMATEST';
COLUMN_NAME DATA_TYPE DATA_LENGHT CHAR_LENGTH CHAR_USED
VC_CHAR     VARCHAR2        16000        4000         C
VC_BYTE     VARCHAR2         4000        4000         B

目标数据库(11.2,但如果未启用扩展数据类型,则与12.1相同(可以轻松复制data_length=4000列,但不能复制data_llenght=16000列:

CREATE MATERIALIZED VIEW test_char BUILD DEFERRED REFRESH COMPLETE ON DEMAND AS
SELECT vc_char FROM sematest@dblink;
ORA-00910: specified length too long for its datatype
CREATE MATERIALIZED VIEW test_byte BUILD DEFERRED REFRESH COMPLETE ON DEMAND AS
SELECT vc_byte FROM sematest@dblink;
Materialized view TEST_BYTE created.

更令人困惑的是,这种行为依赖于BUILD DEFERRED。有了BUILD IMMEDIATE,一切都很好:

CREATE MATERIALIZED VIEW test_char BUILD IMMEDIATE REFRESH COMPLETE ON DEMAND AS
SELECT vc_char FROM sematest@dblink;
Materialized view TEST_BYTE created

真正令人沮丧的是,我们三年前就解决了这个问题,但忘记了如何解决。请帮忙!

您可以使用SUBSTRB(Docs(获取限制为4000字节的远程16000字节列的子字符串。请注意,如果有任何行的值的字符长度为<=4000但字节长度>4000(由于有多个libyte字符(,那么您将丢失额外的数据(您无处将其放入varchar2中(。

在较新的版本中,您可能会将列强制转换为CLOB,但我认为这对您的11.2 DB不起作用。您需要升级到12.2,以便通过数据库链接更容易地传输clobs。如果您计划很快升级,可以考虑使用MVIEW数据库的扩展字符串大小。

相关内容

  • 没有找到相关文章

最新更新