Привязка пустой переменной в PreparedStatement - PullRequest
12 голосов
/ 16 апреля 2010

Клянусь, раньше это работало, но это не так. Я пытаюсь сопоставить 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 ]

9 голосов
/ 16 апреля 2010

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

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

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

3 голосов
/ 16 апреля 2010

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

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

1 голос
/ 16 апреля 2010

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

0 голосов
/ 23 января 2015

Я знаю, что, возможно, слишком поздно, но просто ради этого взломать 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...