[20240512]建立完善sql_idz.sh脚本.txt

来源:这里教程网 时间:2026-03-03 20:01:03 作者:

[20240512]建立完善sql_idz.sh脚本.txt --//使用该脚本计算存在小问题,cat 文件中如果有ascii=0,cat时会过滤掉,一般table namespac是1. --//在尾部追加\01\0\0\0,而sql语句追加的是\0.我以前代码写死的.修改更加灵活一些. --//增加参数3,如果不输入缺省等于\0. --//增加计算exact_matching_signature, force_matching_signature值,当然文本格式要经过格式化输入正确才行. --//当参数2 = 3时 ,计算exact_matching_signature, force_matching_signature --//顺便做了小量改动. --//测试看看: SYS@test> select * from v$db_object_cache where name = 'DEPT'   2   @prxx ============================== OWNER                         : SCOTT NAME                          : DEPT DB_LINK                       : NAMESPACE                     : TABLE/PROCEDURE TYPE                          : TABLE SHARABLE_MEM                  : 4072 LOADS                         : 1 EXECUTIONS                    : 0 LOCKS                         : 0 PINS                          : 0 KEPT                          : NO CHILD_LATCH                   : 93026 INVALIDATIONS                 : 0 HASH_VALUE                    : 2956815202 LOCK_MODE                     : NONE PIN_MODE                      : NONE STATUS                        : VALID TIMESTAMP                     : 2019-08-17/21:38:48 PREVIOUS_TIMESTAMP            : LOCKED_TOTAL                  : 2 PINNED_TOTAL                  : 2 PROPERTY                      : FULL_HASH_VALUE               : d228ecb73e713f600e1f246bb03d6b62 CON_ID                        : 3 CON_NAME                      : TEST01P ADDR                          : 000007FF002CD2E0 EDITION                       : PL/SQL procedure successfully completed. $ ./sql_idz.sh  'DEPT.SCOTT.TEST01P'  0 "\01\0\0\0" sql_text = DEPT.SCOTT.TEST01P\01\0\0\0 full_hash_value(16) = D228ECB73E713F600E1F246BB03D6B62 hash_value(10) = 2956815202 sql_id(32) = 0w7t4dfs3uuv2 sql_id(32) = 0w7t4dfs3uuv2 sql_id(32) = 0w7t4dfs3uuv2 --//注意:表的full_hash_value格式是 table.owner.pdbname\01\0\0\0. --///如果11g,没有.pdbname. $ ./sql_idz.sh  'DEPT.SCOTT.TEST01P\01\0\0'  0 sql_text = DEPT.SCOTT.TEST01P\01\0\0\0 full_hash_value(16) = D228ECB73E713F600E1F246BB03D6B62 or d228ecb73e713f600e1f246bb03d6b62 hash_value(10) = 2956815202 sql_id(32) = 0w7t4dfs3uuv2 sql_id(32) = 0w7t4dfs3uuv2 sql_id(32) = 0w7t4dfs3uuv2 $ ./sql_idz.sh  'DEPT.SCOTT.TEST01P\01\0\0\0'  3 sql_text = DEPT.SCOTT.TEST01P\01\0\0\0 full_hash_value(16) = D228ECB73E713F600E1F246BB03D6B62 or d228ecb73e713f600e1f246bb03d6b62 xxxxx_matching_signature(10) = 1017572085745937250 hash_value(10) = 2956815202 sql_id(32) = 0w7t4dfs3uuv2 sql_id(32) = 0w7t4dfs3uuv2 sql_id(32) = 0w7t4dfs3uuv2 --//以上方法计算都正确. --//看看sql语句: SYS@test> select sysdate from dual ; SYSDATE ------------------- 2024-05-12 20:47:25 --//注意分号前有1个空格. SYS@test> @ hash HASH_VALUE SQL_ID        CHILD_NUMBER KGL_BUCKET PLAN_HASH_VALUE HASH_HEX   SQL_EXEC_START      SQL_EXEC_ID ---------- ------------- ------------ ---------- --------------- ---------- ------------------- -----------  409144692 f0wzs9nc663bn            0      68980      1388734953  18630d74  2024-05-12 20:47:25    16777216 $ ./sql_idz.sh  'select sysdate from dual '  0 sql_text = select sysdate from dual \0 full_hash_value(16) = 2F36775C951D24FEE073F84D18630D74 hash_value(10) = 409144692 sql_id(32) = f0wzs9nc663bn sql_id(32) = f0wzs9nc663bn sql_id(32) = f0wzs9nc663bn --//409144692%2^17 = 68980 --//完全能对上!! --//测试exact_matching_signature, force_matching_signature看看. SCOTT@test01p> select 1 from dual ;          1 ----------          1 SCOTT@test01p> @ hash HASH_VALUE SQL_ID        CHILD_NUMBER KGL_BUCKET PLAN_HASH_VALUE HASH_HEX   SQL_EXEC_START      SQL_EXEC_ID ---------- ------------- ------------ ---------- --------------- ---------- ------------------- ----------- 4041728556 054n8y7sfgsjc            0     123436      1388734953  f0e7e22c  2024-05-15 20:41:03    16777216 SCOTT@test01p> select sql_text,exact_matching_signature, force_matching_signature from v$sqlarea where sql_id='054n8y7sfgsjc'; SQL_TEXT           EXACT_MATCHING_SIGNATURE FORCE_MATCHING_SIGNATURE ------------------ ------------------------ ------------------------ select 1 from dual     12518811395313535686     10559245208183986822 --//EXACT_MATCHING_SIGNATURE=12518811395313535686, FORCE_MATCHING_SIGNATURE=10559245208183986822. $ sql_idz.sh  'SELECT 1 FROM DUAL'  3 sql_text = SELECT 1 FROM DUAL full_hash_value(16) = D9F6DF623A086C51ADBBC0A2F3C68AC6 or d9f6df623a086c51adbbc0a2f3c68ac6 xxxxx_matching_signature(10) = -5927932678396015930 hash_value(10) = 4089875142 sql_id(32) = avfy0nbtwd2q6 sql_id(32) = avfy0nbtwd2q6 sql_id(32) = avfy0nbtwd2q6 --//注意要统一格式化,小写变成大写,dual后面没有空格. --//超出范围了. --//2^64-5927932678396015930 = 12518811395313535686 正好对上!! $ sql_idz.sh  'SELECT :"SYS_B_0" FROM DUAL' 3 sql_text = SELECT :"SYS_B_0" FROM DUAL full_hash_value(16) = A995B29240A442869289F992520D5A86 or a995b29240a442869289f992520d5a86 xxxxx_matching_signature(10) = -7887498865525564794 hash_value(10) = 1376606854 sql_id(32) = 952gtk990uqn6 sql_id(32) = 952gtk990uqn6 sql_id(32) = 952gtk990uqn6 --//超出范围了. --//2^64 -7887498865525564794 = 10559245208183986822 --//再次改写,我有点懒,如果xxxxx_matching_signature那行第1个是负数取最后1个对应matching_signature. $ sql_idz.sh  'SELECT :"SYS_B_0" FROM DUAL' 3 sql_text = SELECT :"SYS_B_0" FROM DUAL full_hash_value(16) = A995B29240A442869289F992520D5A86 or a995b29240a442869289f992520d5a86 xxxxx_matching_signature(10) = -7887498865525564794 or  10559245208183986822 hash_value(10) = 1376606854 sql_id(32) = 952gtk990uqn6 sql_id(32) = 952gtk990uqn6 sql_id(32) = 952gtk990uqn6 --//OK --//sql_idz.sql,注意脚本里面的^M在insert模式下按ctrl+q,ctrl+M输入(windows版本),ctrl+v,ctrl+M输入(linux版本) #! /bin/bash # calcucate sql_text of full_hash_value(16),hash_value(10),sql_id(32). # argv1 sql statement or sql of text file # argv2 flag: 0= sql statement 1=sql of text file for sqlplus  2=sql of text file for other 3=original # argv3 default = '\0' add tailstr odebug=${ODEBUG:-0} oflag=${2:-0} tailstr=${3:-'\0'} if [ $oflag -eq 0 ] then     sql_text=${1}${tailstr} fi # sqlplus format sql_text if [ $oflag -eq 1 ] then sql_text="$( cat $1 | sed -e "s/ $//" -e "s/\s*$//" -e '$s/;$//')""${tailstr}" # sql_text="$( cat $1 | unix2dos | sed '$s/;\s*$//')"'\0' # sql_text="$( cat $1 | sed -e "s/ $//" -e sed '$s/;\s*$//')"'\0' # sql_text="$( cat $1 | sed '$s/;\s*$//')"'\0' fi # other format sql_text if [ $oflag -eq 2 ] then sql_text="$( cat $1 | sed '$s/;\s*$//')""${tailstr}" # sql_text="$( cat $1 | unix2dos | sed '$s/;\s*$//')"'\0' # sql_text="$( cat $1 | sed -e "s/ $//" -e '$s/;\s*$//')"'\0' # sql_text="$( cat $1 | sed '$s/;\s*//')"'\0' fi # exact_matching_signature, force_matching_signature if [ $oflag -eq 3 ] then     sql_text=${1} fi v1=$(echo -e -n "$sql_text" | md5sum | sed 's/  -//' | xxd -r -p | od -t x4 |  sed   -n  -e 's/^0\+ //' -e 's/ //gp' | tr 'a-z' 'A-Z') v2=${v1:(-16):16} v3=${v2:(-8):8} # v2=$(echo "obase=16;ibase=16; $v1 % 10000000000000000" | bc| tr -d '\\\r\n') # v3=$(echo "obase=10;ibase=16; $v1 % 100000000" | bc| tr -d '\\\r\n') if [ $odebug -eq 1 ] ; then         echo v1=$v1 v2=$v2 v3=$v3 fi echo "sql_text = $sql_text" echo "full_hash_value(16) = $v1 or ${v1,,}" if [ $oflag -eq 3 ] ; then     echo "xxxxx_matching_signature(10) = $(( 16#$v2 )) or " $(echo $(( 16#$v2 )) + 2^64|bc ) fi echo "hash_value(10) = $(( 16#$v3 )) " BASE32=($(echo {0..9} {a..z} | tr -d 'eilo')) res='' for i in $(echo "obase=32;ibase=16; $v2" | bc| tr -d '\\\r\n') do         res=${res}${BASE32[$(( 10#$i ))]} done echo "sql_id(32) = $(printf "%13s" $res | tr ' ' '0')" echo "sql_id(32) = $(printf "%013s" $res)" res1=$(eval $(echo "obase=32;ibase=16; $v2" | bc| tr -d '\\\r\n' | awk 'BEGIN{RS=" +"; printf "echo " }/./{printf "${BASE32[$(( 10#%02d))]}", $1}' )) echo "sql_id(32) = $(printf "%013s" $res1)"

相关推荐