2010-04-16 14 views
12

Juro que esto solía funcionar, pero no es en este caso. Estoy intentando hacer coincidir col1, col2 y col3, incluso si uno o más de ellos es nulo. Sé que en algunos idiomas he tenido que recurrir a circumlocutions como ((? is null AND col1 is null) OR col1 = ?). ¿Es eso requerido aquí?Enlazando una variable nula en un Estado Preparado

 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

Véase también http://en.wikipedia.org/wiki/Null_%28SQL%29#Three-valued_logic_.283VL.29 – trashgod

Respuesta

9

Esto puede depender del controlador JDBC, pero en su mayor parte, sí, necesitaría usar la forma más extendida que muestra arriba.

Las declaraciones preparadas de JDBC suelen ser envoltorios relativamente delgados en torno a una implementación nativa de una consulta parametrizada, es decir, la consulta con? en lugar de los parámetros se pasan al compilador de consultas y se compilan, por lo que, más adelante, cuando se llama a stmt.executeQuery(), la instrucción no se puede ajustar desde column = ? a column IS NULL. Esto no es tanto una limitación de JDBC como the semantics of NULL in SQL. Para SQL x = NULL no está definido como x <> NULL.

Dicho esto, algunos controladores JDBC puede violar la noción de NULL -ity en SQL y permitir setNull() para transformar el comunicado de = ? a IS NULL este sería un comportamiento altamente no estándar (aunque se podría lograr fácilmente la escritura algún tipo de método de preprocesamiento de consultas).

1

general algo que es igual a NULL siempre es falsa (incluso NULL, por lo SELECT * FROM tbl WHERE NULL=NULL; habrá un conjunto vacío), por lo que es probable que necesita hacer es el camino más largo si desea aceptar la igualdad nula como la

+0

@ michael-Mrozek 'DONDE NULL = null' en realidad devuelve 'NULL'. Por lo tanto, por ejemplo, 'SELECT * FROM tbl WHERE NOT (NULL = NULL)' también da como resultado un conjunto vacío. – ig0774

3

¿Qué base de datos está utilizando?

Pero al menos con Oracle, la igualdad (y la desigualdad) nunca coincide con NULL, debe escribir IS NOT NULL.

0

sé que es demasiado tarde tal vez, pero sólo por el hecho de que un corte para Oracle que me parece trabajar:

SQL:

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

Y en el código donde se hace la JDBC llamada parecida a:

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

Solo funciona si absolutamente sabes que "0" no es una cadena válida en la columna. –

+0

Sí, estoy de acuerdo. Lo uso en columnas donde espero datos y 0 no es uno de ellos y ciertamente nulo tampoco es una opción. Es un buen truco, creo ... – hephestos

+0

¿Por qué no "CUST_ID =? OR (? IS NULL Y CUST_ID IS NULL)"? – MikeB

Cuestiones relacionadas