Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:
null
. null
. null
, как если бы это был массив. null
, как если бы это был массив. null
как будто это было значение Throwable. Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null
.
Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html
"Издержки" с курсорами являются просто частью API. Курсоры - то, как части RDBMS работают под капотом. Часто CREATE TABLE
и INSERT
имеют SELECT
операторы, и реализация является очевидной внутренней реализацией курсора.
Используя высокоуровневые "основанные на наборе операторы" связывает результаты курсора в единственный набор результатов, означая меньше API назад и вперед.
Курсоры предшествуют современным языкам, которые обеспечивают первоклассные наборы. Старый C, КОБОЛ, Фортран, и т.д., должен был обработать строки по одному, потому что не было никакого понятия "набора", который мог использоваться широко. Java, C#, Python, и т.д., имеет первоклассные структуры списка для содержания наборов результатов.
Медленный Выпуск
В некоторых кругах, реляционные соединения являются тайной, и люди запишут вложенные курсоры, а не простое соединение. Я рассматривал действительно эпические операции вложенного цикла, выписанные как партии и много курсоров. Нанесение поражения оптимизации RDBMS. И выполнение действительно медленно.
Простой SQL переписывает для замены вложенных циклов курсора соединениями, и единственный, плоский цикл курсора может сделать программы выполненными в 100-м время. [Они думали, что я был богом оптимизации. Все, что я сделал, было заменить вложенные циклы соединениями. Все еще используемые курсоры.]
Этот беспорядок часто приводит к обвинительному акту курсоров. Однако это не курсор, это - неправильное употребление курсора, это - проблема.
Выпуск
Размера Для действительно эпических наборов результатов (т.е. дамп таблицы в файл), курсоры важны. Основанные на наборе операции не могут осуществить действительно большие наборы результатов как единственный набор в памяти.
Альтернативы
я пытаюсь использовать уровень ORM как можно больше. Но это имеет две цели. Во-первых, курсорами управляет компонент ORM. Во-вторых, SQL разделяется от приложения в конфигурационный файл. Не то, чтобы курсоры плохи. Это - то кодирование всех, что они открывают, закрывают и выбирают, не значение - добавляет программирование.
Курсоры заставляют людей чрезмерно применить процедурное мышление к основанной на наборе среде.
И они МЕДЛЕННЫЕ !!!
От SQLTeam:
Обратите внимание на то, что курсоры являются САМЫМ МЕДЛЕННЫМ способом получить доступ к данным в SQL Server. Должен только использоваться, когда действительно необходимо получить доступ к одной строке за один раз. Единственная причина, о которой я могу думать для этого, состоит в том, чтобы назвать хранимую процедуру на каждой строке. В статья Cursor Performance я обнаружил, что курсоры более чем в тридцать раз медленнее, чем основанные на наборе альтернативы .
Существует ответ, выше которого говорит, что "курсоры являются САМЫМ МЕДЛЕННЫМ способом получить доступ к данным в SQL Server... курсоры более чем в тридцать раз медленнее, чем основанные на наборе альтернативы".
Этот оператор может быть верным при многих обстоятельствах, но как общий оператор это проблематично. Например, я хорошо использовал курсоры в ситуациях, где я хочу выполнить обновление или удалить операцию, влияющую на многие строки большой таблицы, которая получает постоянные производственные чтения. Выполнение хранимой процедуры, которая делает эти обновления, одна строка за один раз заканчивает тем, что была быстрее, чем основанные на наборе операции, потому что основанные на наборе операционные конфликты с операцией чтения и заканчивают тем, что вызвали ужасающие проблемы блокировки (и может уничтожить производственную систему полностью, в крайних случаях).
В отсутствие другого действия базы данных, основанные на наборе операции универсально быстрее. В производственных системах это зависит.
Оптимизатор часто не может использовать алгебру отношений для преобразования проблемы, когда метод курсора используется. Часто курсор является отличным способом решить проблему, но SQL является декларативным языком, и существует большая информация в базе данных, от ограничений, к статистике и индексам, которые означают, что оптимизатор имеет много опций решить проблему, тогда как курсор в значительной степени явно направляет решение.
Курсоры имеют тенденцию использоваться путем начала разработчиков SQL в местах, где основанные на наборе операции были бы лучше. Особенно то, когда люди изучают SQL после изучения, что традиционный язык программирования, "выполняют итерации по этим записям" менталитета, имеет тенденцию приводить людей использовать курсоры неуместно.
самые серьезные книги SQL включают главу, предписывающую использование курсоров; правильно написанные проясняют, что курсоры имеют свое место, но не должны использоваться для основанных на наборе операций.
существуют, очевидно, ситуации, где курсоры являются верным выбором или по крайней мере верным выбором.
В целом, потому что на реляционной базе данных, производительность кода с помощью курсоров является порядком величины, хуже, чем основанные на наборе операции.
В Oracle МН курсоры / курсоры SQL не приведут к блокировкам таблицы, и возможно использовать bulk-collecting/bulk-fetching.
В Oracle 10 часто используемый неявный курсор
for x in (select ....) loop
--do something
end loop;
выбирает неявно 100 строк за один раз. Явный bulk-collecting/bulk-fetching также возможен.
Однако МН курсоры / курсоры SQL являются чем-то вроде последнего средства, используют их, когда Вы не можете решить проблему с основанным на наборе SQL.
Другой причиной является распараллеливание, для базы данных легче параллелизировать большие основанные на наборе операторы, чем код императива строки строкой. Это - та же причина, почему функциональное программирование становится все более популярным (Haskell, F#, Lisp, C# LINQ, MapReduce...), функциональное программирование делает распараллеливание легче. Центральные процессоры числа на компьютер повышаются так, распараллеливание становится все больше проблемой.
Ответы выше не подчеркнули достаточно важность блокировки. Я не большой поклонник курсоров, потому что они часто приводят к блокировкам уровня таблицы.
Я соглашаюсь со статьей на этой странице:
http://weblogs.sqlteam.com/jeffs/archive/2008/06/05/sql-server-cursor-removal.aspx
Вы, возможно, вероятно, завершили свой вопрос после второго абзаца, вместо того, чтобы назвать людей "безумными" просто, потому что у них есть другая точка зрения, чем Вы делаете и иначе пытающийся дразнить профессионалов, у которых может быть очень серьезное основание для чувства способа, которым они делают.
относительно Вашего вопроса, в то время как существуют, конечно, ситуации, где курсор может требоваться, по моему опыту, разработчики решают, что курсором "должен" быть используемый FAR чаще, чем на самом деле имеет место. Шанс кого-то допускающего ошибку на стороне слишком большого использования курсоров по сравнению с не использованием их, когда они должны, НАМНОГО выше, по-моему.
Если это имеет значение я считал, что "тот" устанавливает курсор, будет работать, его основанный на наборе дубликат находится в рабочем общем количестве. По маленькой таблице скорость подведения итогов строки по порядку столбцами одобряют основанную на наборе операцию, но как увеличения таблицы размера строки курсор станет быстрее, потому что это может просто нести рабочее итоговое значение к следующей передаче цикла. Теперь , где необходимо сделать, рабочее общее количество является другим аргументом...
Можно ли отправить тот пример курсора или ссылку на вопрос? Существует, вероятно, еще лучший путь, чем рекурсивный CTE.
В дополнение к другим комментариям, курсоры при неподходящем использовании (который часто является) вызывают ненужную страницу/блокировки строки.
в основном 2 блока кода, которые делают то же самое. возможно, это - немного странный пример, но это подтверждает точку зрения. SQL Server 2005:
SELECT * INTO #temp FROM master..spt_values
DECLARE @startTime DATETIME
BEGIN TRAN
SELECT @startTime = GETDATE()
UPDATE #temp
SET number = 0
select DATEDIFF(ms, @startTime, GETDATE())
ROLLBACK
BEGIN TRAN
DECLARE @name VARCHAR
DECLARE tempCursor CURSOR
FOR SELECT name FROM #temp
OPEN tempCursor
FETCH NEXT FROM tempCursor
INTO @name
SELECT @startTime = GETDATE()
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE #temp SET number = 0 WHERE NAME = @name
FETCH NEXT FROM tempCursor
INTO @name
END
select DATEDIFF(ms, @startTime, GETDATE())
CLOSE tempCursor
DEALLOCATE tempCursor
ROLLBACK
DROP TABLE #temp
единственное обновление берет 156 мс, в то время как курсор берет 2 016 мс.
Помимо проблем с производительностью (не), я думаю, что самый большой недостаток курсоров состоит в том, что их сложно отлаживать. Особенно по сравнению с кодом в большинстве клиентских приложений, где отладка имеет тенденцию быть сравнительно простой, а языковые функции гораздо проще. Фактически, я утверждаю, что почти все, что человек делает в SQL с курсором, вероятно, должно происходить в первую очередь в клиентском приложении.