Home > Mobile >  Oracle comparing clobs in same row
Oracle comparing clobs in same row

Time:12-07

I have a table that contains some columns and two CLOBS.

In some cases both the CLOBS contain the same exact values and in other cases they contain different values. or one or both CLOBS can be empty or NULl.

I created a function, which I would like to call to compare both CLOBS to determine if the values are 'SAME' or different.


CREATE or REPLACE FUNCTION HASH_SHA512 (
    psINPUT IN VARCHAR2
    ) RETURN VARCHAR2 AS
    rHash RAW (512);
    BEGIN
    rHash := DBMS_CRYPTO.HASH (TO_CLOB (psINPUT), 
dbms_crypto.HASH_SH512);
    RETURN (LOWER (RAWTOHEX (rHash)));
    END HASH_SHA512;
/



CREATE table table_x(
seq_num integer  GENERATED BY DEFAULT AS IDENTITY (START WITH 1) NOT NULL,
val NUMBER, 
clob1 CLOB,
clob2 CLOB);


insert into table_x (val, clob1, clob2) values (1,'aaaaaaaaaa','aaaaaaaaaa');

insert into table_x (val, clob1, clob2) values (1,'aaaaa','aaaaaaaaaa');

insert into table_x (val, clob1, clob2) values (2,'Xaaaaaaaaa','aaaaaaaaaa');

Expected output 

SEQ_NUM    VAL    CLOB1    CLOB2
1    1    aaaaaaaaaa    aaaaaaaaaa  SAME
2    1    aaaaa    aaaaaaaaaa DIFFERENT 
3    2     Xaaaaaaaaa    aaaaaaaaaa DIFFERENT 

Based on the output of the above query if the SHA512 output shows the difference to be the same I want to INSERT 1 row into the new table below. If the output is different, I want to INSERT 2 rows into the table below.

CREATE table table_z(
seq_num integer  GENERATED BY DEFAULT AS IDENTITY (START WITH 1) NOT NULL,
val NUMBER, 
hash_val VARCHAR2(1000) not NULL PRIMARY KEY, 
clob_val CLOB);

CodePudding user response:

It does not make very much sense to write your own function to compare two LOBs since Oracle already has a COMPARE function in the DBMS_LOB package. It can easily be leveraged in your query like this:

SELECT x.*,
       CASE DBMS_LOB.compare (x.clob1, x.clob2) WHEN 0 THEN 'SAME' ELSE 'DIFFERENT' END    AS comparison
  FROM table_x x;
   SEQ_NUM    VAL         CLOB1         CLOB2    COMPARISON
__________ ______ _____________ _____________ _____________
         1      1 aaaaaaaaaa    aaaaaaaaaa    SAME
         2      1 aaaaa         aaaaaaaaaa    DIFFERENT
         3      2 Xaaaaaaaaa    aaaaaaaaaa    DIFFERENT

To insert the different CLOBs into table_z you could use a SQL statement like this:

INSERT INTO table_z (val, hash_val, clob_val)
    SELECT x1.val, DBMS_CRYPTO.HASH (x1.clob1, 6                          /*DBMS_CRYPTO.HASH_SH512*/
                                                ), x1.clob1
      FROM table_x x1
    UNION ALL
    SELECT x2.val, DBMS_CRYPTO.HASH (x2.clob2, 6                          /*DBMS_CRYPTO.HASH_SH512*/
                                                ), x2.clob2
      FROM table_x x2
     WHERE DBMS_LOB.compare (x2.clob1, x2.clob2) <> 0;

Currently, the PRIMARY KEY you have defined on table_z would prevent the sample records you provided from inserting because the same CLOB appears on multiple rows. You can either remove that primary key or add additional columns to the primary key to allow the data to be inserted.

CodePudding user response:

You can sovle this with a Trigger at "table_x".

https://docs.oracle.com/cd/B13789_01/appdev.101/b10795/adfns_tr.htm

→ In the PL-SQL-Code of this Trigger, you can distinguish between the cases "SAME" and "DIFFERENT".

This Trigger should look like:

CREATE OR REPLACE TRIGGER compare_table_x
  BEFORE INSERT ON table_x
  FOR EACH ROW
DECLARE
    compare table_x.compare;
BEGIN
    IF compare = 'SAME' THEN
      INSERT ...
    ELSE
      INSERT ... 
      INSERT ...
    END IF;
END;
  • Related