2009-07-15 34 views
9

Tôi muốn thực hiện ghi nhật ký tất cả các câu lệnh được thực hiện với các tham số liên kết thực tế khi sử dụng Oracle JDBC. Và tôi thích rằng tôi có thể tạo phương thức ghi như vậy chỉ truyền đối tượng PreparedStatement làm tham số.Cách lấy giá trị của các tham số liên kết từ đối tượng Oracle JDBC PreparedStatement

Ví dụ tôi đã tạo PreparedStatement và chịu ràng buộc một tham số

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

Bây giờ tôi muốn để có thể nhận được từ ps các câu lệnh SQL thực tế "SELECT * FROM nhân viên ĐÂU employe_id = 1" mà tôi có thể đặt vào tệp nhật ký.

Cho đến nay tôi thấy rằng tôi có thể sử dụng

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

để có được

SELECT * FROM employees WHERE employe_id = ? 

Bây giờ tôi cần một số cách để có được danh sách các biến ràng buộc hiện tại từ ps vì vậy mà tôi có thể thay thế? với các giá trị tham số liên kết.

Tôi cố gắng tìm trong ps.getClass() getDeclaredFields() và ps.getClass(). GetSuperclass(). GetDeclaredFields() nhưng cho đến nay không thể tìm thấy vị trí mà giá trị tham số liên kết và loại của chúng được lưu trữ .

Bất kỳ đề xuất nào để tìm kiếm chúng?

Trả lời

2

Hầu hết khung đăng nhập đều có khái niệm cho Nested Diagnostic Context. Bạn có thể lưu truy vấn của bạn và các tham số của nó ở đó khi bạn điền vào câu lệnh đã chuẩn bị.

Hoặc, có lẽ, làm điều đó chỉ trong một bước:

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

Tôi vẫn cần tạo nó ngay từ PreparedStatement. Tôi cần điều này cho một thư viện, nơi tôi thêm hỗ trợ Oracle ngoài MySQL và PostgreSQL và các cơ sở dữ liệu khác và có chức năng ghi nhận chấp nhận đối tượng PreparedStatement như đối số. Trong trình điều khiển JDBC của MySQL và PostgreSQL nếu bạn gọi toString() trên đối tượng PreparedStatement thì nó trả về SQL với các tham số liên kết kèm theo - tôi cần triển khai chức năng tương tự cho Oracle. –

+0

Sau đó, có thể thay đổi thư viện để hoạt động theo cách này? Khác hơn thế, bắt đầu gỡ lỗi mã oracle của bạn và phá vỡ các tuyên bố chuẩn bị. Sau đó, xem cấu trúc và định vị địa điểm riêng nơi lưu trữ các giá trị. – akarnokd

+0

Vấn đề này có mùi giống như ORM ở đằng kia ... – ATorras

1

Bạn có thể có một cái nhìn tại p6spy, đó là một proxy để điều khiển cơ sở dữ liệu của bạn cho phép giám sát và khai thác gỗ.

+0

Như tôi đã nhận xét về câu trả lời trước đây, tôi muốn thực hiện hỗ trợ Oracle trong một thư viện hiện có và do đó cần thực hiện việc ghi nhật ký này và không sử dụng công cụ bổ sung. –

+0

Nó không thể được thực hiện chỉ với PreparedStatement. Nếu bạn không thấy nó trong API javadocs, bạn không thể làm điều đó. – duffymo

Các vấn đề liên quan