в триггере DB2 мне нужно сравнить значение поля CLOB. Что-то вроде:
IF OLD_ROW.CLOB_FIELD != UPDATED_ROW.CLOB_FIELD
но "! =" не работает для сравнения CLOB.
Как это сравнить?
Отредактировано для добавления:
Мой триггер должен выполнить какое-то действие, если поле Clob было изменено во время обновления. Это причина, по которой мне нужно сравнить 2 CLOB в коде триггера. Я ищу подробную информацию о том, как это можно сделать


Я считаю, что такие операторы невозможно использовать в полях CLOB из-за способа их хранения.
Вычислите хэш md5 (или другой) для clobs, а затем сравните их. Первоначальный расчет будет медленным, но сравнение будет быстрым и легким. Это может быть хорошим методом, если основная часть ваших данных не меняется очень часто.
Один из способов вычислить md5 - использовать java-оператор в вашем триггере. Сохраните их в той же таблице (если возможно) или создайте простую вспомогательную таблицу.
Идея Иглекотта хороша, но с одной оговоркой:
Будьте осторожны с методом сравнения по хешу, если ваши данные могут подвергнуться атаке. В настоящее время невозможно с вычислительной точки зрения сгенерировать хэш-коллизию для определенного значения MD5, но можно сгенерировать два разных входа, которые будут производить один и тот же MD5 (поэтому не запускать ваш код). Также возможно сгенерировать две разные строки с тот же префикс, которые хешируют одно и то же значение.
Если такая атака может привести к нарушению целостности вашей системы, а это вызывает беспокойство, вам следует изучить другие варианты. Проще всего было бы просто переключить хэш-функции, SHA-2 не имеет известных на данный момент уязвимостей.
Если это не проблема - черт возьми, давай с CRC. Здесь вы не собираетесь использовать криптографическую безопасность. Только не используйте криптографически слабую функцию, если она устанавливается на смарт-бомбу, да? :-)
В 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;
Помните, что «Функции с NULL или недопустимыми входными значениями для параметров возвращают NULL». В некоторых случаях это может быть значительным.
Использует ли DB2 != для не равных? Стандарт ANSI SQL использует <> для обозначения «не равно».
DB2 допускает взаимозаменяемые символы <> и! =. Проблема с этим вопросом заключалась не в операторе, используемом для сравнения, а в том факте, что типы данных больших объектов (BLOB / CLOB) не допускают сравнения на равенство в их собственном типе. Однако DB2 позволяет выражениям SQL приводить верхнюю часть BLOB или CLOB к другому типу данных, включая типы, допускающие операции сравнения.
Если размер CLOB составляет 32 КБ или меньше, вы можете преобразовать их как VARCHAR, что позволяет выполнять сравнение, LIKE и различные строковые функции SQL.
В противном случае вы можете рассмотреть возможность добавления столбца, содержащего хэш CLOB, и изменить приложение (я), чтобы поддерживать этот хэш в актуальном состоянии при каждом обновлении CLOB.
Идея md5, вероятно, лучшая, но другой альтернативой является создание специального триггера, который срабатывает только при обновлении поля CLOB.
Согласно синтаксическая диаграмма, вы должны определить триггер как:
CREATE TRIGGER trig_name AFTER UPDATE OF CLOB_FIELD
//trigger body goes here
Это предполагает, что ваше приложение (или тот, кто обновляет таблицу) достаточно умен, чтобы обновлять поле 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
...
Обратите внимание, что вам нужна привилегия EXECUTE для модуля DBMS_UTILITY. Вы можете найти дополнительную информацию о предоставленном коде SQL PL по следующим ссылкам.
Тогда вам, вероятно, следует подумать об ответе @ igelkott. Вероятно, это лучший способ. Вы вычисляете новую контрольную сумму MD5 и сравниваете ее со старой, и если они отличаются, CLOB изменился. Очень малая вероятность того, что она изменилась и у вас та же контрольная сумма, но не беспокойтесь об этом.