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