2009-07-15 403 views
9

我想在使用Oracle JDBC时实现使用实际绑定参数记录所有已执行的语句。而且我更喜欢我可以创建只传递PreparedStatement对象作为参数的日志记录方法。如何从Oracle JDBC PreparedStatement对象中获取绑定参数的值

例如我已经创建了PreparedStatement和已绑定一个参数

PreparedStatement ps = conn.prepareStatement(
    "SELECT * FROM employees WHERE employee_id = ?"); 
ps.setInt(1,1); 

现在我想可以从PS得到实际的SQL语句“SELECT * FROM雇员WHERE employe_id = 1”,我可以放入日志文件。

到目前为止,我发现我可以使用

((oracle.jdbc.driver.OracleStatement) ps).getOriginalSql() 

得到

SELECT * FROM employees WHERE employe_id = ? 

现在我需要一些方法来摆脱目前的PS绑定变量的列表,以便我能更换?带有绑定参数值。我试图查看ps.getClass()。getDeclaredFields()和ps.getClass()。getSuperclass()。getDeclaredFields(),但到目前为止找不到绑定参数值及其类型存储的位置。

任何建议在哪里寻找他们?

回答

2

大多数日志记录框架都有Nested Diagnostic Context的概念。填写准备好的语句时,可以将查询和参数保存在那里。

或者,也许,这样做的一个步骤:

PreparedStatement fillAndLog(Connection conn, String query, Object... args) { 
    int i = 0; 
    PreparedStatement pstmt = conn.prepareStatement(query); 
    for (Object o : args) { 
     if (o instanceof String) { 
      pstmt.setString(i, (String)o); 
     } // else... 
     i++; 
    } 
    log.debug(String.format(query.replaceAll("\\?", "%s"), args)); 
    return pstmt; 
} 
+0

我仍然需要从PreparedStatement中生成它。我需要一个库,除了MySQL和PostgreSQL以及其他数据库之外,我还需要添加Oracle支持,并且日志记录功能只接受PreparedStatement对象作为参数。 在MySQL和PostgreSQL JDBC驱动程序中,如果您在PreparedStatement对象上调用toString(),那么它会返回包含绑定参数的SQL - 我需要为Oracle实现类似的功能。 – 2009-07-15 11:55:04

+0

那么也许改变图书馆本身以这种方式工作呢?除此之外,开始调试你的oracle代码并打破预备的语句。然后查看结构并找到它存储值的私有位置。 – akarnokd 2009-07-15 12:01:45

1

你可以看看p6spy,这是一个代理服务器到数据库驱动程序,允许监测和记录。