Nienawidzę JDBC
Kod:
public int myMethod(String day) throws SQLException{
String sql = "Select count(*) from MyTable WHERE someColumn = ? ";
Connection connection = ConnFactory.get();
PreparedStatement prepareStatement = null;
ResultSet resultSet = null;
int ret = -1;
try{
prepareStatement = connection.prepareStatement(sql);
prepareStatement.setString(1, day);
resultSet = prepareStatement.executeQuery(sql);
if(resultSet.next()){
ret = resultSet.getInt(1);
}
}
catch(SQLException sqle){
// closing statement & ResultSet, log and throw exception
}
finally{
// closing statement & ResultSet
}
ConnFactory.kill(connection);
return ret;
}
Wynik wywołania 0. Prawidłowy wynik około 100. Jeżeli usunę klauzulę WHERE to zaczyna zwracać prawidłowe wyniki. Czy ktoś może mi powiedzieć dlaczego się tak dzieje?












October 1st, 2009 at 16:30
A nie jest tak że poprostu robisz błędy SQL, sprawdzałeś go jak on wygląda toString ?
Jaka baza danych ?
October 1st, 2009 at 18:34
A to nie jest jakiś problem z formatem daty? Może wysyłasz bazie (zmienna
day)'1 październik 2009'lub'01-10-2009'a baza oczekuje'2009-10-01'?October 1st, 2009 at 22:24
Błędny warunek WHERE. Nie ma czegoś takiego jak “kolumna=?”
October 2nd, 2009 at 07:35
@Sharpek, pisanie SQLek zaczynam zazwyczaj od SQLdevelopera i jak tam rusza to przenoszę do kodu. W SQDdevie działało.
@KosQX, zmienna ma prawidłowy format, YYYYMMDD i raczej innego nie da się tam wpuścić, bo by mi walidator odwalił.
@regdos, niestety jest. Jeżeli używasz PrepareStatement to możesz tak jak w powyższym kodzie wstawić znaki zapytania, a następnie wywołać metodę setXXX(int, XXX), gdzie XXX to typ danych lub Object, w celu ustawienia wartości tego pola. To jest taki myk, którego chyba nie ma w php i pozwala we w miarę prosty sposób zabezpieczyć się przed SQL Injection.
Baza Oracle 10g + driver OJDBC14.
October 2nd, 2009 at 12:00
Jeśli to Oracle, to bardzo zdecydowanie radzę napisać jakieś
TO_DATE(?, ‘YYYY-MM-DD’)
Choć problem węszę najbardziej w czymś innym: czy aby kolumna w bazie nie jest datą z czasem? Może nic nie znajdujesz ze względu na godziny i minuty…
Aha: różnice w działaniu między developerem a programem mogą wynikać ze środowiska (ustawienia językowe w szczególności).
October 3rd, 2009 at 21:08
@Mekk, też nie to. Kolumna ma typ Number.
October 5th, 2009 at 08:18
Jeśli someColumn ma typ Number to może spróbuj: prepareStatement.setInt(1, Integer.parseInt(day));
?
October 5th, 2009 at 09:46
Coś jest strasznie popieprzone z bazą… jakieś wiszące transakcje dla niektórych rekordów… akurat tych na których testowałem… kuźwa… a i tak nienawidzę JDBC.
October 5th, 2009 at 21:32
może poszukaj wsparcia w firmie, która dostarczyła Ci oprogramowanie… chyba że Sam sobie dostarczyłeś
pozdrawiam,
gzat
October 6th, 2009 at 11:58
@Grzegorz, niestety korzystamy z legacy kodu i nie za bardzo mamy możliwość dopisania czegoś w JPA. Zatem muszę się bawić w ten sposób.
October 7th, 2009 at 14:34
Mieliśmy kiedyś podobne problemy na iSeries (AS400, baza 5.4).
Proponuję:
1. SELECT COUNT(*) AS RES FROM TABLE WHERE COL = ?
rs.getInt(“RES”) – czasem pomaga
1.a. SELECT COUNT(PK_COL) AS RES FROM TABLE WHERE COL = ?
2. setString(data.trim()) – JDBC czasem wie lepiej jaki jest typ danych
3. zgodnie z jedną z powyższych podpowiedzi – użyj dokładnie takiego samego typu danych. W PreparedStatement można podejrzeć inspektorem (debug) faktyczne zapytanie – może to pomoże.
October 8th, 2009 at 12:34
A czy możesz podejrzeć w logach serwera db jakie zapytanie jest do niego wysyłane?
October 8th, 2009 at 16:10
Jeszcze coś mi przyszło do głowy… Czy w warunku ustawiasz dni tygodnia? Jeśli tak to może ustawiasz złe wartości dla zmiennej day? Calendar.SUNDAY=1, Calendar.MONDAY=2. To tylko takie moje gdybanie…