Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Функция для получения контрольной суммы произвольной строки() / 20 сообщений из 20, страница 1 из 1
16.08.2007, 11:22
    #34731662
OlegA67
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
Добрый день. Нужна функция для хранимой процедуры, которая возвращала бы величину контрольной суммы символьного выражения. Нужно для сравнения двух символьных выражений. Так как выражения достаточно длинные, то хотелось бы чтобы алгоритм был не менее чем 32 битный. Заранее спасибо.
...
Рейтинг: 0 / 0
16.08.2007, 13:46
    #34732320
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
Добрый день.

MD5 на java:

1. Скомпилируйте ява-файл:
--- Digest.java ---
public class Digest {

public static byte[] md5(java.sql.Clob clob) throws Exception {
java.io.InputStream is = clob.getAsciiStream();
byte[] clobBytes = new byte[is.available()];
is.read(clobBytes);
java.security.MessageDigest algorithm = java.security.MessageDigest.getInstance("MD5");
algorithm.reset();
algorithm.update(clobBytes);
return algorithm.digest();
}

}
--- Digest.java end ---

батником вида (путь к sqllib поставьте свой):

--- make.bat ---
set DB2PATH="C:\PROGRAM FILES\IBM\SQLLIB"
set JDK_PATH=%DB2PATH%\java\jdk
set LIBS=%DB2PATH%\java
%JDK_PATH%\bin\javac -extdirs %LIBS% %1
--- make.bat end ---

т.е. выполните:
make.bat Digest.java

2. Поместите Digest.class в каталог %DB2PATH%\Function на сервере.

3. Зарегистрируйте функцию:
---
create function md5(c clob(1m))
RETURNS varchar(16) for bit data
LANGUAGE Java
EXTERNAL NAME 'Digest.md5'
FENCED THREADSAFE
NO SQL
NOT NULL CALL
NO EXTERNAL ACTION
DISALLOW PARALLEL
PARAMETER STYLE java
---

4. Вызовите ее:
values md5(clob('abcdefg'))
...
Рейтинг: 0 / 0
17.08.2007, 11:02
    #34733918
OlegA67
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
Спасибо буду пробовать
...
Рейтинг: 0 / 0
17.08.2007, 18:40
    #34735779
value
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
можно на С

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
void SQL_API_FN hash(
   SQLUDF_VARCHAR_FBD *in,
   SQLUDF_INTEGER     *out,
   SQLUDF_SMALLINT    *innull,
   SQLUDF_SMALLINT    *outnull,
   SQLUDF_TRAIL_ARGS)  {
	if (*innull == - 1 )  {
		*outnull = - 1 ;
	} else {
		unsigned short i;
		for(*out =  0 , i =  0 ;i < in->length;*out = *out *  31  + (in->data[i++] & 0xFF));
		*outnull =  0 ;
	}
	return;
}

Код: plaintext
1.
2.
3.
4.
5.
6.
CREATE FUNCTION RATE.HASH
(HASH VARCHAR( 32000 ) FOR BIT DATA)
RETURNS INTEGER
SPECIFIC HASH EXTERNAL NAME 'db2hash!hash'
NOT FENCED RETURNS NULL ON NULL INPUT
DETERMINISTIC NO SQL NO EXTERNAL ACTION
LANGUAGE C PARAMETER STYLE SQL ALLOW PARALLEL;
...
Рейтинг: 0 / 0
20.08.2007, 11:41
    #34737922
OlegA67
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
Добрый день Марк.
Все выполнил согласно вашей инструкции.Всепрошло гладко, но когда решил проверить функцию следующим запросом
Код: plaintext
SELECT md5(clob('asdsadf')) FROM sysibm.sysdummy1
, выходит следующая ошибка
Код: plaintext
1.
2.
SQL4302N  Процедура или пользовательская функция "DBADMIN.MD5", 
уникальное имя "SQL070820155819000" прервана из-за исключительной ситуации 
"class COM.ibm.db2.app.ClobWithDB2Buffer".  SQLSTATE= 38501 
По коду ошибки SQL4302N почитал, что надо сделать отладку подпрограммы, чтобы не возникала иключительная ситуация. Честоно говоря не понял что надо делать. Нужен ваш совет.
...
Рейтинг: 0 / 0
20.08.2007, 12:32
    #34738138
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
OlegA67Добрый день Марк.
Все выполнил согласно вашей инструкции.Всепрошло гладко, но когда решил проверить функцию следующим запросом
Код: plaintext
SELECT md5(clob('asdsadf')) FROM sysibm.sysdummy1
, выходит следующая ошибка
Код: plaintext
1.
2.
SQL4302N  Процедура или пользовательская функция "DBADMIN.MD5", 
уникальное имя "SQL070820155819000" прервана из-за исключительной ситуации 
"class COM.ibm.db2.app.ClobWithDB2Buffer".  SQLSTATE= 38501 
По коду ошибки SQL4302N почитал, что надо сделать отладку подпрограммы, чтобы не возникала иключительная ситуация. Честоно говоря не понял что надо делать. Нужен ваш совет.Добрый день.
Посмотрите в db2diag.log, похоже что там какие-то проблемы с размером буфера.
Какая у вас версия БД?
Что выдает
%db2path%\java\jdk\bin\java -version
?
По-хорошему, правильно бы так сделать (для больших lob особенно):
--- Digest.java ---
import java.security.MessageDigest;
import java.security.DigestInputStream;

public class Digest {
public static final int BUF_LEN = 65536;

public static byte[] digest(java.sql.Clob clob) throws Exception {
byte[] buf = new byte[BUF_LEN];
MessageDigest alg = MessageDigest.getInstance("MD5");
DigestInputStream in = new DigestInputStream(clob.getAsciiStream(), alg);
while (in.read(buf, 0, BUF_LEN)!=-1);
in.close();
return alg.digest();
}

}
--- Digest.java ---
После компиляции и копирования нового файла Digest.class в ...\sqllib\funcion сделайте call sqlj.refresh_classes() и поробуйте вызвать функцию снова.
Если опять вывалится, покажите db2diag.log
...
Рейтинг: 0 / 0
20.08.2007, 13:04
    #34738277
OlegA67
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
Код: plaintext
db2level
DB21085I Экземпляр "DB2" использует "32" бит и выпуск DB2 "SQL08027" с
идентификатором уровня "03080106".
Информационные элементы суть "DB2 v8.1.14.292", "s061108", "WR21377", а также
пакет исправлений "14".
Продукт установлен в "G:\PROGRA~1\IBM\SQLLIB".
Код: plaintext
java -version
java version "1.4.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1)
Classic VM (build 1.4.1, J2RE 1.4.1 IBM Windows 32 build cn1411-20040301a (JIT e
nabled: jitc))

Файл заново скомпилировал и скопировал в \FUNCTION
Я так понял что команду call sqlj.refresh_classes() , надо запустить из командного окна DB2. Но на ней вышла ошибка
SQL0444N Подпрограмма "SQLJ.REFRESH_CLASES" (с уникальным именем "")
реализуется при помощи кода функции "", находящегося в библиотеке или в пути
"". Этот код функции недоступен. Код причины: "". SQLSTATE=42724
Вот фрагмент db2diag.log
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
 2007 - 08 - 20 - 18 . 01 . 45 . 045000 + 540  I18507673H299      LEVEL: Warning
PID     :  3512                  TID  :  3724         PROC : db2fmp.exe
INSTANCE: DB2                  NODE :  000 
FUNCTION: DB2 UDB, BSU Java support, sqlejCallJavaRoutine_dll, probe: 370 
MESSAGE : Java routine exited with exception.

 2007 - 08 - 20 - 18 . 01 . 45 . 045000 + 540  E18507974H375      LEVEL: Warning
PID     :  3512                  TID  :  3724         PROC : db2fmp.exe
INSTANCE: DB2                  NODE :  000 
FUNCTION: DB2 UDB, BSU Java support, sqlejLogException, probe: 10 
MESSAGE : ADM10000W  A Java exception has been caught.  The Java stack 
          traceback has been written to the db2diag.log.

 2007 - 08 - 20 - 18 . 01 . 45 . 045000 + 540  I18508351H518      LEVEL: Warning
PID     :  3512                  TID  :  3724         PROC : db2fmp.exe
INSTANCE: DB2                  NODE :  000 
FUNCTION: DB2 UDB, BSU Java support, sqlejLogException, probe: 10 
DATA # 1  : String,  155  bytes
java.lang.IncompatibleClassChangeError: class COM.ibm.db2.app.ClobWithDB2Buffer does not implement interface java.sql.Clob
	at Digest.md5(Digest.java: 4 )
DATA # 2  : Hexdump,  4  bytes
0x01DDF3F4 :  0000   0000                                   ....

 2007 - 08 - 20 - 18 . 01 . 45 . 045000 + 540  E18508871H375      LEVEL: Warning
PID     :  3512                  TID  :  3724         PROC : db2fmp.exe
INSTANCE: DB2                  NODE :  000 
FUNCTION: DB2 UDB, BSU Java support, sqlejLogException, probe: 10 
MESSAGE : ADM10000W  A Java exception has been caught.  The Java stack 
          traceback has been written to the db2diag.log.

 2007 - 08 - 20 - 18 . 01 . 45 . 045000 + 540  I18509248H518      LEVEL: Warning
PID     :  3512                  TID  :  3724         PROC : db2fmp.exe
INSTANCE: DB2                  NODE :  000 
FUNCTION: DB2 UDB, BSU Java support, sqlejLogException, probe: 10 
DATA # 1  : String,  155  bytes
java.lang.IncompatibleClassChangeError: class COM.ibm.db2.app.ClobWithDB2Buffer does not implement interface java.sql.Clob
	at Digest.md5(Digest.java: 4 )
DATA # 2  : Hexdump,  4  bytes
0x01DDF410 :  0000   0000                                   ....

 2007 - 08 - 20 - 18 . 01 . 45 . 045000 + 540  I18509768H384      LEVEL: Warning
PID     :  3512                  TID  :  3724         PROC : db2fmp.exe
INSTANCE: DB2                  NODE :  000 
FUNCTION: DB2 UDB, routine_infrastructure, sqlerJavaCallRoutine, probe: 30 
MESSAGE : Error from DB2ER CallUDF.  RC:
DATA # 1  : Hexdump,  4  bytes
0x01DDF968 : 32EF FFFF                                   2 ...

Ошибка осталась
...
Рейтинг: 0 / 0
20.08.2007, 13:26
    #34738354
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
call sqlj.refresh_cla ss es()
, а не
call sqlj.refresh_cla s es()
...
Рейтинг: 0 / 0
20.08.2007, 13:43
    #34738413
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
Mark Barinstein
public static byte[] digest(java.sql.Clob clob) throws Exception {
Упс!
Ошибочка вышла: функцию в java коде надо назвать md5, а не digest.
Чтобы с предложением
EXTERNAL NAME 'Digest.md5'
в create function совпадало.
...
Рейтинг: 0 / 0
20.08.2007, 17:32
    #34739532
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
Щас добрался до v8.
Действительно, в отличии от v9, этот код не работает почему-то.

Класс и регистрацию функции придется переписать:
--- Digest.java ---
import java.security.MessageDigest;
import java.security.DigestInputStream;
import COM.ibm.db2.app.*;

public class Digest extends UDF {
public static final int BUF_LEN = 65536;

public void md5(Blob blob, Blob r__) throws Exception {
byte[] buf = new byte[BUF_LEN];
MessageDigest alg = MessageDigest.getInstance("MD5");
DigestInputStream in = new DigestInputStream(blob.getInputStream(), alg);
while (in.read(buf, 0, BUF_LEN)!=-1);
in.close();
int cnum = alg.digest(buf, 0, BUF_LEN);
Blob res = Lob.newBlob();
res.getOutputStream().write(buf, 0, cnum);
set(2, res);
}

}
--- Digest.java ---

--- MD5.sql ---
create function md5(c blob(1m))
RETURNS varchar(16) for bit data
LANGUAGE Java
EXTERNAL NAME 'Digest.md5'
FENCED THREADSAFE
NO SQL
NOT NULL CALL
NO EXTERNAL ACTION
DISALLOW PARALLEL
PARAMETER STYLE db2general;
--- MD5.sql ---

вызов:
values md5(blob('12345'))
у меня это работает на v8 и на v9...
...
Рейтинг: 0 / 0
21.08.2007, 05:33
    #34740430
OlegA67
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
Добрый день Марк.
Что-то я опять, где-то напартачил. Начну по порядку.
1. Переписал файл Digest.java
2. Cкомпилировал Digest.java получид файл Digest.class
3. Запустил по новой make.bat Disgest.java (на всякий случай)
4. Скопировал файл Digest.class в папку FUNCTION
5. Отбросил функцию md5
6. Cоздал ее заново
Запускаю из командного окна DB2
db2 values md5(blob('asdf')) и все висит, закрыл это окно, открыл новое
набрал на всякий случай db2 call sqlj.refresh_classes(), а потом заново
db2 values md5(blob('asdf')) висит по прежнему
Все это проделал на другом сервере, там все замечательно отработало. Но мне то нужна эта функция именно на этом сервере ((. При зависании команды в db2diag.log ничего не пишется
...
Рейтинг: 0 / 0
21.08.2007, 09:42
    #34740592
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
OlegA67Что-то я опять, где-то напартачил. Начну по порядку...Очень странно...
Проверьте, правильно ли вы задали команду create function.
В отличии от 1-го варианта там изменился тип параметра (clob->blob) и parameter style (java->db2general).
...
Рейтинг: 0 / 0
21.08.2007, 11:24
    #34740966
OlegA67
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
Команду create function, я копировал прямо отсюда, ошибиться не мог.Буду искать ошибку
...
Рейтинг: 0 / 0
22.08.2007, 04:40
    #34743427
OlegA67
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
Почти как в анекдоте, после перезагрузки сервера все заработало. Еще раз спасибо.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
19.07.2010, 10:57
    #36747625
OlegA67
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
Mark Barinstein,

Добрый день Mark.
Решил перенести вашу функцию md5 на новый сервер DB2. Но в отличие от старого он развернут
на Линуксе(RHE). И сразу же возникли вопросы.
Как создать заново файл Digest.class под Линукс.
Не совсем ясно как его скомпилить, ввиду отсутствия папки JDK.
На самом сервере графика отсутствует, так что пришлось устанавливать DB2 в ручном режиме и похоже стоит там все по минимуму. Версия DB2 8.2
...
Рейтинг: 0 / 0
19.07.2010, 14:55
    #36748309
mustaccio
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
OlegA67
Как создать заново файл Digest.class под Линукс.

Его не нужно создавать заново - достаточно просто скопировать существующий.

OlegA67
Не совсем ясно как его скомпилить, ввиду отсутствия папки JDK.


JDK всегда устанавливается вместе с DB2. Ищите в /opt/IBM/db2/V8.2/java
...
Рейтинг: 0 / 0
20.07.2010, 04:53
    #36749455
OlegA67
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
mustaccio
Его не нужно создавать заново - достаточно просто скопировать существующий.

В начале так и сделал, скопировал файл Digest.class который получил под виндой
в папку /home/db2admin/sqllib/function/

mustaccio
JDK всегда устанавливается вместе с DB2. Ищите в /opt/IBM/db2/V8.2/java

В /opt/IBM/db2/V8.1/java папка JDK также отсутствует

В настройка менеджера для параметра (JDK_PATH) прописан не существующий каталог
Java Development Kit installation path (JDK_PATH) = /opt/IBMJava2-142

Саму функцию я скомпилил, но при обращение к ней
SELECT md5(blob('asdsadf')) FROM sysibm.sysdummy1
выводит следующую ошибку

SQL4301N Java or .NET interpreter startup or communication failed, reason
code "1". SQLSTATE=58004
Explanation:

An error occurred while attempting to start or communicate with a
Java interpreter. The reason codes are:


1 Java environment variables or Java database configuration
parameters are invalid.

Вопрос тогда такой, как доустановить Java Development Kit ?
...
Рейтинг: 0 / 0
20.07.2010, 07:53
    #36749466
mustaccio
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
OlegA67
В /opt/IBM/db2/V8.1/java папка JDK также отсутствует



Это весьма подозрительно. JDK обычно устанавливается автоматически, хотите вы того или нет. Более того, посторонние ЖДК, не !ВМ-овского производства, с ДБ2 работают ненадежно. Я бы попробовал переустановить ДБ2.
...
Рейтинг: 0 / 0
20.07.2010, 11:55
    #36749811
OlegA67
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
mustaccio
Это весьма подозрительно. JDK обычно устанавливается автоматически, хотите вы того или нет.

Вычитал следующее про установку ДБ2
Код: plaintext
1.
При использование других способов (с использованием SMIT или сценария db2_install) пакет Java SDK 
не устанавливается 

Надо читать как этот пакет до установить вручную
...
Рейтинг: 0 / 0
20.07.2010, 12:44
    #36749951
OlegA67
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для получения контрольной суммы произвольной строки()
До установил Java SDK вручную, но ошибка все равно осталось, только поменялся код причины с 1 на 2

SQL4301N Java or .NET interpreter startup or communication failed, reason
code "2". SQLSTATE=58004

SQL4301N Java or .NET interpreter startup or communication failed, reason code "2 ".

Explanation:

An error occurred while attempting to start or communicate with a
Java interpreter. The reason codes are:


1 Java environment variables or Java database configuration
parameters are invalid.

2 A Java Native Interface call to the Java interpreter failed.
...
Рейтинг: 0 / 0
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Функция для получения контрольной суммы произвольной строки() / 20 сообщений из 20, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]