NullPointerException
s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException
. Они наиболее распространены, но другие способы перечислены на странице NullPointerException
javadoc.
Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException
, be:
public class Example {
public static void main(String[] args) {
Object obj = null;
obj.hashCode();
}
}
В первой строке внутри main
я явно устанавливаю ссылку Object
obj
равной null
. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException
, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.
(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)
Это - проблема, которая довольно распространена: генерация отношения на лету, не составляя таблицу. Решения для SQL для этой проблемы являются довольно неловкими. Один пример с помощью полученной таблицы:
SELECT n.id
FROM
(SELECT 2 AS id
UNION SELECT 3
UNION SELECT 4
UNION SELECT 5
UNION SELECT 6
UNION SELECT 7) AS n
LEFT OUTER JOIN foos USING (id)
WHERE foos.id IS NULL;
, Но это не масштабируется очень хорошо, потому что у Вас могло бы быть много значений вместо всего шесть. Это может стать утомительным для построения длинного списка с одним UNION
необходимый на значение.
Другое решение состоит в том, чтобы держать таблицу общего назначения под рукой десяти цифр и неоднократно использовать ее в нескольких целях.
CREATE TABLE num (i int);
INSERT INTO num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
SELECT n.id
FROM
(SELECT n1.i + n10.i*10 AS id
FROM num AS n1 CROSS JOIN num AS n10
WHERE n1.i + n10.i*10 IN (2, 3, 4, 5, 6, 7)) AS n
LEFT OUTER JOIN foos USING (id)
WHERE foos.id IS NULL;
я показываю внутренние генерирующиеся значения запроса от 0.. 99 даже при том, что это не необходимо для этого случая. Но у Вас могли бы быть значения, больше, чем 10 в Вашем списке. Дело в том, что с одной таблицей num
, можно генерировать большие количества, не имея необходимость обращаться к очень длинным цепочкам с одной UNION
на значение. Кроме того, можно определить список требуемых значений в одном месте, которое более удобно и читаемо.
Я не могу найти решение Вашей точной проблемы, которая не использует временную таблицу, но альтернативный способ сделать Ваш запрос с помощью подвыбора вместо соединения:
SELECT bars.* FROM bars WHERE bars.ID NOT IN (SELECT ID FROM foos)
Как другие плакаты я первоначально записал:
SELECT * FROM foos WHERE foos.ID NOT IN (2, 4, 5, 6, 7)
, но тогда я понял, что это производит напротив того, что Вы хотите.
Alnitak (и Ваш) решение должно работать, и я не могу вещь ни о чем больше, что может работать только на языке SQL.
, Но здесь прибывает вопрос - как Вы передаете список значений? Не он лучше, чтобы обработать это в коде вызова - т.е. запросить идентификатор и сравнить его в коде стрижки, который может быть на языке, которому лучше удовлетворяют для этого вида манипуляций.
У меня была аналогичная проблема. У меня был диапазон, в котором автоматически увеличивающийся первичный ключ имел некоторые пропущенные значения, поэтому сначала я выяснил, сколько их было:
select count (*) from node where nid> 1962
. {{ 1}} Сравнивая это число с наибольшим значением, я обнаружил, что число отсутствует. Затем я выполнил этот запрос:
выберите n2.nid из узла n1, правый узел соединения n2 на n1.nid = (n2.nid - 1), где n1.nid имеет значение null, а n2.nid> 1962
Будет найдено количество пропущенных записей, не следующих подряд. Он не будет показывать последовательные, и я не совсем уверен, как это сделать, кроме изменения предложения ON, чтобы обеспечить большую широту (что значительно увеличило бы таблицу JOIN).
В любом случае это дал мне пять результатов из семи отсутствующих, а два других гарантированно были рядом по крайней мере с одним из пяти. Если вам не хватает большего числа, вам, вероятно, понадобится другой способ найти пропавшее.