Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 sql_id из sql_text  [new]
Деев И.
Member

Откуда: отсюда
Сообщений: 783
Tanel Poder недавно привел в своем блоге ссылку на методполучения sql_id из текста запроса.
Пытался воспроизвести в PL/SQL - не удается.

Как ни крутил, но то значение MD5, что получается с помощью dbms_crypto.Hash, отличается от того, что выводится в x$kglob.

Как у того товарища на Python получается то, что нужно - загадка...
17 апр 10, 09:55    [8644478]     Ответить | Цитировать Сообщить модератору
 Re: sql_id из sql_text  [new]
PA3YM
Member

Откуда:
Сообщений: 298
Деев И.
Tanel Poder недавно привел в своем блоге ссылку на методполучения sql_id из текста запроса.
Пытался воспроизвести в PL/SQL - не удается.

Как ни крутил, но то значение MD5, что получается с помощью dbms_crypto.Hash, отличается от того, что выводится в x$kglob.

Как у того товарища на Python получается то, что нужно - загадка...

Получается ... в сравнении с консольным md5sum просто байты в каждой четверке чуть перемешаны ;-)
# printf "select 'Slavik' from dual\x0" >zzz
# md5sum <zzz
903e487aadb45a55ab90e1245d77e7e3  -
KGLNAHSV
--------------------------------------------------------------------------------
7a483e90555ab4ad24e190abe3e7775d
17 апр 10, 10:52    [8644528]     Ответить | Цитировать Сообщить модератору
 Re: sql_id из sql_text  [new]
PA3YM
Member

Откуда:
Сообщений: 298
SQL> set serveroutput on
SQL> declare
  2  l_in_val varchar2(2000) := 'select ''Slavik'' from dual'||chr(0);
  3  l_hash      raw(2000);
  4  begin
  5    l_hash := dbms_crypto.hash (
  6       src => UTL_I18N.STRING_TO_RAW (l_in_val, 'AL32UTF8'),
  7       typ => dbms_crypto.hash_md5
  8    );
  9    dbms_output.put_line('Hash='||l_hash);
 10  end;
 11  /
Hash=903E487AADB45A55AB90E1245D77E7E3

PL/SQL procedure successfully completed.
17 апр 10, 11:18    [8644545]     Ответить | Цитировать Сообщить модератору
 Re: sql_id из sql_text  [new]
Деев И.
Member

Откуда: отсюда
Сообщений: 783
Либо

declare
  l_res raw(32);
begin  
  l_res := dbms_crypto.Hash(to_clob('select ''Slavik'' from dual'||chr(0)), dbms_crypto.HASH_MD5);
  dbms_output.put_line(l_res);
end; 

Спасибо за замечание по поводу перемешивания байтов! Не заметил сразу...
17 апр 10, 11:33    [8644558]     Ответить | Цитировать Сообщить модератору
 Re: sql_id из sql_text  [new]
Деев И.
Member

Откуда: отсюда
Сообщений: 783
лучше, действительно, вариант с аргументом типа RAW - иначе глюки могут быть, если с русским текстом в разных кодировках работать...
17 апр 10, 11:43    [8644569]     Ответить | Цитировать Сообщить модератору
 Re: sql_id из sql_text  [new]
borka66
Member

Откуда:
Сообщений: 39
Спасибо! Я знал что на этот форум можно положится.
Для всех лентяев:
function GET_SQL_ID(i_sql in varchar2) return varchar2 is
  l_b32   varchar2(32) := '0123456789abcdfghjkmnpqrstuvwxyz';
  l_lang  varchar2(32) := SYS_CONTEXT('USERENV','LANGUAGE');
  l_md5   raw(128);
  l_hex   varchar2(32);
  l_value number(30);
  l_sqlid varchar2(32);
 begin
  l_lang := substr(l_lang,instr(l_lang,'.')+1);
  l_md5 := DBMS_CRYPTO.hash(src=>UTL_I18N.STRING_TO_RAW(i_sql||chr(0),l_lang), typ=>DBMS_CRYPTO.HASH_MD5);
  for k in 1 .. 4 loop
   for i in 1 .. 4 loop
    l_hex := substr(substr(l_md5,-8*k,8),2*i-1,2) || l_hex;
   end loop;
  end loop;
  l_value := to_number(substr(l_hex,-16,8)||substr(l_hex,-8), 'XXXXXXXXXXXXXXXX');
  loop
   l_sqlid := substr(l_b32,mod(l_value,32)+1,1) || l_sqlid;
   l_value := trunc(l_value/32);
   exit when l_value = 0;
  end loop;
  return lpad(l_sqlid,13,'0');
 end GET_SQL_ID;
3 мар 11, 14:00    [10319634]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить