查看v$sql_shared_cursor视图获取sql语句为什么不能共享?

[20111213]查看v$sql_shared_cursor视图获取sql语句为什么不能共享?

查询v$sql_shared_cursor视图获取sql语句为什么不能共享,在GUI界面下,由于不能共享的原因很多,视图字段N多,大部分都是'N'的数值,检查这个是一个很费时间的操作。

想到了TOM大师的print_table过程,应该修改一下很容易实现这个功能。

http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:1035431863958

修改一下,很容易实现这个功能:

CREATE OR REPLACE PROCEDURE print_shared_cursor (p_query IN VARCHAR2)
AUTHID CURRENT_USER
IS
   l_thecursor     INTEGER           DEFAULT DBMS_SQL.open_cursor;
   l_columnvalue   VARCHAR2 (4000);
   l_query         VARCHAR2 (4000);
   l_status        INTEGER;
   l_desctbl       DBMS_SQL.desc_tab;
   l_colcnt        NUMBER;
BEGIN
   --EXECUTE IMMEDIATE 'alter session set  nls_date_format=''yyyy-mm-dd hh24:mi:ss'' ';

   l_query := 'select * from v$sql_shared_cursor where sql_id=' || CHR (39) || p_query || CHR (39);
   DBMS_SQL.parse (l_thecursor, l_query, DBMS_SQL.native);
   DBMS_SQL.describe_columns (l_thecursor, l_colcnt, l_desctbl);

   FOR i IN 1 .. l_colcnt
   LOOP
      DBMS_SQL.define_column (l_thecursor, i, l_columnvalue, 4000);
   END LOOP;

   l_status := DBMS_SQL.EXECUTE (l_thecursor);
   DBMS_OUTPUT.put_line ('-------------------------------------------------------');

   WHILE (DBMS_SQL.fetch_rows (l_thecursor) > 0)
   LOOP
      FOR i IN 1 .. l_colcnt
      LOOP
         DBMS_SQL.COLUMN_VALUE (l_thecursor, i, l_columnvalue);

         IF (l_columnvalue 'N')
         THEN
            DBMS_OUTPUT.put_line (RPAD (l_desctbl (i).col_name, 30) || ': ' || l_columnvalue);
         END IF;
      END LOOP;

      DBMS_OUTPUT.put_line ('-------------------------------------------------------');
   END LOOP;
--  execute immediate  'alter session set nls_date_format=''dd-MON-rr'' ';
EXCEPTION
   WHEN OTHERS
   THEN
      NULL;
--  execute immediate  'alter session set nls_date_format=''dd-MON-rr'' ';
      RAISE;
END;
/

实际上我还发现别人已经写了一个sql语句实现一样的操作,只不过他查询的是sql语句,很容易修改为查询sql_id的语句,我修改如下:

http://dioncho.wordpress.com/2009/03/05/vsql_shared_cursor/

$ cat shared_cursor.sql
SET  serveroutput on size 100000;

DECLARE
   c           NUMBER;
   col_cnt     NUMBER;
   col_rec     DBMS_SQL.desc_tab;
   col_value   VARCHAR2 (4000);
   ret_val     NUMBER;
BEGIN
   c := DBMS_SQL.open_cursor;
   DBMS_SQL.parse
      (c,
       'select q.sql_text, s.*
      from v$sql_shared_cursor s, v$sql q
      where s.sql_id = q.sql_id
          and s.child_number = q.child_number
          and q.sql_id like ''&1''',
       DBMS_SQL.native
      );
   DBMS_SQL.describe_columns (c, col_cnt, col_rec);

   FOR idx IN 1 .. col_cnt
   LOOP
      DBMS_SQL.define_column (c, idx, col_value, 4000);
   END LOOP;
   ret_val := DBMS_SQL.EXECUTE (c);
   WHILE (DBMS_SQL.fetch_rows (c) > 0)
   LOOP
      FOR idx IN 1 .. col_cnt
      LOOP
         DBMS_SQL.COLUMN_VALUE (c, idx, col_value);

         IF col_rec (idx).col_name IN ('SQL_ID', 'ADDRESS', 'CHILD_ADDRESS', 'CHILD_NUMBER', 'SQL_TEXT')
         THEN
            DBMS_OUTPUT.put_line (RPAD (col_rec (idx).col_name, 30) || ' = ' || col_value);
         ELSIF col_value = 'Y'
         THEN
            DBMS_OUTPUT.put_line (RPAD (col_rec (idx).col_name, 30) || ' = ' || col_value);
         END IF;
      END LOOP;
      DBMS_OUTPUT.put_line ('--------------------------------------------------');
   END LOOP;

   DBMS_SQL.close_cursor (c);
END;
/

SET serveroutput off;

做一个简单测试:

SQL> var a number;
SQL> exec :a := 10;

PL/SQL procedure successfully completed.

SQL> select * from dept where deptno=:a;

查询获得sql_id='6a2y9jbwu5fz9'.

SQL> alter session set optimizer_mode =first_rows;
SQL> select * from dept where deptno=:a;
SQL> set serveroutput on
SQL> exec print_shared_cursor('6a2y9jbwu5fz9');
-------------------------------------------------------
SQL_ID                        : 6a2y9jbwu5fz9
ADDRESS                       : 00000000BF56C328
CHILD_ADDRESS                 : 00000000BF56BFC8
CHILD_NUMBER                  : 0
-------------------------------------------------------
SQL_ID                        : 6a2y9jbwu5fz9
ADDRESS                       : 00000000BF56C328
CHILD_ADDRESS                 : 00000000B5ED9E80
CHILD_NUMBER                  : 1
OPTIMIZER_MODE_MISMATCH       : Y
-------------------------------------------------------

PL/SQL procedure successfully completed.

@shared_cursor.sql 6a2y9jbwu5fz9
old  15:           and q.sql_id like ''&1''',
new  15:           and q.sql_id like ''6a2y9jbwu5fz9''',
SQL_TEXT                       = select * from dept where deptno=:a
SQL_ID                         = 6a2y9jbwu5fz9
ADDRESS                        = 00000000BF56C328
CHILD_ADDRESS                  = 00000000BF56BFC8
CHILD_NUMBER                   = 0
--------------------------------------------------
SQL_TEXT                       = select * from dept where deptno=:a
SQL_ID                         = 6a2y9jbwu5fz9
ADDRESS                        = 00000000BF56C328
CHILD_ADDRESS                  = 00000000B5ED9E80
CHILD_NUMBER                   = 1
OPTIMIZER_MODE_MISMATCH        = Y
--------------------------------------------------

PL/SQL procedure successfully completed.

时间: 2024-09-20 14:54:37

查看v$sql_shared_cursor视图获取sql语句为什么不能共享?的相关文章

使用优化器性能视图获取SQL语句执行环境

    Oracle SQL语句的运行环境分为多个不同的层次,主要包括实例级别,会话级别,语句级别,其优先级依次递增.即语句级别的执行环境具有最高的优先权,会话级别次之,实例级别最低.反过来,实例级别的环境设置影响全局,而会话级别的则影响当前会话,语句级别的设置当然也就只影响当前语句.由此可知,运行环境中每一个环节的参数都对最终的数据库性能或所执行的SQL语句有直接的影响.因此在对数据库优化或调试SQL时,获得当前SQL语句运行环境显得尤为重要.为此,Oracle提供了三个重要的视图来获取不同级

使用 EXPLAIN PLAN 获取SQL语句执行计划

     SQL查询语句的性能从一定程度上影响整个数据库的性能.很多情况下,数据库性能的低下差不多都是不良SQL语句所引起.而SQL语句的执行 计划则决定了SQL语句将会采用何种方式从数据库提取数据并返回给客户端,本文描述的将是如何通过EXPLAIN PLAN 获取SQL语句执行计划来获 取SQL语句的执行计划. 一.获取SQL语句执行计划的方式     1. 使用explain plan 将执行计划加载到表plan_table,然后查询该表来获取预估的执行计划      2. 查询动态性能视图

20140321]查看大量消耗资源的sql语句.txt

20140321]查看大量消耗资源的sql语句.txt 昨天看Apress.Oracle.Database.12c.Performance.Tuning.Recipes.Dec.2013.pdf,发现P394提高一个 sql语句查看Resource-Intensive SQL in Memory很有意思,做一个记录: Viewing Resource-Intensive SQL in Memory P394 SELECT sql_id, substr(sql_text,1,20) ,disk_r

从Linq中获取sql语句

问题描述 通常,我们直接IQueryable<T>.ToList()获取IList<T>,但这一次我需要得到其对应的sql语句,然后对sql语句进行再加工.我记得是有这样一个功能的,而且也应该有这样一个功能呀,不然最终用的sql从哪里来?我主要是要利用Sphinx,需要将正常Linq得到的结果和SphinxOE进行join. 解决方案 解决方案二:直接写sql吧用EF的SqlQueryhttps://msdn.microsoft.com/en-us/data/jj592907.as

[20120216]查看数据库整体性能问题sql语句.txt

http://dbatrain.wordpress.com/2010/11/22/do-you-have-an-oracle-background/ 从这个blog获得这个sql语句,通过这个查询到生产系统数据库一个seqence没有设置好. /* Formatted on 2012/02/16 09:45 (Formatter Plus v4.8.8) */column value format 9999,9999,9999,9999column stat_name format a60SEL

magento -- 在Magento中获取SQL语句

       Magento是在Zend Framework的基础上搭建而来,有两种方式可以从Magento的collection获得真正的SQL语句.   以 Mage::getResourceModel('reports/product_collection') 为例:   1          $collection=Mage::getResourceModel('reports/product_collection'); $collection->printlogquery(true);

Oracle 历史SQL语句执行计划的对比与分析

    基于CBO优化器的环境中,SQL执行计划的生成依赖于统计信息的真实与完整.如列的离散度,列上的直方图,索引的可用性,索引上的聚簇因子.当这些信息是真实完整的情况下,CBO优化器通常都可以制定最优的执行计划.也正因此CBO优化器也灵活,难以控制,任一信息的不真实或缺失都可能导致执行计划发生变化而产生多个版本.经常碰到的情形是之前的某个SQL语句前阵子还不是TOP SQL,而最近变成了TOP SQL.或者说之前尽管是TOP SQL但,但最近尽然成了TOP 1.对于此情形,我们可以比对SQL语

MySQL中使用SQL语句查看某个表的编码方法_Mysql

MySQL中,如何使用SQL语句来查看某个表的编码呢?我们使用show create table 这一SQL语句来解决这个问题. show create table可以查看创建这个表的SQL语句脚本,它的基本语法是: show create table <表名>; 我们用它看看test表的create脚本: mysql> show create table test; +-------+--------------------------------------------- -----

SqlServer如何通过SQL语句获取处理器(CPU)、内存(Memory)、磁盘(Disk)以及操作系统相关信息

在SQL SERVER中如何通过SQL语句获取服务器硬件和系统信息呢?下面介绍一下如何通过SQL语句获取处理器(CPU).内存(Memory).磁盘(Disk)以及操作系统相关信息.如有不足和遗漏,敬请补充.谢谢! 一:查看数据库服务器CPU的信息 ---SQL 1:获取数据库服务器的CPU型号 EXEC xp_instance_regread 'HKEY_LOCAL_MACHINE', 'HARDWARE\DESCRIPTION\System\CentralProcessor\0', 'Pro