我已经看过十几个这样的问题,但大多数问题都得到的答案并不适用于我的案例。
首先 - 数据库是我试图从一个非常慢的网络获取数据并连接到使用VPN。
我通过数据库链接访问它。
我对我的架构表有完全的读/写访问权限,但我没有DBA权限,所以我无法创建转储,而且我没有为创建新表等提供资助。
我一直试图在本地获取数据库,除了一个表外一切都很好。
它有650万条记录和16列。 获得其中的14个没有问题,但剩下的两个是带有大量XML的Clobs。
数据传输速度很慢,很痛苦。
我试过了 基于select插入 插入全部14然后更新另外2 将表创建为 基于select条件插入,所以我只得到这么多记录并手动提交
问题主要是在事务完成之前连接丢失(或断电或VPN丢失或随机错误等),并且所有已下载的GB都将被丢弃。
正如我所说,我尝试了条件,所以我得到了一些记录,但即使这有点随机,需要我的关注。 类似的东西:
Insert into TableA
Select * from TableA@DB_RemoteDB1
WHERE CREATION_DATE BETWEEN to_date('01-Jan-2016') AND to_date('31-DEC-2016')
有时它有时会起作用。在几GB之后,Toad停止运行,但当我查看它的吞吐量时,它是0KB / s或几个字节/秒。
我正在寻找的是一个循环或一个游标,可以用来一次获得100000或1000000 - 提交它然后去完成剩下的工作直到完成。
这是我正在做的一次性操作,因为我们需要本地数据进行测试 - 所以我不关心它是否效率低,只要数据以块的形式引入并且提交可以使我免于再次检索它。
我已经可以计算过去3天内已经完成的大约15GB的失败下载,而我的本地表仍然有0条记录,因为我的所有尝试都失败了。
服务器:Oracle 11g
本地:Oracle 11g
尝试过的客户端:Toad / Sql Dev / dbForge Studio
感谢。
答案 0 :(得分:1)
您可以执行以下操作:
begin
loop
insert into tablea
select * from tablea@DB_RemoteDB1 a_remote
where not exists (select null from tablea where id = a_remote.id)
and rownum <= 100000; -- or whatever number makes sense for you
exit when sql%rowcount = 0;
commit;
end loop;
end;
/
这假设有一个主/唯一密钥可用于检查远程表中的行是否已存在于本地密钥中 - 在此示例中,我使用了模糊的ID
列,但用实际的键列替换它。
对于循环的每次迭代,它将识别远程表中本地表中不存在的行 - 这可能很慢,但是你说这里的性能不是优先级 - 然后,通过rownum
,将插入的行数限制为可管理的子集。
当没有插入行时,循环终止,这意味着远程表中没有剩下的行不会在本地存在。
由于提交和where not exists
检查,这应该可以重新启动。这通常不是一种好方法 - 因为它会破坏正常的事务处理 - 但是作为一次性和网络问题/约束可能是必要的。
Toad是对的,使用批量收集会(通常会显着)更快一般,因为每次循环都不会重复查询:
declare
cursor l_cur is
select * from tablea@dblink3 a_remote
where not exists (select null from tablea where id = a_remote.id);
type t_tab is table of l_cur%rowtype;
l_tab t_tab;
begin
open l_cur;
loop
fetch l_cur bulk collect into l_tab limit 100000;
forall i in 1..l_tab.count
insert into tablea values l_tab(i);
commit;
exit when l_cur%notfound;
end loop;
close l_cur;
end;
/
这次你可以将limit 100000
更改为你认为合理的数字。这里有一个权衡,因为PL / SQL表会消耗内存,所以你可能需要试验一下来选择那个值 - 如果它太高,你可能会得到错误或影响其他用户。这里的问题较小,除了散装插件的效率稍差。
但是因为你有一个CLOB列(持有你的XML),这对你来说不起作用,正如@BobC指出的那样; insert ... select
is supported over a DB link,但收集版本将从fetch中收到错误:
ORA-22992:不能使用从远程表中选择的LOB定位器
ORA-06512:第10行 22992. 00000 - &#34;不能使用从远程表中选择的LOB定位器&#34;
*原因:无法引用远程LOB列 *操作:删除对远程表中LOB的引用。