是否存储了在SGA中解析的匿名块?

时间:2009-12-23 08:27:40

标签: oracle jdbc plsql

我最近发现可以像这样从jdbc调用一个非常好的块:

    String plsql = "BEGIN" +
                   " :result := foobar( booleanparameter => :mypar > 2);" +
                   "END;";

    con.prepareCall(plsql);

哪个好,因为我可以用它来“包装”一些函数调用和 克服了一些jdbc限制。例如,我无法将布尔变量传递给 pl / sql程序,并且不能改变程序签名,因为有 很多依赖于它们的代码。添加新的“包装”程序也不容易 由于内部政策原因。

所以这似乎是一个可以接受的解决方案,但是,我很担心解析 高架。这样的匿名块是存储在SGA中解析还是它们 每次被调用时解析?

由于

更新1:我已经制作了一个快速的beanhell脚本来查看v $ sqlarea,因为egorius建议:

String  plsql = "BEGIN :myresult := dbms_random.random ; END;";
OracleDriver oracledrv = new OracleDriver();
Connection   con = oracledrv.connect(connstr, new Properties());

for (int i = 0 ; i < 1000 ; i++ ) {
    CallableStatement cb = con.prepareCall(plsql);
    cb.registerOutParameter("myresult", Types.INTEGER);
    cb.execute();
    System.out.println("random ->" +cb.getInt("myresult"));
    cb.close();
}
con.close();

这就是我得到的v $ sqlarea(我已经运行了两次):

SQL_TEXT
--------------------------------------------------------------------------------

PARSE_CALLS EXECUTIONS
----------- ----------
BEGIN :myresult := dbms_random.random ; END;
       2000       2000

这是否意味着预先准备好了?

2 个答案:

答案 0 :(得分:5)

匿名块也被缓存。您可以通过查询V$SQLAREA来查看。

  

SQL&GT;宣布abcabc号码;开始为null;端;
       2 /

     

PL / SQL过程成功完成。

     

SQL&GT; /

     

PL / SQL过程成功完成。

     

SQL&GT;选择sql_text,从v $ sqlarea执行,其中sql_text如'%abcabc%';

     

SQL_TEXT
      -------------------------------------------------- ------------------------------
     EXECUTIONS
      ----------
     宣布abcabc号码;开始为null;端;
              2

     

选择sql_text,从v $ sqlarea执行,其中sql_text如'%abcabc%'
              1

修改

你将永远拥有所谓的SOFT PARSE。它需要查询的语法和语义检查。之后,如果库缓存中存在完全相同的查询,则将跳过HARD PARSE。 (请参阅此Ask Tom question以获得更好的解释)。

以下摘录自tkprofed 10046跟踪文件:

declare abcabc number; begin null; end;

call     count       cpu    elapsed       disk      query    current        rows  
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        2      0.00       0.00          0          0          0           0
Execute      2      0.00       0.00          0          0          0           2
Fetch        0      0.00       0.00          0          0          0           0  
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.00       0.00          0          0          0           2

Misses in library cache during parse: 1

最后一行显示了这一点。

答案 1 :(得分:1)

关于始终软解析,不一定如此。 Oracle允许Java和PL / SQL都能够在每个会话中解析一次语句。 当光标未关闭但重复使用时会发生这种情况 - 无需解析。 SQL解析信息:http://docs.oracle.com/cd/E11882_01/server.112/e25789/sqllangu.htm 私有SQL区域:http://docs.oracle.com/cd/E11882_01/server.112/e25789/memory.htm#i17716