未使用BLOB列,通过dblink访问远程表仍报ORA-22992错误求助
解决ORA-22992错误的方案
原因分析
即便你没有在SELECT列表中指定BLOB列,Oracle优化器的执行计划仍可能尝试获取远程表的LOB定位符(比如扫描整行数据的访问路径),而远程LOB定位符无法在本地会话直接使用,从而触发该错误。
具体解决方法
1. 强制远程端完成数据过滤与投影
让远程数据库先处理好需要的列和过滤逻辑,避免本地会话接触到LOB列,有两种实现方式:
方式A:给远程子查询加NO_MERGE提示
修改内层查询,确保Oracle在远程库仅返回所需列:
insert into TOP.BKR ( SECTANRFFT, REFBEREICH ) select SECTANRFFT, REFBEREICH FROM ( select /*+ NO_MERGE(txtr) */ txtr.SECTANRFFT SECTANRFFT, txtr.REFBEREICH REFBEREICH from TOP.TB_ODS_LAST_DATE TB_ODS_LAST_DATE INNER JOIN ( select /*+ materialize */ SECTANRFFT, REFBEREICH, DAT from BKP.ZORP@"TECD.POR" ) txtr ON 1=1 where TB_ODS_LAST_DATE.TABLE_NAME = 'SRTPO' and (to_date('19700101','yyyymmdd') + (((txtr.DAT/60)/60)/24) > TB_ODS_LAST_DATE.LAST_DATE) ) FRT
方式B:在远程库创建无BLOB的视图
在远程数据库TECD.POR上执行:
CREATE VIEW BKP.V_ZORP_NOBLOB AS SELECT SECTANRFFT, REFBEREICH, DAT FROM BKP.ZORP;
本地查询替换为该视图:
insert into TOP.BKR ( SECTANRFFT, REFBEREICH ) select SECTANRFFT, REFBEREICH FROM ( select txtr.SECTANRFFT SECTANRFFT, txtr.REFBEREICH REFBEREICH from TOP.TB_ODS_LAST_DATE TB_ODS_LAST_DATE INNER JOIN BKP.V_ZORP_NOBLOB@"TECD.POR" txtr ON 1=1 where TB_ODS_LAST_DATE.TABLE_NAME = 'SRTPO' and (to_date('19700101','yyyymmdd') + (((txtr.DAT/60)/60)/24) > TB_ODS_LAST_DATE.LAST_DATE) ) FRT
2. 用临时表中转数据
先将远程所需数据导入本地临时表,再从临时表插入目标表:
-- 创建临时表,列类型匹配原表 CREATE GLOBAL TEMPORARY TABLE TMP_ZORP_DATA ( SECTANRFFT VARCHAR2(100), REFBEREICH VARCHAR2(100), DAT NUMBER ) ON COMMIT DELETE ROWS; -- 从远程表导入临时表 INSERT INTO TMP_ZORP_DATA SELECT SECTANRFFT, REFBEREICH, DAT FROM BKP.ZORP@"TECD.POR"; -- 从临时表插入目标表 insert into TOP.BKR ( SECTANRFFT, REFBEREICH ) select SECTANRFFT, REFBEREICH FROM TMP_ZORP_DATA txtr INNER JOIN TOP.TB_ODS_LAST_DATE TB_ODS_LAST_DATE ON 1=1 where TB_ODS_LAST_DATE.TABLE_NAME = 'SRTPO' and (to_date('19700101','yyyymmdd') + (((txtr.DAT/60)/60)/24) > TB_ODS_LAST_DATE.LAST_DATE);
3. 调整MATERIALIZE提示位置
把/*+ materialize */移到远程子查询上,让远程数据先被物化到本地临时对象,避免LOB定位符传递:
insert into TOP.BKR ( SECTANRFFT, REFBEREICH ) select SECTANRFFT, REFBEREICH FROM ( select txtr.SECTANRFFT SECTANRFFT, txtr.REFBEREICH REFBEREICH from TOP.TB_ODS_LAST_DATE TB_ODS_LAST_DATE INNER JOIN ( select /*+ materialize */ SECTANRFFT, REFBEREICH, DAT from BKP.ZORP@"TECD.POR" ) txtr ON 1=1 where TB_ODS_LAST_DATE.TABLE_NAME = 'SRTPO' and (to_date('19700101','yyyymmdd') + (((txtr.DAT/60)/60)/24) > TB_ODS_LAST_DATE.LAST_DATE) ) FRT
内容的提问来源于stack exchange,提问作者Marcus
相关产品推荐
相关产品推荐

