[20220111]该语句的sql_id如何计算的.txt --//昨天定位一个数据库问题,我发现使用我的计算sql_idx.sh的脚本计算不对,做一个记录并分析. > select sql_id,prev_sql_id from v$session where sid=14382; SQL_ID PREV_SQL_ID ------------- ------------- 50qyqnykr15au 9m7787camwh4m > @ sql_id 9m7787camwh4m --SQL_ID = 9m7787camwh4m begin :id := sys.dbms_transaction.local_transaction_id; end; ; --//该语句来自于plsql develop模块. --//实际上让我感兴趣的是输出带有结尾的分号.注意下一行的分号是我输出脚本加上的.而一般的sql语句计算时不包括结尾的分号并且在结 --//尾加入\0. $ sql_idx.sh "begin :id := sys.dbms_transaction.local_transaction_id; end;" 0 sql_text = begin :id := sys.dbms_transaction.local_transaction_id; end;\0 full_hash_value(16) = 4A67DF6F14018C5774E83D71EF85B8E5 hash_value(10) = 4018518245 sql_id(32) = 79u1xf7rsbf75 sql_id(32) = 79u1xf7rsbf75 sql_id(32) = 79u1xf7rsbf75 --//计算不对,再仔细查看,发现下一个分号出现在下一行,这个分号是我执行脚本输出时加上的,可以确定真正的计算应该是包括\n: $ sql_idx.sh "begin :id := sys.dbms_transaction.local_transaction_id; end;\n" 0 sql_text = begin :id := sys.dbms_transaction.local_transaction_id; end;\n\0 full_hash_value(16) = 3C11BF82C67CCD91999CE83B153E4093 hash_value(10) = 356401299 sql_id(32) = 9m7787camwh4m sql_id(32) = 9m7787camwh4m sql_id(32) = 9m7787camwh4m --//我自己在sqlplus测试时突然明白为什么.看具体测试: SCOTT@book> @ 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 SCOTT@book> variable id number ; SCOTT@book> begin :id := sys.dbms_transaction.local_transaction_id; end; 2 / PL/SQL procedure successfully completed. SCOTT@book> @ hash HASH_VALUE SQL_ID CHILD_NUMBER KGL_BUCKET PLAN_HASH_VALUE SQL_EXEC_START SQL_EXEC_ID ---------- ------------- ------------ ---------- --------------- ------------------- ----------- 4018518245 79u1xf7rsbf75 0 112869 0 2022-01-11 08:26:51 16777216 --//注意看这里并不一致,这也是我当时困惑的地方,实际上在plsqldev.exe上执行的是。 SCOTT@book> begin :id := sys.dbms_transaction.local_transaction_id; end; 2 3 / PL/SQL procedure successfully completed. --//分号后加一个回车再加一个斜线。实际上到这里我还是很困惑,理论讲应该是两个回车,为什么计算时1个,也是PLSQL代码执行的特 --//殊性。 SCOTT@book> @ hash HASH_VALUE SQL_ID CHILD_NUMBER KGL_BUCKET PLAN_HASH_VALUE SQL_EXEC_START SQL_EXEC_ID ---------- ------------- ------------ ---------- --------------- ------------------- ----------- 356401299 9m7787camwh4m 0 16531 0 2022-01-11 08:28:47 16777216 --//打入完成最后的分号时并不执行,要回车+回车+/ 后加入执行,对于PL/SQL语句是这样执行的,这样sql_id的计算就出现前面的情况. --//附上脚本: $ cat sql_id.sql SET LINESIZE 32767 --SET LINESIZE 4000 VAR V_SQL_FULLTEXT CLOB COL SQL_FULLTEXT FOR A4000 WORD_WRAP SET FEEDBACK OFF SET SERVEROUTPUT ON PROMPT PROMPT --SQL_ID = &&1 PROMPT DECLARE V_SQL_FULLTEXT CLOB; V_COUNT NUMBER; BEGIN SELECT COUNT(*) INTO V_COUNT FROM GV$SQLAREA WHERE SQL_ID = '&&1' AND ROWNUM=1; IF V_COUNT=1 THEN SELECT REPLACE (SQL_FULLTEXT||';', CHR(13), '') SQL_FULLTEXT INTO V_SQL_FULLTEXT FROM GV$SQLAREA WHERE SQL_ID = '&&1' AND ROWNUM = 1; --SELECT REPLACE (SQL_FULLTEXT||';', CHR(13), chr(13)) SQL_FULLTEXT INTO V_SQL_FULLTEXT FROM GV$SQLAREA WHERE SQL_ID = '&&1' AND ROWNUM = 1; DBMS_OUTPUT.PUT_LINE (V_SQL_FULLTEXT); ELSE SELECT COUNT(*) INTO V_COUNT FROM DBA_HIST_SQLTEXT WHERE SQL_ID='&&1' AND ROWNUM=1; IF V_COUNT=1 THEN SELECT REPLACE (SQL_TEXT||';',CHR(13),'') INTO V_SQL_FULLTEXT FROM DBA_HIST_SQLTEXT WHERE SQL_ID='&&1' AND ROWNUM=1; --SELECT REPLACE (SQL_TEXT||';',CHR(13),chr(13)) INTO V_SQL_FULLTEXT FROM DBA_HIST_SQLTEXT WHERE SQL_ID='&&1' AND ROWNUM=1; DBMS_OUTPUT.PUT_LINE (V_SQL_FULLTEXT); END IF; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN NULL; END; / PROMPT SET SERVEROUTPUT OFF SET FEEDBACK 6 SET LINESIZE 277 $ cat sql_idx.sh #! /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 odebug=${ODEBUG:-0} oflag=${2:-0} if [ $oflag -eq 0 ] then sql_text=${1}'\0' fi if [ $oflag -eq 1 ] then # sql_text="$( cat $1 | dos2unix | sed '$s/;\s*//')"'\0' $//" | sed '$s/;\s*//')"'\0' "s/ # sql_text="$( cat $1 | sed '$s/;\s*//')"'\0' 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 " 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)"
[20220111]该语句的sql_id如何计算的.txt
来源:这里教程网
时间:2026-03-03 17:24:32
作者:
编辑推荐:
下一篇:
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
热文推荐
- EXCEL常用查询函数?查询函数的妙用
EXCEL常用查询函数?查询函数的妙用
26-03-03 - windows2008R2安裝oracle 10g
windows2008R2安裝oracle 10g
26-03-03 - 安装RAC 19C
安装RAC 19C
26-03-03 - C盘哪些文件可以删除?删除文件看这里
C盘哪些文件可以删除?删除文件看这里
26-03-03 - 程序不足SQL来凑
程序不足SQL来凑
26-03-03 - ORACLE压力测试
ORACLE压力测试
26-03-03 - 电脑误删内存卡照片如何恢复?(三个步骤)
电脑误删内存卡照片如何恢复?(三个步骤)
26-03-03 - C盘哪些文件可以删除?删除文件看这里
C盘哪些文件可以删除?删除文件看这里
26-03-03 - Oracle Grid Infrastructure for a Standalone Server
- 储存卡误删都能恢复吗?这个方法大家用了都说好
储存卡误删都能恢复吗?这个方法大家用了都说好
26-03-03
