2009-07-15 401 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,這是一個代理服務器到數據庫驅動程序,允許監測和記錄。