使用EXECUTE IMMEDIATE来生成含有绑定变量的SQL

一个SQL,通过SPM固定它的执行计划,可以通过DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE实现。也可以通地此功能在不修改原SQL的情况下对其加HINT来固定执行计划。
DB VERSION:Oracle 11.2.0.4
OS:CentOS 6.6
例如:
原SQL走索引:
SELECT * FROM SCOTT.TB_SPM WHERE OBJECT_ID=10;
想通过加HINT让其走全表扫描:
SELECT /*+FULL(TB_SPM)*/* FROM SCOTT.TB_SPM WHERE OBJECT_ID=10;
在V$SQL中查询出,原SQL的SQL_ID=064qcdmgt6thw,加HINT的SQL的SQL_ID=ahdtbgvsd3bht,PLAN_HASH_VALUE=970476072。
执行以下:
DECLARE
CNT NUMBER;
V_SQL CLOB;
BEGIN
--得到原语句SQL文本
SELECT SQL_FULLTEXT INTO V_SQL FROM V$SQL WHERE SQL_ID = ‘064qcdmgt6thw‘ AND ROWNUM=1;
--用加HINT的SQL的SQL_ID和PLAN_HASH_VALUE,来固定原语句的SQL
CNT := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(SQL_ID => ‘ahdtbgvsd3bht‘, PLAN_HASH_VALUE => 970476072, SQL_TEXT => V_SQL);
END;
这样就将加HINT的执行计划固定在原语句上。执行原语句,在V$SQL的PLAN_HASH_VALUE列和SQL_PLAN_BASELINE列来确认是否固定。
测试中发现,一些含有绑定变量的SQL,用常量的SQL的SQL_ID和PLAN_HASH_VALUE无法固定,此时可以尝试使用EXECUTE IMMEDIATE来生成含有绑定变量的SQL。
例如:
DECLARE
V_SQL VARCHAR2(2881064151);
BEGIN
V_SQL := ‘SELECT /*+FULL(TB_SPM)*/* FROM SCOTT.TB_SPM WHERE OBJECT_ID=:1‘;
EXECUTE IMMEDIATE V_SQL
USING 10;
END;

var v number;
exec :v :=10
SELECT /*+FULL(TB_SPM)*/* FROM SCOTT.TB_SPM WHERE OBJECT_ID=:V;
Oracle 通过SQL PROFILE为SQL语句加HINT可参考:http://www.linuxidc.com/Linux/2015-05/116974.htm

更多Oracle相关信息见Oracle 专题页面 http://www.codesec.net/topicnews.aspx?tid=12

时间: 2024-08-04 01:58:58

使用EXECUTE IMMEDIATE来生成含有绑定变量的SQL的相关文章

捕获非绑定变量的SQL语句

之前一直用如下sql来查看非绑定变量的sql,但是不准 select hash_value, substr(sql_text, 1, 80)   from v$sqlarea  where substr(sql_text, 1, 40) in        (select substr(sql_text, 1, 40)           from v$sqlarea         having count(*) > 1          group by substr(sql_text, 1

通过重新生成执行计划解决绑定变量执行计划偏差导致SQL执行时间过长

基本要素(时间.用户.问题) 用户11g环境下有段SQL语句在程序中执行效率非常差,但是在plsql中执行却很快,通过查看执行计划,发现使用了不同的索引导致,程序中执行的如下: PLSQL中执行的效果如下: 可以看到差别,使用门诊费用记录_IX_登记时间索引是在plsql中的执行计划,使用门诊费用记录_UQ_NO的是程序中的执行计划,两者SQL是完全相同的,唯一却别就是前者使用了绑定变量,后者是直接带参数值执行. 问题分析 问题很明显,由于绑定变量生成的执行计划与实际有偏差,11g本来有个绑定变

Oracle绑定变量窥探

随着具体输入值的不同,SQL的where条件的可选择率(Selectivity)和结果集的行数(Cardinality)可能会随之发生变化,而Selectivity和Cardinality的值会直接影响CBO对于相关执行步骤成本值的估算,进而影响CBO对SQL执行计划的选择.这就意味着随着具体输入值的不同,目标SQL执行计划可能会发生变化. 对于不使用绑定变量的SQL而言,具体输入值一量发生了变化,目标SQL的SQL文本就会随之发生变化,这样Oracle就能很容易地计算出对应Selectivit

PLSQL使用绑定变量

想对一个sql做10046trace,结果因为10g数据库无法对sql_id做,只能使用绑定变量的方法,下面sql是如何使用绑定变量运行sql的语句 declare  v_sql  VARCHAR2(2000):= 'insert into regions values(:1,:2)';begin  execute immediate v_sql using 11,'Japan';end;

MySQL高级特性——绑定变量

从MySQL 4.1 版本开始,就支持服务器端的绑定变量,这大大提高了客户端和服务器端数据传输的效率 介绍 当创建一个绑定变量 SQL 时,客户端会向服务器发送一个SQL语句的原型.服务器端收到这个SQL语句框架后,解析并存储这个SQL语句的部分执行计划,返回个客户端一个 SQL 语句处理句柄.以后每次执行这类查询,客户端都指定使用这个句柄. 绑定变量的SQL,使用问号标记可以接受参数的位置,当真正需要执行具体查询的时候,则使用具体值来替代这些问号.例如,下面是一个绑定变量的SQL语句: INS

查看真实的执行计划 绑定变量对执行计划的影响--“绑定变量窥探”

--##################################################### --####     AWR执行计划                             #### --##################################################### SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_AWR('8qfs8857jc8fw',NULL,NULL,'ADVANCED')); SEL

OTL翻译(5) -- otl_stream流相关绑定变量

声明绑定变量 本章节将详细的说明如何在otl_stream流里面声明绑定变量. SQL语句.SQL语句块或存储过程在程序里面使用的时候总是带有占位符.OTL里面带有一个小的解析器用来解析这些占位符,并且在内部进行变量的内存分配操作. 在ORACLE里面占位符的表示方法与其他数据库不同,在ORACLE里面的占位符是通过带有冒号的前缀来表示的,如::f1/:supervisor_name/:employee_id等,并且同一个占位符可能在同一个SQL语句里面使用多次. 在ODBC或DB2 CLI里面

一个11G 抓没有绑定变量的语句.非常好!非常精确,非常快.

--追踪共享池没有绑定变量的SQLSELECT FORCE_MATCHING_SIGNATURE,to_char(FORCE_MATCHING_SIGNATURE ) as sing,       COUNT(1) AS REPLACE_NUM,       ROUND(SUM(SHARABLE_MEM) / 1024 / 1024) AS SHARED_MB,       ROUND(SUM(PERSISTENT_MEM) / 1024 / 1024) AS SHARED_MB,       

绑定变量

从一个简单的示例入手: package dbtest; import java.sql.*; public class Dbtest { public static final String drive = "oracle.jdbc.driver.OracleDriver"; public static final String url = "jdbc:oracle:thin:@//192.168.196.200:1521/orcl2pdb"; public sta