Oracle ORA-22992删除远程表问题中对LOB的引用

Oracle ORA-22992删除远程表问题中对LOB的引用,oracle,casting,subquery,sql-insert,lob,Oracle,Casting,Subquery,Sql Insert,Lob,我正在尝试使用多个select语句将捕获的\u数据\u 01插入表中。我可以插入值EVENT\u ID、ENV\u ID、BRAND\u ID、BP\u ID,但现在我还想插入订阅\u ID值,我将在远程表中使用select语句获得该值。我测试过的查询在获取订阅ID时运行良好。但是,当我尝试使用此select语句在insert查询中插入订阅ID的值时,我在子查询中使用订阅ID的cast函数时出现了错误,如下所示: SQL Error: ORA-22992: cannot use LOB loca

我正在尝试使用多个select语句将捕获的\u数据\u 01插入表中。我可以插入值EVENT\u ID、ENV\u ID、BRAND\u ID、BP\u ID,但现在我还想插入订阅\u ID值,我将在远程表中使用select语句获得该值。我测试过的查询在获取订阅ID时运行良好。但是,当我尝试使用此select语句在insert查询中插入订阅ID的值时,我在子查询中使用订阅ID的cast函数时出现了错误,如下所示:

SQL Error: ORA-22992: cannot use LOB locators selected from remote tables
22992. 00000 -  "cannot use LOB locators selected from remote tables"
*Cause:    A remote LOB column cannot be referenced.
*Action:   Remove references to LOBs in remote tables
我的问题是:

Insert into CAPTURED_DATA_01(SUBSCRIPTION_ID) 
select WF.SUBSCRIPTION_ID 
   from 
   (select WF.SUBSCRIPTION_ID from WF_WORKFLOW@FONIC_RETAIL WF,CAPTURED_DATA_01 CP
where WF.SUBSCRIPTION_ID > CP.SUBSCRIPTION_ID and 
WF.SUBSCRIPTION_ID IN
( 
select iw.SUBSCRIPTION_ID
from (
   SELECT TO_NUMBER(REPLACE(REPLACE(REGEXP_SUBSTR(RESPONSE_XML, '<ax2147:subscriptions xsi:type="ax2127:SubscriptionDTO"><ax2130:id>\d+</ax2130:id>'), 
   '<ax2147:subscriptions xsi:type="ax2127:SubscriptionDTO"><ax2130:id>', ''), '</ax2130:id>', '')) 
   AS SUBSCRIPTION_ID , 
   CAST(REPLACE(REPLACE(
  REGEXP_SUBSTR(REQUEST_XML, '<ns7:orderType>.+</ns7:orderType>'),
    '<ns7:orderType>', ''), '</ns7:orderType>', '')
  AS VARCHAR(100)) AS order_type,
  TO_NUMBER(REPLACE(REPLACE(REGEXP_SUBSTR(RESPONSE_XML, '<ax2147:orderNumber>\d+</ax2147:orderNumber> '), 
   '<ax2147:orderNumber>', ''), '</ax2147:orderNumber> ', '')) 
   AS ORDER_NUMBER,
   CREATE_DATE
   FROM
   SOAP_MONITORING@FONIC_RETAIL 
   where WEB_SERVICE_NAME='RatorWebShopService' and WEB_METHOD_NAME='placeShopOrder' 
) iw
where iw.order_type='SELF_REGISTRATION'
)and WF.NAME='INITIATE_MANDATE' 
and WF.STATUS_ID=0)

据我所知,问题是insert总是在本地数据库上运行

当您只运行select时,Oracle可以决定或提示您在远程数据库上执行某些工作;在本例中,它将CLOB值转换为number和varchar2类型,并且只有那些非LOB值必须通过网络传输到本地数据库进行进一步处理

对于insert,它将尝试检索整个LOB以在本地对其进行转换,并且它阻止了这种情况的发生——可能是由于涉及的潜在数据量。对于插入,将忽略driving_site提示,因此您不能像对select那样调整该行为

为了解决这个问题,您可以通过PL/SQL块中的光标,分两步执行选择和插入。一般模式是:

declare
  type cp_tab_type is table of CAPTURED_DATA_01%ROWTYPE;
  cp_tab cp_tab_type;
  cur sys_refcursor;
begin
  open cur for
    select ... -- some value for every column in the table you're inserting
               -- into, in the same order they appear in the DDL
  loop
    fetch cur bulk collect into cp_tab;
    exit when cp_tab.count = 0;
    forall i in 1..cp_tab.count
      insert into CAPTURED_DATA_01 values cp_tab(i);
  end loop;
end;
/
关于批量收集和forall进行批量查询/插入

如您所建议的,如果您有可以用于on子句的内容,也可以使用merge;对于exmaple,如果事件id根本不存在:

merge into CAPTURED_DATA_01 cp
using (
    select ..
) data
on (cp.event_id = data.event_id)
when not matched then
insert (EVENT_ID,SUBSCRIPTION_ID,EVENT_TIMESTAMP,ENV_ID,BRAND_ID,BP_ID)
values (data.event_id, data.subscription_id, data.start_date,
  data.env_id, data.brand_id, data.bp_id);

您发布的每个问题都会使您的查询变得更加复杂,可能会简化很多。

此语句对\u numberreplaceregregexp\u SUBSTRRESPONSE\u XML,“\d+”的处理存在一个小问题,我得到了错误:并且没有可用于搜索此错误的文档,正如SUBSCRIPTION一样,我认为问题在于插入总是在本地处理的,因此它不会像使用普通select那样远程执行LOB列上的substr等操作。您可以使用driving_site提示来改变行为,以打破这一点,但据我所知,insert会忽略该提示。您可能需要在PL/SQL块中查询一个游标,然后从中进行大容量插入。哦,好的,我的PL/SQL非常差,但是在这种情况下,请尝试使用一些游标。您是否有此select查询的光标示例?在这种情况下,我们是否可以使用Merge语句?如果您有一个键字段可以用于on,则是。在我的回答中补充了这一点。您可能想比较两种方法的性能。您好,Alex,谢谢您的提示。你认为通过合并可以远程插入什么?或者我将面临与普通插入相同的问题?因此,与其使用游标处理completetd批量插入,我可以尝试合并?我通过删除其他列编辑了一个问题,我想尝试合并,只需插入SUBSCRIPTION\u ID,首先排除其他列,这样您就知道根据我的问题合并语句的外观了?要仅使用一列,只需更改insert和values子句。远程插入从哪里来?当您不断更改需求、限制和现有代码时,这是非常令人沮丧的。祝你好运。不,亚历克斯,我没有改变要求。我没有在列中插入其他值,而是尝试先将订阅ID插入到捕获的表格中。因为这对我很重要。如果它可以工作,那么当我在本地运行这个查询时,我可以在本地插入其他列值。谢谢您:。最后一个问题。我尝试插入订阅ID、事件时间戳、事件ID,它正在插入值。但我现在添加了更多的列ENV_ID、BRAND_ID、BP_ID及其显示的小错误。我的问题是: