SQL - 如何比较 CLOB

发布于 2024-07-05 23:46:09 字数 315 浏览 12 评论 0 原文

在 DB2 触发器中,我需要比较 CLOB 字段的值。 类似于:

IF OLD_ROW.CLOB_FIELD != UPDATED_ROW.CLOB_FIELD 

但是“!=”不适用于比较 CLOB。

有什么方法可以比较呢?

编辑添加:

如果 Clob 字段在更新期间发生更改,我的触发器需要执行一些操作。 这就是我需要比较触发代码中的 2 个 CLOB 的原因。 我正在寻找一些有关如何做到这一点的详细信息

in a DB2 trigger, I need to compare the value of a CLOB field.
Something like:

IF OLD_ROW.CLOB_FIELD != UPDATED_ROW.CLOB_FIELD 

but "!=" does not work for comparing CLOBs.

What is the way to compare it?

Edited to add:

My trigger needs to do some action if the Clob field was changed during an update. This is the reason I need to compare the 2 CLOBs in the trigger code.
I'm looking for some detailed information on how this can be done

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

不打扰别人 2024-07-12 23:46:09

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

In Oracle 10g you can use DBMS_LOB.compare() API.

Example:

select * from table t where dbms_lob.compare(t.clob1, t.clob2) != 0

Full 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;
誰ツ都不明白 2024-07-12 23:46:09

计算 clob 的 md5(或其他)哈希值,然后比较它们。 初始计算会很慢,但比较快速且容易。 如果您的大部分数据不经常更改,这可能是一个好方法。

计算 md5 的一种方法是通过触发器中的 java 语句。 将它们保存在同一个表中(如果可能)或构建一个简单的辅助表。

Calculate the md5 (or other) hash of the clobs and then compare these. Initial calculation will be slow but comparison is fast and easy. This could be a good method if the bulk of your data doesn't change very often.

One way to calculate md5 is through a java statement in your trigger. Save these in the same table (if possible) or build a simple auxiliary table.

泅渡 2024-07-12 23:46:09

md5 的想法可能是最好的,但另一种选择是创建一个特殊的触发器,仅在 CLOB 字段更新时触发。

根据 语法图,您可以将触发器定义为:

CREATE TRIGGER trig_name AFTER UPDATE OF CLOB_FIELD 
//trigger body goes here

这假设您的应用程序(或更新表的任何人)足够聪明,仅当存在对 clob 字段进行的更改,而不是每次更新表时都会更改。

The md5 idea is probably the best, but another alternative is to create a special trigger that only fires when your CLOB field is updated.

According to the syntax diagram, you would define the trigger as:

CREATE TRIGGER trig_name AFTER UPDATE OF CLOB_FIELD 
//trigger body goes here

This is assuming that your application (or whoever is updating the table) is smart enough to update the CLOB field ONLY WHEN there has been a change made to the clob field, and not every time your table is updated.

梦毁影碎の 2024-07-12 23:46:09

Iglekott 的想法是一个很好的想法,但有一个警告:

如果您的数据可能受到攻击,请小心使用哈希比较。 目前,为特定 MD5 值生成哈希冲突在计算上不可行,但可以生成两个不同的输入来生成相同的 MD5(因此不会触发您的代码)。 还可以生成两个具有相同前缀的不同字符串,并哈希为相同的值。

如果这种攻击可能会导致系统的完整性受到损害,并且这是一个令人担忧的问题,那么您需要探索其他选择。 最简单的方法就是简单地切换哈希函数,SHA-2 没有当前已知的漏洞。

如果这不是一个问题——见鬼,就选择 CRC。 您不会在这里追求加密安全。 如果这个东西安装在智能炸弹上,就不要使用密码学上较弱的功能,好吗? :-)

Iglekott's idea is a good one, with a caveat:

Be careful with compare-by-hash if your data is likely to get attacked. It is not currently computationally feasible to generate a hash collision for a specific MD5 value, but it is possible to generate two different inputs that will produce the same MD5 (therefore not triggering your code). It is also possible to generate two different strings with the same prefix that hash to the same value.

If that kind of attack can lead to the integrity of your system being compromised, and that's a concern, you want to explore other options. The easiest would be simply switching the hash functions, SHA-2 does not have currently known vulnerabilities.

If this isn't a concern -- hell, go with CRC. You aren't going for cryptographic security here. Just don't go with a cryptographically weak function if this stuff is getting installed on a smartbomb, 'mkay? :-)

少女的英雄梦 2024-07-12 23:46:09

如果 CLOB 为 32K 或更少,您可以将它们转换为 VARCHAR,这允许比较、LIKE 和各种 SQL 字符串函数。

否则,您可能需要考虑添加一列来包含 CLOB 的哈希值,并更改应用程序以在 CLOB 更新时保持该哈希值最新。

If the CLOBs are 32K or less, you can cast them as VARCHAR, which allows comparison, LIKE, and various SQL string functions.

Otherwise, you may want to consider adding a column to contain the hash of the CLOB and change the application(s) to keep that hash up to date whenever the CLOB is updated.

明明#如月 2024-07-12 23:46:09

DB2 是否使用 != 表示不等于? ANSI SQL 标准使用 <> 表示不等于。

Does DB2 use != for not equals? The ANSI SQL Standard uses <> for not equals.

埋葬我深情 2024-07-12 23:46:09

我认为由于它们的存储方式,不可能在 CLOB 字段上使用此类运算符。

I believe it's not possible to use these kind of operators on CLOB fields, because of the way they're stored.

深白境迁sunset 2024-07-12 23:46:09

只需声明触发器在更新该特定列时触发即可。

create trigger T_TRIG on T 
before update of CLOB_COL
...

Just declare the trigger to fire if that particular column is updated.

create trigger T_TRIG on T 
before update of CLOB_COL
...
妄想挽回 2024-07-12 23:46:09

生成哈希值并比较它们是恕我直言的最佳方法。

以下是未经测试的代码:

...
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 代码的更多信息。

Generating a hash value and comparing them is the best way IMHO.

Here is the untested code:

...
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
...

Note that you need EXECUTE privilege on the DBMS_UTILITY module. You can find more information about the provided SQL PL code in the following links.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文