我最近发现可以像这样调用jdbc中的aoymous块:
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
这是否意味着预先准备好了?
匿名块也被缓存.您可以通过查询V $ SQLAREA来检查它.
SQL>声明abcabc号; 开始为null; 结束;
2 /PL/SQL过程成功完成.
SQL> /
PL/SQL过程成功完成.
SQL> select sql_text,v $ sqlarea中的执行,其中sql_text如'%abcabc%';
SQL_TEXT
------------------------------------------------- -------------------------------
执行
----------
申报abcabc号码; 开始为null; 结束;
2选择sql_text,从v $ sqlarea执行,其中sql_text如'%abcabc%'
1
编辑:
你将永远拥有所谓的SOFT PARSE.它需要查询的语法和语义检查.之后,如果库缓存中存在完全相同的查询,则将跳过HARD PARSE.(请参阅此问问汤姆问题以获得一个很好的解释).
以下是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
Run Code Online (Sandbox Code Playgroud)
最后一行显示了这一点.
| 归档时间: |
|
| 查看次数: |
731 次 |
| 最近记录: |