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;
我有一个 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;