[20240902]验证sql_idz.sh计算PLSQL代码块.txt

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

[20240902]验证sql_idz.sh计算PLSQL代码块.txt --//测试验证sql_idz.sh计算PLSQL代码块是否正确. 1.环境: SYS@book> @ver2 ============================== PORT_STRING                   : x86_64/Linux 2.4.xx VERSION                       : 21.0.0.0.0 BANNER                        : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production BANNER_FULL                   : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production Version 21.3.0.0.0 BANNER_LEGACY                 : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production CON_ID                        : 0 PL/SQL procedure successfully completed. $ cat -Av mn.txt DECLARE$     l_count PLS_INTEGER;$ BEGIN$     FOR i IN 1..&&1$     LOOP$        EXECUTE IMMEDIATE 'SELECT count(*)  FROM dept ,emp WHERE dept.deptno = emp.deptno' into l_count;$     END LOOP;$ END;$ /$ $ 2.测试: SCOTT@book01p> @ mn.txt Enter value for 1: 1e8 SYS@book> @ ashtop sql_id,TOP_LEVEL_SQL_ID    1=1 &1min     Total                                                                                       Distinct Distinct    Distinct   Seconds     AAS %This   SQL_ID        TOP_LEVEL_SQL FIRST_SEEN          LAST_SEEN           Execs Seen  Tstamps Execs Seen1 --------- ------- ------- ------------- ------------- ------------------- ------------------- ---------- -------- -----------        45      .8   73% | b7zpx6jm6mdpy 8uqtnw78t2sa4 2024-09-02 16:35:10 2024-09-02 16:36:09         35       45          45         9      .2   15% |               8uqtnw78t2sa4 2024-09-02 16:35:20 2024-09-02 16:36:08          1        9           9         6      .1   10% | 8uqtnw78t2sa4 8uqtnw78t2sa4 2024-09-02 16:35:14 2024-09-02 16:36:01          2        6           2         2      .0    3% |                             2024-09-02 16:35:42 2024-09-02 16:36:03          1        2           2 --//sql_id=8uqtnw78t2sa4对应plsql代码块. SYS@book> @ sql_id 8uqtnw78t2sa4 --SQL_ID = 8uqtnw78t2sa4 DECLARE     l_count PLS_INTEGER; BEGIN     FOR i IN 1..1e8     LOOP        EXECUTE IMMEDIATE 'SELECT count(*)  FROM dept ,emp WHERE dept.deptno = emp.deptno' into l_count;     END LOOP; END;; --//注:我写的sql_id脚本自动在结尾加上一个分号.PL/sql变成2个分号. $ cp mn.txt aa2.txt --//适当编辑aa2.txt,替换&&1=>1e8,取消结尾的/以及后面字符,在结尾的;在加上一个;主要原因我写的计算脚本计算时会丢弃结尾的1 --//个分号. $ cat -Av aa2.txt DECLARE$     l_count PLS_INTEGER;$ BEGIN$     FOR i IN 1..1e8$     LOOP$        EXECUTE IMMEDIATE 'SELECT count(*)  FROM dept ,emp WHERE dept.deptno = emp.deptno' into l_count;$     END LOOP;$ END;;$ $ sql_idz.sh aa2.txt 2 sql_text = DECLARE     l_count PLS_INTEGER; BEGIN     FOR i IN 1..1e8     LOOP        EXECUTE IMMEDIATE 'SELECT count(*)  FROM dept ,emp WHERE dept.deptno = emp.deptno' into l_count;     END LOOP; END;\0 full_hash_value(16) = 4A569457CB346ADE8D5B34E1D1916144 or 4a569457cb346ade8d5b34e1d1916144 hash_value(10) = 3515965764 sql_id(32) = 8uqtnw78t2sa4 sql_id(32) = 8uqtnw78t2sa4 sql_id(32) = 8uqtnw78t2sa4 --//计算完成正确. SYS@book> @ sharepool/shp4x 8uqtnw78t2sa4 0 HANDLE_TYPE            KGLHDADR         KGLHDPAR         C40                                        KGLHDLMD   KGLHDPMD   KGLHDIVC KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16   N0_6_16        N20   KGLNAHSH KGLOBT03        KGLOBT09 ---------------------- ---------------- ---------------- ---------------------------------------- ---------- ---------- ---------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ---------- child handle address   0000000070210BB8 000000006A7BB380 DECLARE     l_count PLS_INTEGER; BEGIN            1          2          0 000000006A7B9C50 000000006A7BA638       4032      16464       3455     23951      23951 3515965764 8uqtnw78t2sa4          0 parent handle address  000000006A7BB380 000000006A7BB380 DECLARE     l_count PLS_INTEGER; BEGIN            1          0          0 0000000070211158 00                     4064          0          0      4064       4064 3515965764 8uqtnw78t2sa4      65535 --//如果脚本如下,结尾仅仅1个分号. $ cat aa2.txt DECLARE     l_count PLS_INTEGER; BEGIN     FOR i IN 1..1e8     LOOP        EXECUTE IMMEDIATE 'SELECT count(*)  FROM dept ,emp WHERE dept.deptno = emp.deptno' into l_count;     END LOOP; END; --//加入参数3补上';\0' $ sql_idz.sh aa2.txt 2 ';\0' sql_text = DECLARE     l_count PLS_INTEGER; BEGIN     FOR i IN 1..1e8     LOOP        EXECUTE IMMEDIATE 'SELECT count(*)  FROM dept ,emp WHERE dept.deptno = emp.deptno' into l_count;     END LOOP; END;\0 full_hash_value(16) = 4A569457CB346ADE8D5B34E1D1916144 or 4a569457cb346ade8d5b34e1d1916144 hash_value(10) = 3515965764 sql_id(32) = 8uqtnw78t2sa4 sql_id(32) = 8uqtnw78t2sa4 sql_id(32) = 8uqtnw78t2sa4 --//计算完成正确. 3.附上源代码: --//^M 在vim for linux下按ctrl+v ctrl+M输入. $ cat -v ~/bin/sql_idz.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 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/^M$//" -e "s/\s*$//" -e '$s/;$//')""${tailstr}" # sql_text="$( cat $1 | unix2dos | sed '$s/;\s*$//')"'\0' # sql_text="$( cat $1 | sed -e "s/^M$//" -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/^M$//" -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)" $ cat shp4x.sql column N0_6_16 format 99999999 column handle_type format a22 SELECT /*+ USE_CONCAT(@"SEL$1" 8 OR_PREDICATES(1)) */ DECODE (kglhdadr,                kglhdpar, 'parent handle address',                'child handle address')            handle_type,        kglhdadr,        kglhdpar,        --//substr(kglnaobj,1,40) c40,        substr(replace(nvl(decode(kglnaown, null, kglnaobj, kglnaown||'.'||kglnaobj), '(name not found)'),chr(13),'') ,1,40)  c40,            KGLHDLMD,            KGLHDPMD,            kglhdivc,        kglobhd0,        kglobhd6,        kglobhs0,kglobhs6,kglobt16,        kglobhs0+kglobhs6+kglobt16 N0_6_16,            kglobhs0+kglobhs1+kglobhs2+kglobhs3+kglobhs4+kglobhs5+kglobhs6+kglobt16 N20,            kglnahsh,            kglobt03,            kglobt09   FROM x$kglob  WHERE kglobt03 = lower('&1') or KGLNAHSH= &2; $ 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  

相关推荐