[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. ABP入门教程11 - 展示层实现增删改查-视图

    点这里进入ABP入门教程目录 创建目录 在展示层(即JD.CRS.Web.Mvc)的Views下新建文件夹Course //用以存放Course相关视图 创建视图 在JD.CRS.Web.Mvc/Vi ...

  2. 微信小程序官方文档中表单组建button部分有关function(type)中type的个人理解

    官方文档关于button组件的简介 xml页面挺容易理解,但js部分起初对整体写的形式都不太理解,随着逐渐阅读代码基本理解了 xml页面代码: <button type="defaul ...

  3. sshd 启动后 出现:Could not load host key: /etc/ssh/ssh_host_rsa_key

    今天在启动sshd时,出现了如下问题,导致客户端不能成功连接服务端,不能建立ssh连接: 有两个提示 Could not load host key: /etc/ssh/ssh_host_rsa_ke ...

  4. ssh免密登录配置后,登陆失败问题

    本文转自博主:_Lance 本文转自:https://blog.csdn.net/qq_19648191/article/details/54845440 相关资料http://blog.csdn.n ...

  5. ACM 基本输入

    单次输入 C语言 int a,b; scanf("%d %d",&a,&b); C++语言 int a,b; cin >> a >> b; ...

  6. 05-Django后台管理和视图

    Django的后台管理可以方便的生成管理页面,使用前先准备如下: 1.本地化 语言和时区的本地化,修改settings.py文件 # LANGUAGE_CODE = 'en-us' LANGUAGE_ ...

  7. 手工挖掘web常见漏洞时的一些经验总结

    一.前提: 漏洞挖掘原则 所有变量 所有头 cookie中的变量 逐个变量删除 漏洞的本质 数据与指令的混淆 对用户输入信息过滤不严判断失误,误将数据当指令 二.经典漏洞: 1.身份认证 常用弱口令/ ...

  8. SPA项目开发之首页导航左侧菜单栏

    1. Mock.js 前后端分离开发开发过程当中,经常会遇到以下几个尴尬的场景: 1. 老大,接口文档还没输出,我的好多活干不下去啊! 2. 后端小哥,接口写好了没,我要测试啊! 前后端分离之后,前端 ...

  9. go语言设计模式之template

    template.go package template import ( "strings" ) type MessageRetriever interface { Messag ...

  10. 使用canal增量同步mysql数据库信息到ElasticSearch

    本文介绍如何使用canal增量同步mysql数据库信息到ElasticSearch.(注意:是增量!!!) 1.简介 1.1 canal介绍 Canal是一个基于MySQL二进制日志的高性能数据同步系 ...