首页 > 解决方案 > 使用 dbms_lob.compare 比较 CLOB,没有得到我想要的结果

问题描述

不使用 dbms_lob.compare,所以更新工作正常,但是当它到达 IF 语句时,看起来只有当它支持交替时才做同样的事情,就像你可以看到下面

我的 PL/SQL 代码:

CREATE OR REPLACE PROCEDURE teste
IS
   aux CLOB;
   cnt NUMBER := 0;
   cnt1 NUMBER := 0;      
BEGIN
   FOR rec IN (SELECT  xxxx)
     LOOP
      aux := rec.VALUE;
        UPDATE db
        SET VALUE = TO_CLOB(deletexml(
        xmltype(VALUE),
        '//*:getPaymentDetailsResponse/*:Payment/*:childs[./*:status[text()="Failed"]]'
        ))
        WHERE id=rec.gb_ID;
          --Teste
          IF DBMS_LOB.compare(rec.VALUE, aux) = 0 THEN      
            DBMS_OUTPUT.put_line('### ORDERS NOT CHANGED ###');            
            cnt1 := cnt1 + 1;  --count orders without any change
            DBMS_OUTPUT.put_line(cnt1 || '- ' || rec.ORDER_PUBLIC_ID);
          ELSE
            DBMS_OUTPUT.put_line('### ORDERS CHANGED ###');
            cnt := cnt +1;  --count changed orders
            DBMS_OUTPUT.put_line(cnt || '- ' || rec.ORDER_PUBLIC_ID);
          END IF;  
     END LOOP;
   -- Print count results
   DBMS_OUTPUT.put_line('Orders without changing: '|| cnt1 || ' orders.');
   DBMS_OUTPUT.put_line('Orders updated: '|| cnt || ' orders.');
END;
/

这是我目前得到的:

订单未更改

1- 160000

订单未更改

2- 160000

订单未更改

3- 160313

订单未更改

4- 160313

我想要发生的事情:

订单已更改

1- 160000

订单未更改

2- 160000

订单已更改

3- 160313

订单未更改

4- 160313

标签: plsql

解决方案


创建游标时,它是运行选择时存在的数据的快照。在游标执行期间所做的任何表更改都不会反映在游标中。请参阅数据库游标是否会拾取对基础数据的更改?更多细节。

所以你更新你的游标的基表(我假设你没有显示实际的选择)

UPDATE db
    SET VALUE = TO_CLOB(deletexml(
    xmltype(VALUE),
    '//*:getPaymentDetailsResponse/*:Payment/*:childs[./*:status[text()="Failed"]]'
    ))
    WHERE id=rec.gb_ID;

然后您使用光标中的详细信息进行比较

IF DBMS_LOB.compare(rec.VALUE, aux) = 0 THEN

由于游标是一个快照,这将始终以未更改的形式返回,您必须从基表中重新选择值或使用 SQL%ROWCOUNT 来检查您的更新语句是否影响了任何行(请参阅https://community .oracle.com/thread/2370954?start=0&tstart=0)了解如何使用它的详细信息。


推荐阅读