[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. arcgis api 4.x for js 集成 Echarts4 实现模拟迁徙图效果(附源码下载)

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 4.x for js:esri 官网 api,里面详细的介绍 arcgis api 4.x 各个类 ...

  2. thinkphp 5.x No input file specified 解决

    原规则: <IfModule mod_rewrite.c> Options +FollowSymlinks -Multiviews RewriteEngine On RewriteCond ...

  3. SSH的本地、远程、动态端口转发实验笔记

    SSH端口转发 SSH 会自动加密和解密所有 SSH 客户端与服务端之间的网络数据.但是,SSH 还能够将其他 TCP 端口的网络数据通过 SSH 链接来转发,并且自动提供了相应的加密及解密服务.这一 ...

  4. vscode笔记

    一.修改操作栏字体 https://www.cnblogs.com/liuyangfirst/p/9759966.html 1.代码改写,进入默认安装的如下路径,搜索workbench 2.用Vs c ...

  5. acwing 55. 连续子数组的最大和

    地址  https://www.acwing.com/problem/content/50/ 输入一个 非空 整型数组,数组里的数可能为正,也可能为负. 数组中一个或连续的多个整数组成一个子数组. 求 ...

  6. Java四个关键字 this super final static

    一.this ​ 关键字主要有三个应用: this调用本类中的属性,也就是类中的成员变量: this调用本类中的其他方法: this调用本类中的其他构造方法初始化对象,调用时要放在构造方法的首行. 引 ...

  7. 将scrapy爬取数据通过django入到SQLite数据库

    1. 在django项目根目录位置创建scrapy项目,django_12是django项目,ABCkg是scrapy爬虫项目,app1是django的子应用 2.在Scrapy的settings.p ...

  8. php 截取字符串 strstr 和strrchr

    截取字符串 strstr 和strrchr 结果:(其中之一) strstr : 执行时间在0.10 - 0.19 之间 strrchr : 执行时间在0.095 - 0.19 之间 结论:从数十次执 ...

  9. Groovy元编程应用之自动生成订单搜索接口测试用例集

    背景 在 "Groovy元编程简明教程" 一文中,简明地介绍了 Groovy 元编程的特性. 那么,元编程可以应用哪些场合呢?元编程通常可以用来自动生成一些相似的模板代码. 在 & ...

  10. 【linux运维】linux系统上忘记密码如何操作

    目录 红帽系统忘记密码操作 红帽系统设置ip,主机名 centos系统忘记密码操作 一.红帽系统忘记密码操作 1)再出现以下界面后按键盘e键 2)进入以下界面后,再次按e键 3)使用上下键选择第2项或 ...