2009-04-16 4 views
1

Ich verwende den offiziellen Sybase-JDBC-Treiber, um eine Verbindung zu einer Datenbank herzustellen und eine gespeicherte Prozedur aufzurufen, indem ich ein CallableStatement-Objekt erstelle, die Parameter daran bindest und .execute() darauf aufruft.Warum "ißt" der Sybase JDBC-Treiber die Ausnahmen?

Allerdings habe ich festgestellt, dass keine Ausnahme ausgelöst wird, auch wenn die gespeicherte Prozedur fehlschlägt. Ich kann überprüfen, ob der Fehler an mich weitergegeben wurde, indem ich den Datenverkehr mit Wireshark in die Datenbank geschnüffelt und die Fehlermeldungen beobachtet habe, die zurückkommen.

Schließlich fand ich, dass .executeUpdate mit() anstelle von .execute() mir die Ausnahmen nicht geben, jedoch habe ich noch zwei Fragen offen:

  1. Warum sind .execute() und .executeUpdate() verhält sich anders? Von der SUN-Dokumentation der Schnittstelle scheint es, dass sie (fast) das gleiche tun sollten ...
  2. Ist es immer angemessen, .execute() mit .executeUpdate() beim Aufrufen einer gespeicherten Prozedur zu ersetzen? Muss die gespeicherte Prozedur bestimmten Anforderungen entsprechen, damit sie mit .executeUpdate() aufgerufen werden kann? (Zum Beispiel muss ein Update haben/Löschen/Insert-Anweisung als letzten Schritt?)

aktualisieren: Ich habe jTDS versucht, und es verhält sich korrekt (wie in: die SQLException in beide wirft Fälle - mit .execute() und mit .executeUpdate()). Aufgrund von Einschränkungen, die außerhalb meiner Kontrolle liegen, ist es jedoch nicht möglich, den Treiber auszuschalten.

Auch: Ich bin nicht interessiert an das Ergebnis von dieser gespeicherten Prozedur zurückgegeben, es ist ein Einfüge-/Update-Typ-Verfahren. Ich würde nur eingefügt werden, um zu sehen (und in der Lage sein zu fangen/loggen), wenn es scheitert oder nicht. Eine andere Sache, die ich versucht habe, ist, die Warnungen nach .execute() aus der Verbindung zu bekommen, aber es enthielt auch nichts.

+1

verhalten sich andere Treiber gleich? Was ist mit jTDS? http://jtds.sourceforge.net/ –

Antwort

5

Weil diese Sybase Leute verrückt sind, deshalb isst es Ausnahmen! Es gibt keinen Grund, die Verwendung von executeUpdate() für vorbereitete/aufrufbare Anweisungen zu vermeiden. Wenn das ist, was Sie verwenden müssen, um es zum Laufen zu bringen, dann gehen Sie voran und tun Sie es. Aber Sie sollten einen Fehlerbericht mit Sybase einreichen - es gibt keinen Grund, warum der Treiber das tun sollte.

0

wissen nichts über Sybase aber

executeUpdate gibt mehr Infos als ausführen: die Anzahl der Zeilen eingefügt/aktualisiert/gelöscht

-> es ist verwendbar mit UPDATE INSERT DELETE und DML-Operationen nach zum Javadoc.

executeQuery gibt ein ResultSet zurück, dies ist für SELECT-Anweisungen.

1

nicht sicher, ob die Sybase-Leute "verrückt" sind. Könnte sein.

Auf der anderen Seite, nicht synchron Ergebnisse abrufen, wenn Sie nicht aktiv nach dem Rückkehrcode einer aufrufbaren Anweisung suchen, kann Leistung sinnvoll sein. Ich habe es noch nicht vollständig getestet, aber es gibt eine einfache Problemumgehung (ASE 15.5, jconn 7):

die Ausnahme ausgelöst wird, wenn Sie einen aus param aus dem gespeicherten proc (zumindest holen, wenn Aufruf von gespeicherten Prozeduren):

// one may force the error check by retrieving the return code! 
    cs = conn.prepareCall("{ ? = call sp_nested_error @nNestLevels = 1 }"); 
    cs.registerOutParameter(1, Types.INTEGER); 
    cs.execute(); 
    try { 
     cs.getInt(1); 
     fail(); 
    } catch(SQLException e) { 
     assertTrue(e.getMessage().indexOf("some error") > -1); 
    } 

Eine weitere Kuriosität ist, dass dieses Verhalten nur auftaucht Wenn Fehler in geschachtelten gespeicherten Prozeduraufrufen ausgelöst werden, ist die Problemumgehung nicht erforderlich, wenn die oberste Prozedur den Fehler auslöst.