天天看点

[20171005]parsing.txt

[20171005]parsing.txt

--//如果一条sql语句输入有错,会在sharepool存在记录.参考链接:

--//jonathanlewis.wordpress.com/2017/10/03/parsing/

1.环境:

SCOTT@test01p> @ ver1

PORT_STRING                    VERSION        BANNER                                                                               CON_ID

------------------------------ -------------- -------------------------------------------------------------------------------- ----------

IBMPC/WIN_NT64-9.1.0           12.1.0.1.0     Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production              0

2.简单测试使用sys用户执行:

SYS@test> select user frrom dual;

select user frrom dual

                  *

ERROR at line 1:

ORA-00923: FROM keyword not found where expected

SYS@test> @ sharepool/shp4 bshhvh0ypcz6x 0

old  18:  WHERE kglobt03 = '&1'  or kglhdpar='&1' or kglhdadr='&1' or KGLNAHSH= &2

new  18:  WHERE kglobt03 = 'bshhvh0ypcz6x'  or kglhdpar='bshhvh0ypcz6x' or kglhdadr='bshhvh0ypcz6x' or KGLNAHSH= 0

TEXT           KGLHDADR         KGLHDPAR         C40                  KGLHDIVC KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16   N0_6_16        N20   KGLNAHSH KGLOBT03      KGLOBT09

-------------- ---------------- ---------------- -------------------- -------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ----------

子游标句柄地址 000007FF1298E2D8 000007FF12A711C8 select user frrom du        1 00               00                        0          0       3111      3111       3111 1029078237 bshhvh0ypcz6x 0

父游标句柄地址 000007FF12A711C8 000007FF12A711C8 select user frrom du        1 000007FF129B5820 00                     4072          0          0      4072       4072 1029078237 bshhvh0ypcz6x 65535

--//产生了父子游标,不过子游标的KGLOBHD0,KGLOBHD6 等于0.

--//参考链接计算sql_id http://blog.itpub.net/267265/viewspace-1063541/

SYS@test> select dbms_sql_translator.sql_id ('select user frrom dual') sql_id, dbms_sql_translator.sql_hash ('select user frrom dual') hash_value  from dual;

SQL_ID        HASH_VALUE

------------- -----------

bshhvh0ypcz6x 1029078237

--//不过在视图v$sql无法查询到.

SYS@test> select * from v$sql where sql_id='bshhvh0ypcz6x';

no rows selected

--//shp4.sql脚本:

column N0_6_16 format 99999999

SELECT DECODE (kglhdadr,

               kglhdpar, '父游标句柄地址',

               '子游标句柄地址')

          text,

       kglhdadr,

       kglhdpar,

       substr(kglnaobj,1,40) c40,

       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 = '&1'  or kglhdpar='&1' or kglhdadr='&1' or KGLNAHSH= &2;

--//继续看后面的讨论:

DECLARE

   mcur     NUMBER;

   mstat    NUMBER;

   v_name   VARCHAR2 (14);

BEGIN

   mcur := DBMS_SQL.open_cursor;

   DBMS_SQL.parse ( mcur ,'SSlect dname from dept where deptno = :deptno' ,DBMS_SQL.native);

-- DBMS_SQL.bind_variable (mcur, ':deptno', 20);

-- DBMS_SQL.define_column ( mcur ,1 ,v_name ,14);

-- mstat := DBMS_SQL.execute (mcur);

-- mstat := DBMS_SQL.fetch_rows (mcur);

-- DBMS_SQL.COLUMN_VALUE (mcur, 1, v_name);

-- DBMS_OUTPUT.put_line ('查询结果:' || v_name);

-- DBMS_SQL.close_cursor (mcur);

END;

/

*

ORA-00900: invalid SQL statement

ORA-06512: at "SYS.DBMS_SQL", line 1120

ORA-06512: at line 7

select kglhdpar, kglhdadr, kglobt03, kglnaobj from x$kglob where kglnaobj like 'SSlect%' and kglnaobj not like '%kgl%';

SYS@test> select kglhdpar, kglhdadr, kglobt03, kglnaobj from x$kglob where kglnaobj like 'SSlect%' and kglnaobj not like '%kgl%';

KGLHDPAR         KGLHDADR         KGLOBT03      KGLNAOBJ

---------------- ---------------- ------------- ------------------------------

000007FF12A26F08 000007FF122F83E0 a50u3spg2590v SSlect dname from de

000007FF12A26F08 000007FF12A26F08 a50u3spg2590v SSlect dname from de

SYS@test> @ sharepool/shp4 a50u3spg2590v

new  18:  WHERE kglobt03 = 'a50u3spg2590v'  or kglhdpar='a50u3spg2590v' or kglhdadr='a50u3spg2590v' or KGLNAHSH= 0

子游标句柄地址 000007FF122F83E0 000007FF12A26F08 SSlect dname from de        1 00               00                        0          0       3134      3134       3134 1579328539 a50u3spg2590v  0

父游标句柄地址 000007FF12A26F08 000007FF12A26F08 SSlect dname from de        1 000007FF12B3A470 00                     4072          0          0      4072       4072 1579328539 a50u3spg2590v  65535

--//可以看看我以前的测试:http://blog.itpub.net/267265/viewspace-2141526/ => [20170703]SQL语句分析执行过程.txt

--//但是很奇怪的是如果修改DML语句:

   DBMS_SQL.parse ( mcur ,'INSERT INTO YY VALUESSS (1)' ,DBMS_SQL.native);

ORA-00928: missing SELECT keyword

--//注VALUESSS拼写错误故意的.

SELECT kglhdpar, kglhdadr, kglobt03, kglnaobj

 WHERE kglnaobj LIKE 'INSERT INTO YY VALUES%'

   AND kglnaobj NOT LIKE '%kgl%'

   AND kglnaobj NOT LIKE '%DECLARE%';

no rows selected   

--//即使我建立表YY结果也一样,有点奇怪.....oracle有时候也太奇怪了...

--//改写如下:

   DBMS_SQL.parse ( mcur ,'INSERT INTO YY VALUES(1)' ,DBMS_SQL.native);

--   mstat := DBMS_SQL.execute (mcur);

--   DBMS_SQL.close_cursor (mcur);

000007FF13111E40 000007FF13110990 d7xszfs543j5q INSERT INTO YY VALUES(1)

000007FF13111E40 000007FF13111E40 d7xszfs543j5q INSERT INTO YY VALUES(1)

SYS@test> @ sharepool/shp4 d7xszfs543j5q 0

new  18:  WHERE kglobt03 = 'd7xszfs543j5q'  or kglhdpar='d7xszfs543j5q' or kglhdadr='d7xszfs543j5q' or KGLNAHSH= 0

TEXT           KGLHDADR         KGLHDPAR         C40                      KGLHDIVC KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16   N0_6_16        N20   KGLNAHSH KGLOBT03        KGLOBT09

-------------- ---------------- ---------------- ------------------------ -------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ----------

子游标句柄地址 000007FF13110990 000007FF13111E40 INSERT INTO YY VALUES(1)        0 000007FF131108D8 000007FF131114C8       4032       8088       3113     15233      15233  172082358 d7xszfs543j5q   0

父游标句柄地址 000007FF13111E40 000007FF13111E40 INSERT INTO YY VALUES(1)        0 000007FF13111D88 00                     4072          0          0      4072       4072  172082358 d7xszfs543j5q   65535