2010-04-16 10 views
12

Przysięgam, że to zadziałało, ale nie w tym przypadku. Próbuję dopasować col1, col2 i col3, nawet jeśli jeden lub więcej z nich ma wartość null. Wiem, że w niektórych językach musiałem uciekać się do opowiadań takich jak ((? is null AND col1 is null) OR col1 = ?). Czy to jest wymagane tutaj?Wiązanie zmiennej zerowej w Przygotowanej Deklaracji

 PreparedStatement selStmt = getConn().prepareStatement(
       "SELECT  * " + 
       "FROM  tbl1 " + 
       "WHERE  col1 = ? AND col2 = ? and col3 = ?"); 
     try 
     { 
      int col = 1; 
      setInt(selStmt, col++, col1); 
      setInt(selStmt, col++, col2); 
      setInt(selStmt, col++, col3); 
      ResultSet rs = selStmt.executeQuery(); 
      try 
      { 
       while (rs.next()) 
       { 
        // process row 
       } 
      } 
      finally 
      { 
       rs.close(); 
      } 
     } 
     finally 
     { 
      selStmt.close(); 
     } 

    // Does the equivalient of stmt.setInt(col, i) but preserves nullness. 
    protected static void setInt(PreparedStatement stmt, int col, Integer i) 
    throws SQLException 
    { 
     if (i == null) 
      stmt.setNull(col, java.sql.Types.INTEGER); 
     else 
      stmt.setInt(col, i); 
    } 
+0

Zobacz również http://en.wikipedia.org/wiki/Null_%28SQL%29#Three-valued_logic_.283VL.29 – trashgod

Odpowiedz

9

Może to zależeć od sterownika JDBC, ale w większej części, tak, należy użyć bardziej rozszerzonego formularza pokazanego powyżej.

Przygotowane instrukcje JDBC są zwykle względnie cienkimi opakowaniami wokół natywnej implementacji sparametryzowanego zapytania, tj. Zapytania z? w miejsce parametrów przekazywane są do kompilatora zapytań i kompilowane, więc później, gdy wywołasz stmt.executeQuery(), instrukcja nie może zostać zmieniona z column = ? na column IS NULL. To nie jest ograniczenie JDBC, ponieważ jest to the semantics of NULL in SQL. W przypadku SQL x = NULL jest niezdefiniowany, podobnie jak x <> NULL.

Powiedział, że niektóre sterowniki JDBC może naruszać pojęcie NULL -ity w SQL i pozwalają setNull(), aby przekształcić oświadczenie = ? do IS NULL byłoby to bardzo nietypowe zachowanie (choć może to łatwo osiągnąć poprzez pisanie jakiś rodzaj metody wstępnego przetwarzania zapytań).

1

Ogólnie coś jest równe NULL jest zawsze fałszem (nawet NULL, więc SELECT * FROM tbl WHERE NULL=NULL; będzie zbiorem pustym), więc prawdopodobnie trzeba zrobić to długa droga, jeśli chcesz przyjąć zerową równości jak ten

+0

@ michael-Mrozek 'gdzie null = NULL' faktycznie zwraca 'NULL'. Tak więc, na przykład, "SELECT * FROM tbl WHERE NOT (NULL = NULL)" również daje w wyniku pusty zbiór. – ig0774

3

Jakiej bazy danych używasz?

Ale przynajmniej w przypadku Oracle równość (i nierówność) nigdy nie jest równa NULL, trzeba napisać NIE JEST NULL.

0

wiem, że jest zbyt późno, być może, ale tylko ze względu na to hack for Oracle, która wydaje mi się pracuje:

SQL:

SELECT.....FROM....WHERE NVL(CUST_ID,0)=? AND NVL(vendor_id,0)=? 

I w kodzie gdzie wykonać JDBC wywołanie coś takiego:

pstmt.setString(1, (xxo.getCustId().equals("")) ? "0":xxo.getCustId()); 
pstmt.setString(2, (xxo.getVendId().equals("")) ? "0":xxo.getVendId()); 
rs = pstmt.executeQuery(); 
+0

Działa tylko wtedy, gdy masz absolutną pewność, że "0" nie jest poprawnym łańcuchem w kolumnie. –

+0

Tak, zgadzam się. Używam go w kolumnach, gdzie spodziewam się danych, a 0 nie jest jednym z nich i na pewno null też nie jest opcją. Myślę, że jest to dobra sztuczka .... – hephestos

+0

Dlaczego nie "CUST_ID =? OR (? IS NULL AND CUST_ID IS NULL)"? – MikeB

Powiązane problemy