SQL - Как вы сравниваете CLOB - PullRequest
8 голосов
/ 21 сентября 2008

в триггере DB2, мне нужно сравнить значение поля CLOB. Что-то вроде:

IF OLD_ROW.CLOB_FIELD != UPDATED_ROW.CLOB_FIELD 

но "! =" Не работает для сравнения CLOB.

Как это можно сравнить?

Отредактировано, чтобы добавить:

Мой триггер должен выполнить какое-то действие, если поле Clob было изменено во время обновления. Вот почему мне нужно сравнить 2 CLOB в коде триггера. Я ищу подробную информацию о том, как это можно сделать

Ответы [ 9 ]

8 голосов
/ 05 ноября 2008

В Oracle 10g вы можете использовать API DBMS_LOB.compare ().

Пример:

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;
7 голосов
/ 21 сентября 2008

Рассчитайте md5 (или другой) хэш сгустков, а затем сравните их. Первоначальный расчет будет медленным, но сравнение будет быстрым и простым. Это может быть хорошим методом, если объем ваших данных меняется не очень часто.

Один из способов вычислить md5 - использовать оператор Java в вашем триггере. Сохраните их в той же таблице (если возможно) или создайте простую вспомогательную таблицу.

6 голосов
/ 22 сентября 2008

Идея Иглкотта хорошая, с оговоркой:

Будьте осторожны с сравнением по хэшу, если ваши данные могут быть атакованы. В настоящее время с вычислительной точки зрения невозможно сгенерировать коллизию хеш-функции для конкретного значения MD5, но можно сгенерировать два разных входа, которые будут генерировать один и тот же MD5 (следовательно, не запускать ваш код). Также возможно генерировать две разные строки с одинаковым префиксом , которые хэшируют к одному и тому же значению.

Если такого рода атака может привести к нарушению целостности вашей системы, и это вызывает беспокойство, вы хотите изучить другие варианты. Проще всего было бы просто переключить хеш-функции, SHA-2 не имеет известных уязвимостей.

Если это не проблема - черт возьми, иди с КПР. Вы не собираетесь за криптографическую безопасность здесь. Только не используйте криптографически слабую функцию, если все это устанавливается на смарт-бомбу, ладно? : -)

2 голосов
/ 17 июня 2009

Идея md5, вероятно, лучшая, но другой альтернативой является создание специального триггера, который срабатывает только при обновлении поля CLOB.

Согласно синтаксической диаграмме , вы можете определить триггер как:

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

Предполагается, что ваше приложение (или тот, кто обновляет таблицу) достаточно умен, чтобы обновлять поле CLOB ТОЛЬКО ПРИ внесении изменений в поле clob, а не при каждом обновлении таблицы.

2 голосов
/ 17 июня 2009

Если значения CLOB 32 КБ или меньше, вы можете привести их как VARCHAR, что позволяет сравнивать, LIKE и выполнять различные строковые функции SQL.

В противном случае вы можете рассмотреть возможность добавления столбца, содержащего хэш CLOB, и изменить приложение (я), чтобы обновлять этот хэш при каждом обновлении CLOB.

1 голос
/ 21 сентября 2008

Я считаю, что невозможно использовать операторы такого типа в полях CLOB из-за способа их хранения.

0 голосов
/ 09 декабря 2012

Генерация хеш-значений и сравнение их - лучший способ ИМХО.

Вот непроверенный код:

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

Обратите внимание, что вам нужна привилегия EXECUTE для модуля DBMS_UTILITY. Вы можете найти больше информации о предоставленном коде SQL PL по следующим ссылкам.

0 голосов
/ 06 сентября 2012

Просто объявите срабатывание триггера, если этот конкретный столбец обновлен.

create trigger T_TRIG on T 
before update of CLOB_COL
...
0 голосов
/ 05 ноября 2008

Использует ли DB2 != для неравных? Стандарт ANSI SQL использует <> для неравных.

...