ora-22992 通过DBLINK 访问远程CLOB表问题

本文介绍了解决通过DBLink访问远程数据库时遇到的ORA-22992错误的方法,包括使用全局临时表和两步插入更新策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在本地用select语句访问远程,如果远程表有CLOB字段的话则会有错:ora-22992;
如果真的想看到clob字段的内容的话就得在本地建立一个表,用下面两条语句:
我刚才试验insert into table select * from remote table成功
remote table含有CLOB
总结:在我的环境中成功
(1)create table aaa select * from remote table
(2)insert into table select * from remote table


不过网上也有以下说法,虽然有错,不过也是一种方法,

通过临时表从DBLink中获取Blob对象2006-12-05 20:37做系统集成时,通过Database Link共享数据是不错的选择。不过真正使用DBLink时却碰到一个不小的问题:从远程数据库上查询Blob字段时总返回ORA-22992错误,如下:

select blobcolumn from remoteTable
@dl_remote;

ORA-22992无法使用从远程表选择的 LOB 定位器

查找了一下解决方法,有人提出了采用物化视图可以解决这个问题。物化视图唯一的缺陷在于同步机制的问题,如果同步时间设置过短,则占用大量的系统资源,给服务器带来极大的压力;如果设置时间过长,前台用户不可接受。

后来还是AskTom给出了极好的解决方案:使用全局临时表。

SQL
create global temporary table foo

  2  
(

  
3    X BLOB

  4  
)

  
5  on commit delete rows;

Table created

SQL
insert into foo select blobcolumn from remoteTable@dl_remote where rownum 1;

1 row inserted

SQL


插入本地临时表之后,在本地的操作就没有任何问题了。

 

 

 

 

 

-- 另外一篇

Oracle官方论坛关于DBLink problem ORA-22992的讨论

 

我做了一下整理,最终那句是最后的答案,相信不用怎么翻译大家都应该能够看懂说些什么,这一点可是搞IT所必须的。
 
don't know if this is related, but we were also having a problem that was causing the ORA-22992 error, and the solution turned out to be surprisingly simple. A full day of searching the web didn't turn up this answer, but then one of our DBAs accidentally stumbled over something buried in some Oracle documentation that provided the answer.
 
We have a database table that contains a couple primary key fields (a varchar and an integer), plus a BLOB that holds Word documents. One of our programs needs to be able to connect to a remote Oracle instance and copy Word documents based on certain primary keys.
 
Our code first attempted to do that like this:
 
insert into [local Word doc table] ([key column1], [key column 2], [blob column])
values ('[key 1 literal]', [key 2 literal],
(select [blob column] from [Word doc table]@[remote instance]
where [keys = remote keys])
 
Attempting to execute that was giving us the "cannot use LOB locators selected from remote tables" error.
 
The documentation that our DBA turned up included a bunch of SQL examples of using remote BLOBs which he thought would be helpful. But what provided the solution was the sentence following the SQL examples: "In statements structured like the preceding examples, only standalone LOB columns are allowed in the select list".
 
I took that to mean that if you're going to access a BLOB on a remote database, then that BLOB column has to be the ONLY column you're referencing. So I broke our program's SQL up into this:
 
insert into [local Word doc table] ([key 1 col], [key 2 col], [blob col]) values
('[key 1]', [key 2], NULL)
 
update [local Word doc table] set [blob col] = 
(select [blob col] from [Word doc table]@[remote instance]
where [keys = remote keys])
where [keys = local keys]
 
I was amazed to find that the above works like a charm. We've got a 100 meg Word document going from one Oracle instance to the other with no problem.
 
Since doing a Google search on "cannot use LOB locators selected from remote tables" turns this page up near the top of its list of links, I'm hoping that by posting this I can save another programmer somewhere the two or three days of banging your head against the screen that I just went though.
### Oracle 数据库中通过 DBLink 操作 CLOB 字段的最佳实践 #### 使用 TO_LOB 函数转换 为了能够成功读取远程数据库中的 CLOB 字段,可以考虑使用 `TO_LOB` 函数来处理这些大对象字段。此函数允许将 LONG 或者其他类型的 LOB 转换为 CLOB 类型的数据[^1]。 ```sql SELECT id, TO_LOB(remote_clob_column) AS converted_clob FROM remote_table@dblink; ``` #### 创建视图简化访问 对于频繁使用的查询,建议创建本地视图以封装复杂的 SQL 达式。这不仅提高了可维护性,还使得后续的应用程序开发更加简便[^5]。 ```sql CREATE OR REPLACE VIEW v_remote_data AS SELECT id, dbms_lob.substr(photo, 4000, 1) as photo_preview FROM tsource@dblink1; ``` #### 利用 PL/SQL 进行分片读写 针对较大的 CLOB 数据量,采用 PL/SQL 编程方式逐块读取或写入数据是一个有效的策略。这种方法能有效规避单次传输带来的性能瓶颈以及潜在错误[^2]。 ```plsql DECLARE l_clob CLOB; BEGIN SELECT photo INTO l_clob FROM tsource@dblink WHERE id = :id; FOR i IN 1..CEIL(DBMS_LOB.GETLENGTH(l_clob)/4000) LOOP INSERT INTO local_table (chunk) VALUES (DBMS_LOB.SUBSTR(l_clob, 4000*(i-1)+1, LEAST(4000,DBMS_LOB.GETLENGTH(l_clob)-(4000*(i-1))))); END LOOP; END; / ``` #### 配置网络参数优化效率 适当调整客户端与服务器端之间的 TCP/IP 设置和其他相关配置项也可以显著改善跨数据库链接时的操作体验。特别是对于大数据集而言,合理的缓冲区大小设置至关重要[^3]。 ```ini # sqlnet.ora configuration example TCP.NODELAY=NO SQLNET.SEND_BUF_SIZE=65536 SQLNET.RECV_BUF_SIZE=65536 ``` #### 建立中间暂存数据 如果目标是在两个不同实例间同步大量 CLOB 数据,则可以在源端建立临时存储区域用于阶段性保存待迁移的信息片段;之后再由目的端发起批量插入动作完成最终转移过程[^4]。 ```sql -- On source side create staging table and populate it with chunks of data. CREATE TABLE stage_photo_chunks ( chunk_id NUMBER, part_num INTEGER GENERATED BY DEFAULT ON NULL AS IDENTITY, content CLOB); INSERT ALL WHEN MOD(dbms_utility.get_time(), 2)=0 THEN INTO stage_photo_chunks(chunk_id,content) VALUES (:id,DBMS_LOB.SUBSTR(:photo, 4000,:offset)) SELECT id, photo, offset FROM ... ; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值