[20191011]通过bash计算sql语句的sql_id.txt

--//当我知道如何通过bash计算sql语句的full_hash_value ,就很想通过bash编程计算sql_id.当时受限自己能力
--//感觉不好实现.
--//链接: http://blog.itpub.net/267265/viewspace-2142512/=> [20170724]关于sql_id那些事.txt

1.简单介绍sql_id.
--//sql_id的计算是使用MD5算法进行哈希,生成一个128位的Hash Value,其中低32位作为HASH VALUE显示,SQL_ID则取了后64位。
--//实际上sql_id使用32进制表示,hash_value使用10进制表示。

2.环境:
SCOTT@book> @ &r/ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

select * from emp where deptno=10;
--//查询可以知道sql_id='557p4j1ggw222'.

SCOTT@book> select sql_text c70,sql_id,hash_value  from v$sql where sql_id = '557p4j1ggw222';
C70                                SQL_ID        HASH_VALUE
---------------------------------- ------------- ----------
select * from emp where deptno=10  557p4j1ggw222 1593706562

SCOTT@book> select name c70,hash_value,full_hash_value from V$DB_OBJECT_CACHE where name like '%emp%' and hash_value=1593706562;
C70                               HASH_VALUE FULL_HASH_VALUE
--------------------------------- ---------- --------------------------------
select * from emp where deptno=10 1593706562 8bb974871a4f8c88529ea4885efe0842
select * from emp where deptno=10 1593706562 8bb974871a4f8c88529ea4885efe0842

--//注以上是以前的测试!!

3.简单说明如何计算sql_id:
--//简单说明sql_id采用32进制,编码0-9,a-z.没有eilo字符,这些字符容易与数字0,1混淆.
--//编程利用bc obase=32;ibase=16;输出.通过数组BASE32定位编码.注意bc的输出例子:
$ echo "obase=32;ibase=16; 529EA4885EFE0842" | bc| tr -d '\\\r\n'
 05 05 07 21 04 17 01 15 15 28 02 02 02
--//这些数字是10进制数字,前面虽然有0,不能写成${BASE32[$i]},必须写成{BASE32[$(( 10#$i ))]}.

$ ./sql_id.sh "select * from emp where deptno=10"
sql_text = select * from emp where deptno=10\0
full_hash_value(16) = 8BB974871A4F8C88529EA4885EFE0842
hash_value(10) = 1593706562
sql_id = 557p4j1ggw222

--//再测试一个例子:
SCOTT@test01p> select /*+ 12345678abdef */ sysdate from dual ;
SYSDATE
-------------------
2019-10-11 22:34:56

SCOTT@test01p> @ dpc '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  0p0rzks2gkrj6, child number 0
-------------------------------------
select /*+ 12345678abdef */ sysdate from dual

Plan hash value: 1388734953

------------------------------------------------------------------
| Id  | Operation        | Name | E-Rows | Cost (%CPU)| E-Time   |
------------------------------------------------------------------
|   0 | SELECT STATEMENT |      |        |     2 (100)|          |
|   1 |  FAST DUAL       |      |      1 |     2   (0)| 00:00:01 |
------------------------------------------------------------------
--//sql_id=0p0rzks2gkrj6,主要要找一个sql_id前面是0的情况.注意dual后面有1个空格.

$ ./sql_id.sh "select /*+ 12345678abdef */ sysdate from dual "
sql_text = select /*+ 12345678abdef */ sysdate from dual \0
full_hash_value(16) = EF5A2C4876C9E93D0A82FF9604F95E26
hash_value(10) = 83451430
sql_id(32) = 0p0rzks2gkrj6

--//完成能对上.
SCOTT@test01p> select name c70,hash_value,full_hash_value from V$DB_OBJECT_CACHE where  hash_value=83451430;
C70                                           HASH_VALUE FULL_HASH_VALUE
--------------------------------------------- ---------- --------------------------------
select /*+ 12345678abdef */ sysdate from dual   83451430 ef5a2c4876c9e93d0a82ff9604f95e26
select /*+ 12345678abdef */ sysdate from dual   83451430 ef5a2c4876c9e93d0a82ff9604f95e26

4.总结:
--//我几乎是一气呵成写成脚本,当我回过头看我写的脚本,感觉原来如此简单.
--//自己真没想到短短几行代码,就能实现这个功能.

5.脚本如下:
$ cat sql_id.sh
#! /bin/bash
# calcucate sql_text of full_hash_value(16),hash_value(10),sql_id(32).
odebug=${ODEBUG:-0}

sql_text=${1}'\0'
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 "
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')"

[20191011]通过bash计算sql语句的sql_id.txt的更多相关文章

  1. [20191101]通过zsh计算sql语句的sql_id.txt

    [20191101]通过zsh计算sql语句的sql_id.txt 1.简单介绍以及测试使用zsh遇到的问题:--//前段时间写的,链接http://blog.itpub.net/267265/vie ...

  2. [20171110]sql语句相同sql_id可以不同吗.txt

    [20171110]sql语句相同sql_id可以不同吗.txt --//提一个问题,就是sql语句相同sql_id可以不同吗?--//使用dbms_shared_pool.markhot就可以做到. ...

  3. [20190328]简单探究sql语句相关mutexes.txt

    [20190328]简单探究sql语句相关mutexes.txt --//摘要:http://www.askmaclean.com/archives/understanding-oracle-mute ...

  4. vertica时间计算SQL语句实例:统计一天内登录的用户

    SQL语句实例: select count(id) as num from public.user where cast((CURRENT_TIMESTAMP-login_timed) day as ...

  5. 计算sql语句的查询时间

    set statistics profile on set statistics io on set statistics time on go <这里写上你的语句...> go set ...

  6. 常用日期计算SQL语句

    -- 本月的第一天 SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0) -- 本月的最后一天 SELECT DATEADD(ms,-3,DATEADD(mm ...

  7. 查看SQL语句的真实执行计划

    DBMS_XPLAN包中display_cursor函数不同于display函数,display_cursor用于显示SQL语句的真实的执行计划,在大多数情况下,显示真实的执行计划有助于更好的分析SQ ...

  8. 如何使用SQLPLUS分析SQL语句(查询执行计划跟踪)

    方法一:autotrace 1,  connect sys/密码 as sysdba,在sys用户下运行$ORACLE_HOME/sqlplus/admin/plustrce.sql这段sql的实际内 ...

  9. ORACLE 查看有多个执行计划的SQL语句

    在SQL优化过程,有时候需要查看哪些SQL具有多个执行计划(Multiple Executions Plans for the same SQL statement),因为同一个SQL有多个执行计划一 ...

随机推荐

  1. [Spring]:java.lang.NoSuchMethodError: 'java.lang.String javax.annotation.Resource.lookup()'

    错误信息 11月 05, 2019 9:32:15 下午 org.springframework.test.context.TestContextManager prepareTestInstance ...

  2. Oracle merge into的优势

    简介 Oracle merge into命令,顾名思义就是“有则更新,无则插入”,这个也是merge into 命令的核心思想,在实际开发过程中,我们会经常遇到这种通过两表互相关联匹配更新其中一个表的 ...

  3. OpenCV:图像的裁剪

    import cv2 import matplotlib.pyplot as plt def show(image): plt.imshow(image) plt.axis('off') plt.sh ...

  4. Servlet 使用介绍(1)

    说明 本篇介绍java web中比较重要的一个技术:servlet.servlet是一种对用户请求动态响应的一个技术,是java web的核心一环.对于一般服务性质的纯后台服务应用而言,或许整个应用是 ...

  5. PHP清除数组中为0的元素

    array_diff($arr, [0]): // 清除数组中指定元素 $arr = [1,2,3,0,1]; $arr = array_diff($arr, [0]);//输出[1,2,3,1] v ...

  6. php对微信支付回调处理的方法(合集)

    支付完成后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理,并返回应答. 对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽 ...

  7. 更改 undo_retention 时,Lob retention 不更改 (Doc ID 563470.1)

    Lob retention not changing when undo_retention is changed (Doc ID 563470.1) APPLIES TO: Oracle Datab ...

  8. JavaScriptES6中Map与对象、数组,JSON之间的相互转换

    JavaScriptES6中Map与对象.数组,JSON之间的相互转换 https://blog.csdn.net/c__dreamer/article/details/82183130

  9. C语言解决汉诺塔问题!

    很难受,看了很多资料才明白..... 对这个问题分析,发现思路如下:有n个黄金盘,要先把n-1个弄到B柱上,再把第n个弄到C柱上,然后把n-1个借助A柱弄到C柱上. 实现的函数如下: void f(i ...

  10. 推荐|MathType的使用技巧

    前言 持续更新中,敬请期待... 数学学科 制作新的数学符号 不包含于符号:输入$\not\subseteq,然后按回车键enter即可: 分式\(\cfrac{3-x}{2x-1}\)符号:输入$\ ...