Привязка переменной null в PreparedStatement

Я клянусь, что это сработало, но это не в этом случае. Я пытаюсь сопоставить col1, col2 и col3, даже если один или несколько из них равны нулю. Я знаю, что на некоторых языках мне приходилось прибегать к таким околичностям, как ((? is null AND col1 is null) OR col1 = ?). Это требуется здесь?

        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);
    }

4 ответов


это может зависеть от драйвера JDBC, но по большей части, да, вам нужно будет использовать более расширенную форму, которую вы показываете выше.

подготовленные операторы JDBC обычно являются относительно тонкими оболочками вокруг собственной реализации параметризованного запроса, т. е. запроса с ? вместо параметров передаются в компилятор запросов и компилируются, поэтому, позже, при вызове stmt.executeQuery (), оператор не может быть настроен из column = ? до column IS NULL. Это не так много ограничение JDBC как это семантика NULL в SQL. Для SQL x = NULL не определено как x <> NULL.

тем не менее, некоторые драйверы JDBC могут нарушить понятие NULL - ity в SQL и позволяет setNull () преобразовать оператор из = ? to IS NULL это было бы очень нестандартным поведением (хотя это можно было бы легко сделать, написав какой-то метод предварительной обработки запроса).


какую базу данных вы используете?

но, по крайней мере, с Oracle равенство (и неравенство) никогда не соответствует NULL, вы должны написать не NULL.


обычно что-то, равное нулю, всегда ложно (даже NULL, поэтому SELECT * FROM tbl WHERE NULL=NULL; будет пустым набором), поэтому вам, вероятно, нужно сделать это длинный путь, если вы хотите принять нулевое равенство, как это


Я знаю, что, возможно, слишком поздно, но только ради этого хак для Oracle, который, как мне кажется, работает:

SQL:

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

и в коде, где вы делаете вызов jdbc, что-то вроде этого:

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