Skip to Main Content

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question.

Asked: November 20, 2015 - 11:46 am UTC

Last updated: November 21, 2015 - 2:08 am UTC

Version: Oracle 12c

Viewed 10K+ times! This question is

You Asked

Hello Tom,

my question is about comparison of CLOBs.
Assume we have table with two CLOB columns. The query

select clob1, clob2 from mytable where clob1 = clob2

will not work. It will bring error. So, direct comparison of two CLOB columns is not allowed.
I know that I should use DBMS_LOB.COMPARE function in the WHERE clause and it will be fine.

However it seems to me that direct comparison of NEW and OLD values in the trigger works:

IF :OLD.clob1 <> :NEW.clob1 THEN
-- do something
END IF;

Actually I have checked it in debug and it works.
Does it mean that in the query you cannot use direct compare because you are trying to compare references and
in the trigger it is different because in this case Oracle get column content into the NEW and OLD variables?

Thank you very much,
Vladimir

and Connor said...

Triggers do it because they are taking advantage of the special case when the lob is being built from scratch. To demonstrate what I mean:


SQL> drop table T purge;

Table dropped.

SQL>
SQL> create table T ( x clob, y clob );

Table created.

SQL>
SQL> create or replace
  2  trigger TRG before insert or update on T
  3  for each row
  4  begin
  5    if :new.x != :new.y then
  6       raise_application_error(-20000,'error');
  7    end if;
  8  end;
  9  /

Trigger created.

SQL>
SQL> insert into T values ('qwe','qwe');

1 row created.

SQL> update T set y = 'abc';
update T set y = 'abc'
       *
ERROR at line 1:
ORA-20000: error
ORA-06512: at "MCDONAC.TRG", line 3
ORA-04088: error during execution of trigger 'MCDONAC.TRG'


So all looks good right ? But then look at this

SQL>
SQL> declare
  2    c clob;
  3  begin
  4    select y into c from t for update;
  5    dbms_lob.writeappend(c,100,rpad('x',100,'x'));
  6    commit;
  7  end;
  8  /

PL/SQL procedure successfully completed.

SQL>
SQL> select * from T;

X
--------------------------------------------------------------------------------
Y
--------------------------------------------------------------------------------
qwe
qwexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


SQL>
SQL>


So, yes, you're correct - the way we deal with clobs in triggers is different to simply equality in SQL.

DBMS_LOB.COMPARE will work but is very resource intensive for large clobs. If this is a need, better to calculate a checksum as you store the clob and use that.

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Thanks

vbe, November 23, 2015 - 5:54 am UTC

Thank You very much!

More to Explore

CLOB/BLOB/etc

Complete documentation on Securefiles and Large Objects here