Frage

Eine Sache, die ein Schmerz immer ist SQL (JDBC) Fehler zu protokollieren, wenn Sie ein PreparedStatement anstelle der Abfrage selbst haben.

Sie am Ende immer mit Meldungen wie:

2008-10-20 09:19:48,114 ERROR LoggingQueueConsumer-52 [Logger.error:168] Error 
executing SQL: [INSERT INTO private_rooms_bans (room_id, name, user_id, msisdn, 
nickname) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE room_id = ?, name = ?, 
user_id = ?, msisdn = ?, nickname = ?]

Natürlich habe ich eine Hilfsmethode zum Abrufen der Werte schreiben könnte und Parsen / ersetzen die Fragezeichen mit realen Werten (und wird nach unten gehen wahrscheinlich diesen Weg, wenn ich nicht ein Ergebnis dieser Frage bekommen), aber ich wollte nur zu wissen, ob dieses Problem vor von jemandem anderen gelöst wurde und / oder ob es eine allgemeine Protokollierung Helfer, dass automatisch für mich tun würde.

Herausgegeben nach einigen Antworten:

Die Bibliotheken bisher vorgesehen scheint Protokollierung der Aussagen für das Debuggen geeignet zu sein, die ohne Zweifel nützlich ist. Aber ich bin auf der Suche nach einem Weg, um eine PreparedStatement der Einnahme selbst (nicht einige Unterklassen) und Protokollierung seiner SQL-Anweisung, wenn ein Fehler auftritt. Ich möchte nicht über eine Produktions App mit einer alternativen Implementierung von PreparedStatement einzusetzen.

Ich denke, was ich für eine Utility-Klasse suchen, nicht eine PreparedStatement Spezialisierung.

Danke!

War es hilfreich?

Lösung

Ich habe versucht, log4jdbc und es hat den Job für mich.

SECURITY Hinweis: Ab heute August 2011, die protokollierten Ergebnisse einer log4jdbc vorbereitete Anweisung sind nicht sicher auszuführen. Sie können für die Analyse verwendet werden, sollten aber nie wieder in ein DBMS zugeführt werden.

Beispiel: von log durch logjdbc erzeugt:

  

2010.08.12 16.30.56 jdbc.sqlonly   org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate (DelegatingPreparedStatement.java:105)   8. INSERT INTO A_TABLE   (ID_FILE, CODE1, ID_G, ID_SEQUENCE, REF, NAME, BAR, DRINK_ID, AMOUNT, Beschreibung, STATUS, CODE2, REJECT_DESCR, ID_CUST_REJ)   WERTE   (2, '123', 1 '2', 'AA', 'Awe', null, '0123', 4317,95, 'RCCC', '0', null, null, null)

Die Bibliothek ist sehr einfach zu installieren:


Meine Konfiguration mit HSQLDB :

jdbc.url=jdbc:log4jdbc:hsqldb:mem:sample

Mit Oracle :

jdbc.url=jdbc:log4jdbc:oracle:thin:@mybdd:1521:smt
jdbc.driverClass=net.sf.log4jdbc.DriverSpy

logback.xml:

<logger name="jdbc.sqlonly" level="DEBUG"/>

Schade, es war nicht auf einer Maven-Repository, aber immer noch nützlich.
Von dem, was ich versuchte, wenn Sie

Sie werden nur die Anweisungen in Fehlermeldung erhalten, aber ich weiß nicht, ob diese Bibliothek einen Einfluss auf die Leistung hat.

Andere Tipps

Das ist sehr Datenbank abhängig. Zum Beispiel, ich verstehe, dass einige JDBC-Treiber (z sybase, vielleicht MS-SQL) vorbereitete Anweisungen behandeln, indem eine temporäre gespeicherte Prozedur auf dem Server erstellen, und dann diese Prozedur mit den mitgelieferten Argumenten aufgerufen wird. So ist die komplette SQL ist nie wirklich von den Kunden weitergegeben.

Als Ergebnis der JDBC-API deckt nicht die Informationen, die Sie nach sind. Sie können in der Lage sein, Ihre Aussage Objekte die interne Treiber-Implementierung zu werfen, aber wahrscheinlich nicht -. Ihre appserver können die Aussagen in seiner eigenen Implementierung gut wickeln

Ich denke, man kann nur den sauren Apfel beißen und Ihre eigene Klasse schreiben, die die Argumente in den Platzhalter SQL interpoliert. Dies wird schwierig sein, weil Sie nicht PreparedStatement für die Parameter fragen, die gesetzt wurden, so dass Sie sie in einem Hilfsobjekt haben sich daran zu erinnern, bevor sie an die Anweisung übergeben.

Es scheint mir, dass eine der Utility-Bibliotheken, der Wrap-Fahrer Implementierung Objekte ist die praktischste Art und Weise zu tun, was Sie erreichen wollen, aber es wird unangenehm oder so sein.

Verwenden Sie p6spy : Die Oracle, mySQL, JNDI, JMX, Frühling und Maven freundlich. In hohem Maße konfigurierbar. Einfache und Low-Level-Integration Kann die Drucken stacktrace . Kann nur schwere Anrufe drucken -. Zeit Threashold Basis

  1. Wenn Sie mit MySQL, MySQL Connector PreparedStatement.toString () tut umfassen die gebundenen Parameter . Obwohl Fremdverbindungspools können diese brechen.

  2. Unterklasse PreparedStatement die Abfragezeichenfolge aufzubauen als Parameter hinzugefügt werden. Es gibt keinen Weg, um die SQL von einem PreparedStatement zu extrahieren, da es eine kompilierte binäre Form verwendet wird.

scroll top