Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何捕获从Java(tomcat)发送到Oracle数据库的查询?_Java_Oracle_Tomcat_Sniffing - Fatal编程技术网

如何捕获从Java(tomcat)发送到Oracle数据库的查询?

如何捕获从Java(tomcat)发送到Oracle数据库的查询?,java,oracle,tomcat,sniffing,Java,Oracle,Tomcat,Sniffing,我有一个由第三方编写的应用程序,它使用Java/Tomcat与Oracle 12c(12.2.0.1)DB通信。它在日志中报告“插入表时出错”,但没有提供详细信息。在与作者的支持人员交谈时,他们表示这是旧代码,他们无法提供更多细节。他们说MSSQL更好地支持该应用程序,而我们的商店不支持MSSQL 我想看看进入Oracle DB的insert语句是什么样子的,但在v$sqltext中找不到它。作为替代方案,我希望找到像fiddler这样的工具来查看1521端口上的出站流量 是否有特定的工具可以捕

我有一个由第三方编写的应用程序,它使用Java/Tomcat与Oracle 12c(12.2.0.1)DB通信。它在日志中报告“插入表时出错”,但没有提供详细信息。在与作者的支持人员交谈时,他们表示这是旧代码,他们无法提供更多细节。他们说MSSQL更好地支持该应用程序,而我们的商店不支持MSSQL

我想看看进入Oracle DB的insert语句是什么样子的,但在v$sqltext中找不到它。作为替代方案,我希望找到像fiddler这样的工具来查看1521端口上的出站流量

是否有特定的工具可以捕获未加密的流量,以便我可以看到发送的“查询”和从Oracle DB返回的响应

一个普通的嗅探器可能会起作用,但它们通常会得到大量无关的流量,需要大量的捣乱才能找到你想要的东西

注:

正如我在评论中提到的,我不是Tomcat/Java人。我想我找到了类路径的设置位置。给定下面的windows批处理文件,是否需要替换bcprov-jdk16-138.jar的“驱动程序”

set PROJLIB=..\..
set JAVA_HOME=%PROJLIB%\jdk\

set libDIR=%PROJLIB%\appserver\webapps\receiver\WEB-INF\lib
set consoleDIR=%PROJLIB%\bin\lib

set endorsedLibDir=%PROJLIB%\appserver\endorsed

set CPATH= %consoleDIR%\console.jar;%libDIR%\ebxml.jar;%libDIR%\commons-io-1.1.jar;%libDIR%\bcprov-jdk16-138.jar;%libDIR%\xercesImpl.jar

set CLASSPATH=%CPATH%

set PATH=%JAVA_HOME%\bin;%SystemRoot%;%SystemRoot%\system32
补充说明:

上面的文件名为setenv.bat


关于尝试从数据库捕获SQL,该应用程序不是windows应用程序,而是一个从网络接收数据并将其写入数据库的应用程序。这使得准确地知道何时开始和停止监控变得困难。它似乎在很短的一段时间内相互关联。它似乎能够读取数据,但不能插入。

假设您使用的是Oracle JDBC驱动程序,并且您能够在某些环境中替换JDBC驱动程序以调试问题,Oracle会提供执行的SQL语句

另一种方法是在数据库中创建一个日志,记录失败的SQL语句。我相信这将要求失败的SQL语句是格式良好的,如果第三方应用程序在动态组装语句时遇到错误,则无法保证这一点。如果该语句从未出现在
v$sql
中,这可能表明它的格式不好,但值得一试


如果您获得使用AWR/ASH表的许可,您还可以尝试查询
dba\u hist\u active\u sess\u history
。Oracle每秒对活动会话进行一次采样。如果失败的语句恰好在采样中被捕获,您将在那里看到它。如果这是一个典型的执行单行插入的OLTP应用程序,您可能需要运行大量的示例,以便用该语句捕获活动会话,但这可能是合理的。

如果您通过sqldeveloper访问数据库

转到“报告”选项卡,然后向下钻取数据字典、数据库管理、会话,最后是会话

在该视图中,查找应用程序的活动模块并查看活动SQL选项卡。 其中一个应该有您的insert语句

这可能也有帮助。。。
如果您可以本地化数据库会话(使用
gv$session
选择连接
用户名
),则simples方法是

获取连接的
SID
串行#
,并使用以下语句激活10046跟踪。(将SID替换为会话id,将SERIAL替换为SERIAL#num)

请注意,查询
gv$session
和执行
DBMS\u MONITOR
都需要权限,因此需要DBA访问权限才能将它们授予用户

然后检查数据库服务器上文件夹
trace
中的跟踪文件,跟踪文件的名称为
xe\u m005\u 1336.trc

Grep对于表名,您可以看到类似这样的内容,我在表
my\u表

=====================
PARSING IN CURSOR #854854488 len=38 dep=0 uid=104 oct=2 lid=104 tim=380974114197 hv=1259660490 ad='7ff08904d88' sqlid='1ttgvst5j9t6a'
insert into my_table(col1) values(:1 )
END OF STMT
PARSE #854854488:c=0,e=495,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=380974114195
=====================
PARSE ERROR #854854488:len=39 dep=0 uid=104 oct=2 lid=104 tim=380974117361 err=904
insert into my_table(col1) values(:1 )
请注意,这是一个异常示例

java.sql.SQLSyntaxErrorException:ORA-00904:“COL1”:无效标识符

因此,语句失败,出现
解析错误

如果由于某些约束而导致插入失败,您将看到这样的序列

=====================
PARSING IN CURSOR #715594288 len=37 dep=0 uid=104 oct=2 lid=104 tim=382407621534 hv=3290870806 ad='7ff0032e238' sqlid='17t3q0v22dd0q'
insert into my_table(col) values(:1 )
END OF STMT
PARSE #715594288:c=0,e=245,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=382407621532
=====================
光标id是
715594288
,因此在跟踪文件中进一步检查此id

BINDS #715594288:

 Bind#0
  oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
  oacflg=03 fl2=1000000 frm=01 csi=873 siz=24 off=0
  kxsbbbfp=2aa71a00  bln=22  avl=02  flg=05
  value=7
=====================
在这里,您可以看到插入中传递的绑定变量,是值=7导致了失败

EXEC #715594288:c=0,e=4614,p=0,cr=7,cu=0,mis=1,r=0,dep=0,og=1,plh=0,tim=382407626259
ERROR #715594288:err=2290 tim=382407626283
语句执行失败,出现异常,如

java.sql.SQLIntegrityConstraintViolationException:ORA-02290:违反了检查约束(XXXX.SYS\u C0012357)

查看以了解更多详细信息

最终方法是跟踪客户机上的JDBC连接。请查找完整的文档

第一步中必须在
类路径
上获取日志JDBC驱动程序。日志驱动程序的名称中有一个suggix
\u g
,例如,如果使用
ojdbc8.jar

驱动程序可以在Oracle安装中的文件夹
jdbc/lib/

进一步您必须定义一个属性文件,比如带有以下内容的
jdbcloging.properties

.level=SEVERE
oracle.jdbc.level=ALL
oracle.jdbc.handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=FINE
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
最后运行Java应用程序时,必须定义两个属性

 java -Doracle.jdbc.Trace=true -Djava.util.logging.config.file=jdbcLogging.properties ...
这将从错误输出生成一个跟踪文件,您可以在其中找到已执行的语句

范例

INFO: DRCP Enabled: false
Mar 23, 2021 10:40:31 PM oracle.jdbc.driver.OracleStatement logSQL
CONFIG: BAB2F1 SQL: insert into my_table(col1) values(?)

最后我下载了一个嗅探器WireShark,并监视TCP/IP数据包。

监视端口1521将完全实现零。该端口用于侦听器接收传入的连接请求。时期句号。一旦侦听器接收到请求,它就会生成一个专用服务器(或找到一个调度程序),并告诉请求客户端通过另一个未分配的端口与该服务器/调度程序通信。1521上的唯一通信量是入站连接请求和出站消息“继续”
INFO: DRCP Enabled: false
Mar 23, 2021 10:40:31 PM oracle.jdbc.driver.OracleStatement logSQL
CONFIG: BAB2F1 SQL: insert into my_table(col1) values(?)