在 DB2 触发器中,我需要比较 CLOB 字段的值。就像是:
IF OLD_ROW.CLOB_FIELD != UPDATED_ROW.CLOB_FIELD
但是“!=”不适用于比较 CLOB。
有什么比较方法?
编辑添加:
如果在更新期间更改了 Clob 字段,我的触发器需要执行一些操作。这就是我需要比较触发器代码中的 2 个 CLOB 的原因。 我正在寻找一些关于如何做到这一点的详细信息
在 Oracle 10g 中,您可以使用 DBMS_LOB.compare() API。
例子:
select * from table t where dbms_lob.compare(t.clob1, t.clob2) != 0
完整的 API:
DBMS_LOB.COMPARE (
lob_1 IN BLOB,
lob_2 IN BLOB,
amount IN INTEGER := 4294967295,
offset_1 IN INTEGER := 1,
offset_2 IN INTEGER := 1)
RETURN INTEGER;
DBMS_LOB.COMPARE (
lob_1 IN CLOB CHARACTER SET ANY_CS,
lob_2 IN CLOB CHARACTER SET lob_1%CHARSET,
amount IN INTEGER := 4294967295,
offset_1 IN INTEGER := 1,
offset_2 IN INTEGER := 1)
RETURN INTEGER;
DBMS_LOB.COMPARE (
lob_1 IN BFILE,
lob_2 IN BFILE,
amount IN INTEGER,
offset_1 IN INTEGER := 1,
offset_2 IN INTEGER := 1)
RETURN INTEGER;
计算 clob 的 md5(或其他)哈希值,然后比较它们。初始计算会很慢,但比较起来又快又容易。如果您的大部分数据不经常更改,这可能是一个好方法。
计算 md5 的一种方法是通过触发器中的 java 语句。将这些保存在同一个表中(如果可能)或构建一个简单的辅助表。
Iglekott 的想法很好,但有一点需要注意:
如果您的数据可能受到攻击,请小心使用哈希比较。目前,为特定的 MD5 值生成哈希冲突在计算上是不可行的,但可以生成两个不同的输入来生成相同的 MD5(因此不会触发您的代码)。也可以生成两个具有相同前缀的不同字符串,这些字符串哈希到相同的值。
如果这种攻击会导致您的系统的完整性受到损害,并且这是一个问题,那么您需要探索其他选项。最简单的方法是简单地切换散列函数,SHA-2 没有当前已知的漏洞。
如果这不是问题 - 见鬼,请使用 CRC。您不会在这里寻求加密安全。如果这些东西被安装在智能炸弹上,请不要使用加密弱功能,'好吧?:-)
md5 想法可能是最好的,但另一种选择是创建一个特殊触发器,该触发器仅在您的 CLOB 字段更新时触发。
根据语法图,您可以将触发器定义为:
CREATE TRIGGER trig_name AFTER UPDATE OF CLOB_FIELD
//trigger body goes here
这是假设您的应用程序(或更新表的任何人)足够聪明,仅在对 clob 字段进行更改时才更新 CLOB 字段,而不是每次更新表时。
如果 CLOB 为 32K 或更少,您可以将它们转换为 VARCHAR,这允许比较、LIKE 和各种 SQL 字符串函数。
否则,您可能需要考虑添加一列来包含 CLOB 的散列,并更改应用程序以使该散列在 CLOB 更新时保持最新。
我相信不可能在 CLOB 字段上使用这类运算符,因为它们的存储方式。
如果该特定列被更新,只需声明触发器即可触发。
create trigger T_TRIG on T
before update of CLOB_COL
...
生成哈希值并比较它们是恕我直言的最佳方法。
这是未经测试的代码:
...
declare leftClobHash integer;
declare rightClobHash integer;
set leftClobHash = (
SELECT DBMS_UTILITY.GET_HASH_VALUE(OLD_ROW.CLOB_FIELD,100,1024) AS HASH_VALUE
FROM SYSIBM.SYSDUMMY1);
set rightClobHash = (
SELECT DBMS_UTILITY.GET_HASH_VALUE(UPDATED_ROW.CLOB_FIELD,100,1024) AS HASH_VALUE
FROM SYSIBM.SYSDUMMY1);
IF leftClobHash != rightClobHash
...
请注意,您需要 DBMS_UTILITY 模块的 EXECUTE 权限。您可以在以下链接中找到有关提供的 SQL PL 代码的更多信息。
DB2 是否使用!=
不等于?ANSI SQL 标准使用<>
不等于。