我们有一个 Oracle 12.1 数据库,其中MAX_STRING_SIZE
已设置为EXTENDED
,从而可以使用VARCHAR2(32767)
列。我们通过物化视图和数据库链接将数据复制到 Oracle 11.2 数据库。一切都顺利运行了三年,直到我们删除并重新创建 mview(在开发中)并得到一个错误
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_lenght=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
真正令人沮丧的是,我们三年前已经解决了这个问题,但忘记了如何解决。请帮忙!