2009-07-15 2 views
9

Ich möchte die Protokollierung aller ausgeführten Anweisungen mit tatsächlichen Bindungsparametern implementieren, wenn Oracle JDBC verwendet wird. Und ich würde es vorziehen, dass ich eine solche Protokollierungsmethode erstellen könnte, die nur das PreparedStatement-Objekt als Parameter übergibt.Wie Werte von Bindeparametern aus Oracle erhalten werden JDBC PreparedStatement-Objekt

Zum Beispiel habe ich erstellt PreparedStatement und gebunden haben einen Parameter

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

Nun möchte ich von ps erhalten zu können, wie die tatsächliche SQL-Anweisung „SELECT * FROM Mitarbeiter WHERE employe_id = 1“, was ich konnte Log-Datei einfügen.

Bisher fand ich, dass ich

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

SELECT * FROM employees WHERE employe_id = ? 

Jetzt bekommen verwenden kann ich irgendwie müssen die Liste der aktuellen Bind-Variablen von ps zu erhalten, damit ich ersetzen könnte? mit Bindeparameterwerten.

Ich habe versucht, in ps.getClass(). GetDeclaredFields() und ps.getClass(). GetSuperclass(). GetDeclaredFields() zu suchen, aber konnte bisher die Stelle nicht finden, wo Bindung Parameterwerte und ihre Typen gespeichert sind .

Irgendwelche Vorschläge, wo man nach ihnen suchen?

Antwort

2

Die meisten Logging-Framework haben die Idee für Nested Diagnostic Context. Sie können Ihre Abfrage und ihre Parameter dort speichern, wenn Sie die vorbereitete Anweisung ausfüllen.

Oder vielleicht tun es in einem Schritt:

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

Ich muss es immer noch nur von PreparedStatement generieren. Ich brauche das für eine Bibliothek, wo ich Oracle-Unterstützung zusätzlich zu MySQL und PostgreSQL und anderen Datenbanken hinzufüge und dort die Logging-Funktion nur das PreparedStatement-Objekt als Argument akzeptiert. In MySQL und PostgreSQL JDBC-Treiber, wenn Sie toString() auf PreparedStatement-Objekt aufrufen, dann gibt es SQL mit enthaltenen Bind-Parameter zurück - ich muss ähnliche Funktionalität für Oracle implementieren. –

+0

Dann vielleicht die Bibliothek selbst ändern, um auch so zu arbeiten? Andernfalls starten Sie das Debuggen Ihres Oracle-Codes und brechen Sie die vorbereitete Anweisung ab. Dann schau dir die Struktur an und finde den privaten Ort, an dem die Werte gespeichert sind. – akarnokd

+0

Dieses Problem riecht wie ein ORM ist da drüben ... – ATorras

1

Sie einen Blick auf p6spy haben kann, ist es ein Proxy auf Ihre Datenbanktreiber ist die Überwachung und Protokollierung ermöglicht.

+0

Als ich die vorherige Antwort kommentiert habe, möchte ich die Oracle-Unterstützung in einer vorhandenen Bibliothek implementieren und muss daher diese Protokollierung programmgesteuert durchführen und kein zusätzliches Tool verwenden. –

+0

Es kann nicht nur mit dem PreparedStatement durchgeführt werden. Wenn Sie es nicht in der Javadocs-API sehen, können Sie es nicht tun. – duffymo