匿名块存储在 SGA 中吗?

Posted

技术标签:

【中文标题】匿名块存储在 SGA 中吗?【英文标题】:Are anonymous blocks stored parsed in the SGA? 【发布时间】:2009-12-23 08:27:39 【问题描述】:

我最近发现可以像这样从 jdbc 调用匿名块:

字符串 plsql = "开始" + " :result := foobar( booleanparameter => :mypar > 2);" + “结尾;”; con.prepareCall(plsql);

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

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

谢谢

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

字符串 plsql = "BEGIN :myresult := dbms_random.random ; END;"; OracleDriver oracledrv = new OracleDriver(); 连接 con = oracledrv.connect(connstr, new Properties()); 对于 (int i = 0 ; i " +cb.getInt("myresult")); cb.close(); con.close();

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

SQL_TEXT -------------------------------------------------- ------------------------------ PARSE_CALLS 执行 ------------ ---------- 开始 :myresult := dbms_random.random ;结尾; 2000 2000

这是否意味着已预先解析?

【问题讨论】:

上次我检查(Oracle 10g)时,没有布尔数据类型。 Oracle 的 SQL 中可能没有,但 PL/SQL 肯定有。 我已经编辑了关于您的更新1的答案。 【参考方案1】:

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

SQL> 声明 abcabc 数;开始为空;结束; 2 /

PL/SQL 过程成功完成。

SQL> /

PL/SQL 过程成功完成。

SQL> select sql_text, executions from v$sqlarea where sql_text like '%abcabc%';

SQL_TEXT -------------------------------------------------- ------------------------------ 执行 ---------- 声明 abcabc 编号;开始为空;结束; 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 另一件事:PrepareCall() 返回 CallableStatement 对象,该对象可以通过多次调用来获得具体的已经准备好的语句的结果,而无需解析。【参考方案2】:

关于始终软解析,不一定如此。 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

【讨论】:

以上是关于匿名块存储在 SGA 中吗?的主要内容,如果未能解决你的问题,请参考以下文章

存储过程与匿名块 - 相同的数据,不同的结果

怎么用ORACLE PLSQL匿名块调用存储过程

oracle存储过程匿名块函数包

匿名块和过程中出现的问题

oracle存储过程

oracle中的创建过程,函数,包