Oracle 比较同一行中的 clob

Oracle comparing clobs in same row

我有一个 table,其中包含一些列和两个 CLOBS。

在某些情况下,两个 CLOBS 包含完全相同的值,而在其他情况下,它们包含不同的值。 或一个或两个 CLOBS 可以为空或 NULl。

我创建了一个函数,我想调用它来比较两个 CLOBS 以确定值是 'SAME' 还是不同。


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 

根据上述查询的输出,如果 SHA512 输出显示差异相同,我想将 1 行插入到下面的新 table 中。如果输出不同,我想在下面的 table 中插入 2 行。

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);

编写自己的函数来比较两个 LOB 没有多大意义,因为 Oracle 在 DBMS_LOB 包中已经有一个 COMPARE 函数。它可以很容易地在您的查询中使用,如下所示:

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

要将不同的 CLOB 插入 table_z,您可以使用这样的 SQL 语句:

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;

目前,您在 table_z 上定义的 PRIMARY KEY 会阻止您提供的示例记录插入,因为同一个 CLOB 出现在多行上。您可以删除该主键或向主键添加额外的列以允许插入数据。

您可以在“table_x”处使用触发器解决此问题。

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

→ 在这个Trigger的PL-SQL-Code中,可以区分“SAME”和“DIFFERENT”的情况。

此触发器应如下所示:

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;