如何在不访问源代码的情况下确定 Oracle 查询?
Posted
技术标签:
【中文标题】如何在不访问源代码的情况下确定 Oracle 查询?【英文标题】:How to determine an Oracle query without access to source code? 【发布时间】:2009-01-14 11:21:28 【问题描述】:我们有一个系统,该系统带有一个我们可以访问(尽管可能不是管理访问)的 Oracle 后端和一个我们没有源代码的前端。数据库很大,不容易理解——我们没有文档。总的来说,我对 Oracle 也不是特别了解。
前端的一个方面向数据库查询一组特定的数据并将其显示出来。我们需要确定正在执行什么查询,以便我们可以在没有前端的情况下复制和自动化它(例如,通过定期生成 csv 文件)。
您将使用哪些方法来确定检索这组数据所需的 SQL?
目前我倾向于使用 EeePC、Wireshark 和集线器(可能无法在客户端机器上安装 Wireshark),但我很想听听任何其他想法以及是否有人能想到任何陷阱使用这种特殊的方法。
【问题讨论】:
【参考方案1】:显然有很多方法。我觉得最简单的一个是:
(1) 以 SYS 或 SYSTEM 连接数据库
(2) 查询 V$SESSION 以识别您感兴趣的数据库会话。 记录 SID 和 SERIAL# 值。
(3) 执行以下命令激活会话跟踪:
exec sys.dbms_system.set_bool_param_in_session( *sid*, *serial#*, 'timed_statistics', true )
exec sys.dbms_system.set_int_param_in_session( *sid*, *serial#*, 'max_dump_file_size', 2000000000 )
exec sys.dbms_system.set_ev( *sid*, *serial#*, 10046, 5, '' )
(4) 在客户端应用中执行一些操作
(5) 终止数据库会话(例如通过关闭客户端)或停用跟踪( exec sys.dbms_system.set_ev( sid, serial#, 10046, 0, '' ) )
(6) 在数据库服务器上找到 udump 文件夹。数据库会话将有一个跟踪文件显示执行的语句和每次执行中使用的绑定值。
此方法不需要对客户端计算机进行任何访问,这可能是一个好处。它确实需要访问数据库服务器,如果您不是 DBA 并且他们不允许您进入机器,这可能会出现问题。此外,如果您有许多客户端或客户端应用程序打开多个会话,则可能很难确定要跟踪的正确会话。
【讨论】:
我还不知道我是否能够访问数据库机器本身 - 我会在几周后(希望)知道我们何时开始。不过,这和 tuinstoel 的回复给了我很多尝试,谢谢。【参考方案2】:从查询 Oracle 系统视图开始,例如 V$SQL、v$sqlarea 和 v$sql 文本。
【讨论】:
这绝对是一种可能的方法,但是根据系统上的活动级别,可能很难识别您感兴趣的特定语句。如果您想要最近的所有语句的概述执行,这很好。【参考方案3】:Oracle 的哪个版本?如果它是 10+ 并且您具有管理权限 (sysdba),那么您可以通过 Oracle 企业管理器相对容易地找到执行的查询。
对于旧版本,您需要访问 tuinstoel 在他的回答中提到的视图。
您可以通过 TOAD for oracle 获得相同的数据,这是一款功能强大的软件,但价格昂贵。
【讨论】:
【参考方案4】:Wireshark 确实是个好主意,它有 Oracle 支持并且可以很好地显示整个对话。
如果您没有数据库服务器的管理员权限但您可以访问网络(例如,因为以太网交换机上有端口镜像),那么像 Wireshark 这样的数据包嗅探器会特别有趣。
【讨论】:
【参考方案5】:我已经成功使用过这些说明多次: http://www.orafaq.com/wiki/SQL_Trace#Tracing_a_SQL_session
【讨论】:
【参考方案6】:“虽然可能不是管理访问”。某人应该具有管理权限,可能是负责备份的人。至少,我希望您有一个对运行 oracle 数据库的机器具有 root/Administrator 访问权限的用户。管理员应该能够使用 “SQLPLUS / AS SYSDBA”语法将提供完全访问权限(这可能非常危险)。 root 可以向 oracle 用户“su”并执行相同操作。
如果您确实无法获得管理员访问权限,那么作为wireshark 的替代方案,如果您的前端通过Oracle 客户端连接到数据库,请查找文件sqlnet.ora。您可以设置trace_level_client、trace_file_client和trace_directory_client,并让它记录客户端和数据库服务器之间的Oracle网络流量。
但是,客户端可能会调用存储过程并将数据作为输出参数或引用游标检索,这意味着您可能看不到通过该机制执行的查询。如果是这样,您将需要对数据库服务器的管理员访问权限,并按照 Dave Costa 的回答进行跟踪
【讨论】:
【参考方案7】:如果您可以在行为中捕获 SQL 语句,那么一种快速而肮脏的方法是在 SQL*Plus 中运行它:-
set verify off lines 140 head on pagesize 300
column sql_text format a65
column username format a12
column osuser format a15
break on username on sid on osuser
select S.USERNAME, s.sid, s.osuser,sql_text
from v$sqltext_with_newlines t,V$SESSION s
where t.address =s.sql_address
and t.hash_value = s.sql_hash_value
order by s.sid,t.piece
/
您需要访问这些 v$ 视图才能使其工作。通常这意味着作为系统连接。
【讨论】:
以上是关于如何在不访问源代码的情况下确定 Oracle 查询?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不保存 MS 访问查询的情况下将查询数据导出到 txt 文件
如何在不使用集合运算符的情况下在 oracle 中查找不匹配的行并加入 & 还查询特定行的不匹配列名
如何在不进行分组的情况下在Oracle中向SQL结果添加虚拟行