如何查看正在执行的实际Oracle SQL语句

时间:2008-09-11 06:26:01

标签: sql oracle

我正在使用定制的内部应用程序,每周生成一组标准报告。我无法访问应用程序的源代码,每个人都告诉我没有可用于Oracle数据库架构的文档。 (AARGH!)

我被要求为现有报告的变体定义规范(例如,应用其他过滤器来约束数据集,并稍微修改布局)。原则上这听起来很简单,但没有任何现有文档很难。

我的理解是日志无法帮助我,因为报告只查询数据库;它实际上并没有插入,删除或更新数据库值,所以没有任何记录(这是正确的吗?)。

所以我的问题是:是否有一个工具或实用程序(Oracle或其他),我可以使用它来查看报告生成作业仍在运行时正在执行的实际SQL语句?我想,如果我能看到实际访问哪些表来生成现有报告,我将有一个非常好的起点来探索模式并确定用于我自己的报告的正确SQL。

6 个答案:

答案 0 :(得分:24)

在数据字典方面,您可以使用许多工具,例如Schema Spy

要查看正在运行的查询,请查看视图sys.v_ $ sql和sys.v_ $ sqltext。您还需要访问sys.all_users

需要注意的是,使用参数的查询将显示一次,例如

and TABLETYPE=’:b16’

而其他人不会多次出现,例如:

and TABLETYPE=’MT’

这些表的一个例子是使用以下SQL来查找前20个diskread hog。您可以通过删除 WHERE rownum< = 20 并添加 ORDER BY模块来更改此设置。您经常会发现该模块将为您提供关于运行查询的软件的线索(例如:“TOAD 9.0.1.8”,“JDBC瘦客户端”,“runcbl @ somebox(TNS V1-V3)”等)

SELECT 
 module, 
 sql_text, 
 username, 
 disk_reads_per_exec, 
 buffer_gets, 
 disk_reads, 
 parse_calls, 
 sorts, 
 executions, 
 rows_processed, 
 hit_ratio, 
 first_load_time, 
 sharable_mem, 
 persistent_mem, 
 runtime_mem, 
 cpu_time, 
 elapsed_time, 
 address, 
 hash_value 
FROM 
  (SELECT
   module, 
   sql_text , 
   u.username , 
   round((s.disk_reads/decode(s.executions,0,1, s.executions)),2)  disk_reads_per_exec, 
   s.disk_reads , 
   s.buffer_gets , 
   s.parse_calls , 
   s.sorts , 
   s.executions , 
   s.rows_processed , 
   100 - round(100 *  s.disk_reads/greatest(s.buffer_gets,1),2) hit_ratio, 
   s.first_load_time , 
   sharable_mem , 
   persistent_mem , 
   runtime_mem, 
   cpu_time, 
   elapsed_time, 
   address, 
   hash_value 
  FROM
   sys.v_$sql s, 
   sys.all_users u 
  WHERE
   s.parsing_user_id=u.user_id 
   and UPPER(u.username) not in ('SYS','SYSTEM') 
  ORDER BY
   4 desc) 
WHERE
 rownum <= 20;

请注意,如果查询很长,则必须查询v_ $ sqltext。这将存储整个查询。您将不得不查找ADDRESS和HASH_VALUE并获取所有部分。例如:

SELECT
 *
FROM
 sys.v_$sqltext
WHERE
 address = 'C0000000372B3C28'
 and hash_value = '1272580459'
ORDER BY 
 address, hash_value, command_type, piece
;

答案 1 :(得分:8)

很抱歉答案很简短,但已经很晚了。 Google“oracle event 10046 sql trace”。最好跟踪单个会话,因为如果它是共享的sql并被多个用户使用,那么从v $ sql中确定哪个SQL属于哪个会话并不容易。

如果您想给您的Oracle DBA朋友留下深刻印象,请了解如何使用事件10046设置oracle跟踪,解释等待事件的含义并找到最佳cpu使用者。

Quest有一个免费的产品,可以让你捕获从客户端发出的SQL,但不确定它是否适用于你的产品/版本的Oracle。谷歌“为此探索oracle sql监视器”。

晚安。

答案 2 :(得分:3)

我认为V$SQLAREA表包含您要查找的内容(请参阅列 SQL_TEXT SQL_FULLTEXT )。

答案 3 :(得分:2)

是的,这绝对有可能。 v $ sql视图包含该信息。像this piece of code这样的东西应该指向正确的方向。我自己没有尝试过那段特定的代码 - 现在远不及Oracle数据库。

[编辑]该死的其他两个答案已经。下次必须输入更快; - )

答案 4 :(得分:1)

- 我使用类似的东西,概念和一些代码从asktom中窃取。
- 欢迎提出改进建议


sess AS (
    SELECT *
    来自V $ SESSION
    在哪里USERNAME =用户
    按SID订购

SELECT si.SID,
       si.LOCKWAIT,
       si.OSUSER,
       si.PROGRAM,
       si.LOGON_TIME,
       si.STATUS,
       (
           SELECT ROUND(USED_UBLK * 8 / 1024,1)
           来自V $ TRANSACTION,
                SESS
           在哪里sess.TADDR = V $ TRANSACTION.ADDR
           AND sess.SID = si.SID

        )rollback_remaining,

        (
           SELECT(MAX(DECODE(PIECE,0,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,1,SQL_TEXT,NULL))||
                   MAX(DECODE(PIECE,2,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,3,SQL_TEXT,NULL))||
                   MAX(DECODE(PIECE,4,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,5,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,6,SQL_TEXT,NULL))||
                   MAX(DECODE(PIECE,7,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,8,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,9,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,10,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,11,SQL_TEXT,NULL))||
                   MAX(DECODE(PIECE,12,SQL_TEXT,NULL))||
                   MAX(DECODE(PIECE,13,SQL_TEXT,NULL))||
                   MAX(DECODE(PIECE,14,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,15,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,16,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,17,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,18,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,19,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,20,SQL_TEXT,NULL))||
                   MAX(DECODE(PIECE,21,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,22,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,23,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,24,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,25,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,26,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,27,SQL_TEXT,NULL))||
                   MAX(解码(PIECE,28,SQL_TEXT,NULL))||
                   MAX(DECODE(PIECE,29,SQL_TEXT,NULL)))
            来自V $ SQLTEXT_WITH_NEWLINES
            在哪里ADDRESS = SI.SQL_ADDRESS和
            PIECE&lt; 30个
        )SQL_TEXT
来自sess si;

答案 5 :(得分:0)

我在Java应用程序中遇到过类似的问题。我在Oracle驱动程序周围编写了一个JDBC驱动程序包装器,因此所有输出都被发送到日志文件。