oracle将字符串转成hash,Oracle SQLID 与 Hash_value 算法及转换

在Oracle 10g中,SQL被以 SQLID 描述,此前SQL是通过HASH VALUE来表述的。

这两者具有同源的对应关系,最早 Tanel Poder 对这个问题进行过揭秘。

这个问题的本质是:

对于Library Cache对象,Oracle使用MD5算法进行哈希,生成一个128位的Hash Value,其中低32位作为HASH VALUE显示,SQL_ID则取了后64位。

这两者可以相互转换,在Oracle 10g中,提供了一个包函数,用于转换:

SQL> select sql_id,hash_value,dbms_utility.SQLID_TO_SQLHASH(sql_id) convert from v$sql where rownum <9;

SQL_ID          HASH_VALUE    CONVERT

------------- ---------- ----------

1fkh93md0802n 3657695316 3657695316

b39dwjz0a404c 3231842444 3231842444

93s9k7wvfs05m  921436339  921436339

50ph8shy0408h 1006764304 1006764304

g9sqp5dpas0mw 1789657724 1789657724

0j7j10ykus0uy 2779513694 2779513694

bwsx6utfbh15q 1555563702 1555563702

79uvsz1g1c168 1578501320 1578501320

8 rows selected.可以看到dbms_utility的转换结果与数据库存储一致。Tanel Poder解析了这个算法:

SQL> define 1 = 1fkh93md0802n

SQL> @1

SQL>

SQL> select

2       lower(trim('&1')) sql_id

3    , trunc(mod(sum((instr('0123456789abcdfghjkmnpqrstuvwxyz',substr(lower(trim('&1')),level,1))-1)

4                  *power(32,length(trim('&1'))-level)),power(2,32))) hash_value

5  from

6       dual

7  connect by

8       level <= length(trim('&1'))

9  /

old   2:     lower(trim('&1')) sql_id

new   2:     lower(trim('1fkh93md0802n')) sql_id

old   3:   , trunc(mod(sum((instr('0123456789abcdfghjkmnpqrstuvwxyz',substr(lower(trim('&1')),level,1))-1)

new   3:   , trunc(mod(sum((instr('0123456789abcdfghjkmnpqrstuvwxyz',substr(lower(trim('1fkh93md0802n')),level,1))-1)

old   4:            *power(32,length(trim('&1'))-level)),power(2,32))) hash_value

new   4:            *power(32,length(trim('1fkh93md0802n'))-level)),power(2,32))) hash_value

old   8:     level <= length(trim('&1'))

new   8:     level <= length(trim('1fkh93md0802n'))

SQL_ID                 HASH_VALUE

-------------------------------- ----------

1fkh93md0802n             3657695316可以看到以上的转换过程。

参考:

http://blog.tanelpoder.com/2009/02/22/sql_id-is-just-a-fancy-representation-of-hash-value

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值