A. Produkt: Posgres (eine ansonsten insgesamt wirklich TOLLE Datenbank).
Ja auch Posgres. Werd mal einen ernsthaften chat mit den Entwicklern führen müssen (geht über ICQ).
B.Issue:
Man betrachte den folgenden SQL Query (bold von mir).
Select StockOffer.ID as id, StockOffer.VERSION as version,StockOffer.idUser as idUser,Person.nameUser as nameUser,Stockoffer.idStockDescr As idStockDescr, StockDescr.longName as longNameStock,StockDescr.shortName as shortNameStock,StockOffer.amount As amount,StockOffer.price as price,StockOffer.created as created from StockOffer,Person, StockDESCR where
StockOrder.IDUser = Person.ID and StockDescr.ID = StockOffer.IDStockDescr AND StockOffer.IDStockDescr = 2 AND StockOffer.price <= 41.00 ORDER BY StockOffer.price DESC for update
Bei diesem Query kommt ein Resultset mit 0 Elementen raus.
Ersetze ich StockOrder durch StockOffer wird wie von den Testdaten zu erwarten ein Resultset mit 1 Element gefunden.
Das dort StockOrder statt StockOffer steht ist eindeutig die Folge von copy & paste Aktionen (in der Anwendung zwischen 2 ibatis-config Files und der query wird teilweise von IBatis generiert, wobei der Fehler in meinem Config-File ist).
Ich hätte erwartet, dass Posgres bei sowas einen Fehler generiert.
Nochmal der SQL Query ist so:
Select StockOffer.ID as id, StockOffer.VERSION as version,StockOffer.idUser as idUser,Person.nameUser as nameUser,Stockoffer.idStockDescr As idStockDescr, StockDescr.longName as longNameStock,StockDescr.shortName as shortNameStock,StockOffer.amount As amount,StockOffer.price as price,StockOffer.created as created
from StockOffer,Person, StockDESCR where
StockOrder.IDUser = Person.ID and StockDescr.ID = StockOffer.IDStockDescr AND StockOffer.IDStockDescr = 2 AND StockOffer.price <= 41.00 ORDER BY StockOffer.price DESC for update
Man sieht, dass die in der where Clause referenzierte Tabelle StockOrder überhaupt nicht in der Liste der Tabellen der FROM Clause steht. Theoretisch könnte Posgres diesen Query zurückweisen mit der Meldung, dass StockOrder nicht in der From clause auftaucht. Vielleicht sprechen irgendwelche Performance-Überlegungen dagegen. Ich probiers später mal aus, aber ich bin mir ziemlich sicher, dass DB2 das nicht akzeptieren würde.
C. Wie sich dagegen schützen1. Einfache Queries schreiben. Der Query ist sowieso zu kompliziert. Der inner join mit der Tabelle Person ist überhaupt nicht notwendig.
2. Einfachere Datenbanken schreiben. Im Grunde ist es unnötig, dass es für StockOrder und StockOffer jeweils eine eigene Tabelle gibt. Schlauer wäre es gewesen, beides in eine Tabelle zu packen und mit einer char-Spalte ein flag setzen, ob es Offer oder Order ist.
3. Copy & Paste bei ibatis config Files ist ok, jedoch sollte man den daraus resultierenden von IBatis generierten Query selbst aus dem config-File Query ergänzen und an der Konsole testen (dann wäre es sofort aufgefallen).
4. In der Entwicklungsphase sämtliche aus der Anwendung gegen Posgres geschickten Queries in ein Log File schreiben. So habe ich es herausgefunden. Der folgende Eintrag in log4j.xml ist dafür notwendig:
<logger name="java.sql">
<level value="debug"/>
<appender-ref ref="javasqlconnection"/>
</logger>
Meines Wissens geht das mit LEI nicht so einfach.
Gruß Axel