JDBC, что цель PreparedStatement # setNull
Я сделал эксперимент с таблицей, имеющей столбец VARCHAR с нулевыми значениями, пытающимися получить количество строк, имеющих определенный столбец NULL. Я использовал три формы:
форма A
SELECT COUNT(*) FROM buyers WHERE buye_resp IS NULL
форма B
SELECT COUNT(*) FROM buyers WHERE buye_resp = ?
... где параметр предоставляется с помощью setString (1, null)
форма C
... как форма B, но параметр устанавливается с помощью setNull (1, java.sql.Types.VARCHAR)
Из трех форм, только форма A создала правильный результат, формы B и C оба возвращались 0 (код трех форм в конце сообщения). Что вызывает вопрос: какая цель setNull?
Тестирование, выполняемое в базе данных PostgreSQL 9.2.
код
private static int numOfRows_formA(Connection conn) throws SQLException {
PreparedStatement pstm = null;
ResultSet rs = null;
try {
String pstmStr = "SELECT COUNT(*) FROM buyers WHERE buye_resp IS NULL";
pstm = conn.prepareStatement(pstmStr);
rs = pstm.executeQuery();
rs.next();
return rs.getInt(1);
} finally {
DbUtils.closeQuietly(null, pstm, rs);
}
}
private static int numOfRows_formB(Connection conn) throws SQLException {
PreparedStatement pstm = null;
ResultSet rs = null;
try {
String pstmStr = "SELECT COUNT(*) FROM buyers WHERE buye_resp = ?";
pstm = conn.prepareStatement(pstmStr);
pstm.setString(1, null);
rs = pstm.executeQuery();
rs.next();
return rs.getInt(1);
} finally {
DbUtils.closeQuietly(null, pstm, rs);
}
}
private static int numOfRows_formC(Connection conn) throws SQLException {
PreparedStatement pstm = null;
ResultSet rs = null;
try {
String pstmStr = "SELECT COUNT(*) FROM buyers WHERE buye_resp = ?";
pstm = conn.prepareStatement(pstmStr);
pstm.setNull(1, java.sql.Types.VARCHAR);
rs = pstm.executeQuery();
rs.next();
return rs.getInt(1);
} finally {
DbUtils.closeQuietly(null, pstm, rs);
}
}
Ответы
Ответ 1
SQL использует тернарную логику, поэтому buye_responsible = ?
всегда возвращает unknown
(и никогда true
), когда buye_responsible
есть null
. Для этого вам нужно IS NULL
проверить null
.
setNull()
может использоваться, например, когда вам нужно передать инструкции null
в INSERT
и UPDATE
. Поскольку такие методы, как setInt()
и setLong()
, принимают примитивные типы (int
, long
), вам понадобится специальный метод для передачи null
в этом случае.
Ответ 2
В системе базы данных нуль не равен другому нульу, поэтому
строка SELECT COUNT(*) FROM vat_refund.er_buyers WHERE buye_responsible = null
не вернет никакой записи. Метод setNull() просто устанавливает нуль в позиции индекса. Sets the designated parameter to SQL NULL.
Это из JAVA API. То есть он установит нулевой SQL для этого индекса, но не будет использовать функцию isNull() по вашему желанию.
Вот почему для формы C вы также не получаете никакого результата.