Что означает значение null

Заметка про NULL

Основные положения

Для удобства сделаем процедуру, печатающую состояние булевого параметра:

и включим опцию печати сообщений на консоль:

Привычные операторы сравнения пасуют перед NULLом:

Сравнение с NULLом

Соответственно, IS NOT NULL действует наоборот: вернёт истину, если значение операнда отлично от NULLа и ложь, если он является NULLом:

DECODE идёт против системы:

Пример с составными индексами находится в параграфе про индексы.

Логические операции и NULL

В большинстве случаев неизвестный результат обрабатывается как ЛОЖЬ :

Отрицание неизвестности даёт неизвестность:

Операторы IN и NOT IN

Для начала сделаем несколько предварительных действий. Для тестов создадим таблицу T с одним числовым столбцом A и четырьмя строками: 1, 2, 3 и NULL

Включим трассировку запроса (для этого надо обладать ролью PLUSTRACE ).
В листингах от трассировки оставлена только часть filter, чтобы показать, во что разворачиваются указанные в запросе условия.

Предварительные действия закончены, давайте теперь поработаем с операторами. Попробуем выбрать все записи, которые входят в набор (1, 2, NULL) :

Попробуем теперь с NOT IN :

Вообще ни одной записи! Давайте разберёмся, почему тройка не попала в результаты запроса. Посчитаем вручную фильтр, который применила СУБД, для случая A=3 :

Из-за особенностей трёхзначной логики NOT IN вообще не дружит с NULLами: как только NULL попал в условия отбора, данных не ждите.

NULL и пустая строка

Здесь Oracle отходит от стандарта ANSI SQL и провозглашает эквивалентность NULLа и пустой строки. Это, пожалуй, одна из наиболее спорных фич, которая время от времени рождает многостраничные обсуждения с переходом на личности, поливанием друг друга фекалиями и прочими непременными атрибутами жёстких споров. Судя по документации, Oracle и сам бы не прочь изменить эту ситуацию (там сказано, что хоть сейчас пустая строка и обрабатывается как NULL, в будущих релизах это может измениться), но на сегодняшний день под эту СУБД написано такое колоссальное количество кода, что взять и поменять поведение системы вряд ли реально. Тем более, говорить об этом они начали как минимум с седьмой версии СУБД (1992-1996 годы), а сейчас уже двенадцатая на подходе.

NULL и пустая строка эквивалентны:

непременный атрибут жёсткого спора:

Длина пустой строки не определена:

Сравнение с пустой строкой невозможно:

Критики подхода, предлагаемого Ораклом, говорят о том, что пустая строка не обязательно обозначает неизвестность. Например, менеджер по продажам заполняет карточку клиента. Он может указать его контактный телефон (555-123456), может указать, что он неизвестен (NULL), а может и указать, что контактный телефон отсутствует (пустая строка). С оракловым способом хранения пустых строк реализовать последний вариант будет проблемно. С точки зрения семантики довод правильный, но у меня на него всегда возникает вопрос, полного ответа на который я так и не получил: как менеджер введёт в поле «телефон» пустую строку и как он в дальнейшем отличит его от NULLа? Варианты, конечно, есть, но всё-таки…

Вообще-то, если говорить про PL/SQL, то где-то глубоко внутри его движка пустая строка и NULL различаются. Один из способов увидеть это связан с тем, что ассоциативные коллекции позволяют сохранить элемент с индексом » (пустая строка), но не позволяют сохранить элемент с индексом NULL:

Использовать такие финты ушами на практике не стоит. Во избежание проблем лучше усвоить правило из доки: пустая строка и NULL в оракле неразличимы.

Математика NULLа

Этот маленький абзац писался пятничным вечером под пиво, на фоне пятничного РЕН-ТВшного фильма. Переписывать его лень, уж извините.

Очевидно, что мы ничем не сможем помочь Коле: неизвестное количество любовников Маши до замужества сводит все расчёты к одному значению — неизвестно. Oracle, хоть и назвался оракулом, в этом вопросе уходит не дальше, чем участники битвы экстрасенсов: он даёт очевидные ответы только на очевидные вопросы. Хотя, надо признать, что Oracle гораздо честнее: в случае с Колей он не будет заниматься психоанализом и сразу скажет: «я не знаю»:

С конкатенацией дела обстоят по другому: вы можете добавить NULL к строке и это её не изменит. Такая вот политика двойных стандартов.

NULL и агрегатные функции

Таблица с данными. Используется ниже много раз:

Пустые значения игнорируются агрегатами:

Набор данных только из NULLов:

Пустой набор данных:

NULL в OLAP

Удобная фишка sqlplus: при выводе данных заменяет NULL на указанную строку:

Проверяем дуализм NULLа в многомерном кубе:

Источник

Null, великий и ужасный

Именно так и никак иначе: null в C# — однозначно ошибочное решение, бездумно скопированное из более ранних языков.

Этот ящик Пандоры был открыт еще при создании языка ALGOL W великим Хоаром, который позднее назвал собственную идею ошибкой на миллиард долларов.

Лучшая историческая альтернатива

Разумеется, она была, причем очевидная по современным меркам

Самое трагичное, что все это не было откровением и даже новинкой уже к моменту проектирования первой версии языка. Увы, тогда матерых функциональщиков в команде Хейлсберга не было.

Лекарства для текущей реальности

Хотя прогноз очень серьезный, летального исхода можно избежать за счет применения различных практик и инструментов. Способы и их особенности пронумерованы для удобства ссылок.

Явные проверки на null в операторе if. Очень прямолинейный способ с массой серьезных недостатков.

Атрибут NotNull. Немного упрощает использование явных проверок

Паттерн проектирования Null object. Очень хороший способ, но с ограниченной сферой применения.

Конвенция о возврате живых объектов по умолчанию. Очень просто и эффективно.

Любой метод или свойство, для которых явно не заявлена возможность возвращать null, должны всегда предоставлять полноценный объект. Для поддержания достаточно выработки хорошей привычки, например, посредством ревью кода.

Конвенция о стандартных способах явно указать что свойство или метод может вернуть null: например, префикс Try или суффикс OrDefault в имени метода. Органичное дополнение к возврату полноценных объектов по умолчанию. Достоинства и недостатки те же.

Атрибут CanBeNull. Добрый антипод-близнец атрибута NotNull.

Операторы C# (тернарный, Элвиса, coalesce)

Тип Optional. Позволяет явно поддержать отсутствие объекта.

Монада Maybe. LINQ для удобной обработки случаев как наличия, так и отсутствия объекта.

Пакет Fody/NullGuard. Автоматические проверки на null на стероидах.

Ссылочные типы без возможности присвоения null (если добавят в одну из будущих версий C#)

Итоги

Буду краток — все выводы в таблице:

Настоятельная рекомендацияАнтипаттернНа ваш вкус и потребности
4, 5, 7, 11, 12 (когда и если будет реализовано)1, 23, 6, 8, 9, 10

На предвосхищение ООП через 20 лет не претендую, но дополнениям и критике буду очень рад.

Обновление

добавил примеры кода к утопической альтернативе.

Источник

Оригинал статьи этой статьи впервые был опубликован в блоге автора @KevinMarquette. Группа разработчиков PowerShell благодарит Кевина за то, что он поделился с нами этими материалами. Читайте его блог — PowerShellExplained.com.

Что означает NULL

Значение NULL можно считать неизвестным или пустым значением. Переменная имеет значение NULL, пока ей не присвоено значение или объект. Это важный момент, так как некоторые команды требуют значения и возвращают ошибку, если значением является NULL.

$null в PowerShell

$null — это автоматическая переменная в PowerShell, используемая для представления значения NULL. Ее можно назначать переменным и использовать в сравнениях, а также в качестве заполнителя для значения NULL в коллекции.

В строках

Это одна из причин, по которой я предпочитаю заключать переменные в скобки при их использовании в сообщениях журнала. Если значение находится в конце строки, это также помогает обнаружить границы значений переменных.

В числовом уравнении

Вместо коллекции

Вместо объекта

Метод в выражении со значением NULL

Взгляните на следующий пример и постарайтесь предсказать результаты:

PSScriptAnalyzer и VSCode

Поскольку VS Code также использует правила PSScriptAnalyser, в редакторе такие фрагменты кода выделяются и считаются проблемой.

Простая проверка if

Но это еще не все. На самом деле строка значит следующее:

Ниже приведен более полный пример этой инструкции.

Несколько дней назад я столкнулся с этой проблемой при рефакторинге кода. В нем присутствовала базовая проверка такого типа.

$null.Count

[PSCustomObject] Count

Выполнение этого примера в Windows PowerShell 5.1 и PowerShell 6.0 дает разные результаты.

Пустое значение NULL

Pipeline

foreach

Оператор foreach начал так работать с версии PowerShell 3.0. Если у вас предыдущая версия, такой режим работы в ней не поддерживается. Это одно из важных отличий, которое необходимо учитывать при обратном портировании кода для совместимости с версией 2.0.

Типы значений

Параметры функции

Общепринято использовать строго типизированные значения в параметрах функций. Обычно мы стараемся определять типы параметров, даже если не собираемся определять типы других переменных в скриптах. Возможно, вы сами строго типизировали переменные в функциях, даже не осознавая этого.

IsNotNullOrEmpty

Я часто так делаю, когда знаю, что тип значения должен быть строкой.

Сценарий без результатов

У меня выработалась привычка инициализировать все переменные перед их использованием. В других языках это обязательно. В начале функции или цикла foreach я определяю все используемые значения.

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

Проблемы с областью действия

Если взять тот же пример Do-something и удалить из него цикл, то код будет таким:

Out-Null

Сводка

Источник

Обработка значений NULL

Значения NULL и логика трех значений

Разрешение значений NULL в определениях столбцов вводит в приложение логику трех значений. Результатом сравнения может быть одно из трех условий:

Так как значение NULL считается неизвестным, два значения NULL, сравниваемые друг с другом, не считаются равными. В выражениях, использующих арифметические операторы, если какой-либо из операндов имеет значение NULL, результат также равен NULL.

Значения NULL и SqlBoolean

При сравнении между любыми типами System.Data.SqlTypes будет возвращаться значение SqlBoolean. Функция IsNull для каждого типа SqlType возвращает SqlBoolean и может использоваться для проверки на наличие значений NULL. В следующих таблицах истинности показано, как работают операторы AND, OR и NOT при наличии значения NULL. (T = true, F = false и U = неизвестно или NULL.)

Что означает значение null. Смотреть фото Что означает значение null. Смотреть картинку Что означает значение null. Картинка про Что означает значение null. Фото Что означает значение null

Основные сведения о параметре ANSI_NULLS

Стандарт ANSI SQL-92 не поддерживает columnName = NULL в предложении WHERE. В SQL Server параметр ANSI_NULLS управляет допустимостью значений NULL по умолчанию в базе данных и вычислением сравнений со значениями NULL. Если параметр ANSI_NULLS включен (по умолчанию), то при проверке на наличие значений NULL в выражениях должен использоваться оператор IS NULL. Например, результатом следующего сравнения всегда является неизвестность при включенном параметре ANSI_NULLS:

Сравнение с переменной, содержащей значение NULL, также приводит к неизвестному результату:

Для тестирования на значение NULL используются предикаты IS NULL и IS NOT NULL. Это может усложнить предложение WHERE. Например, столбец TerritoryID в таблице AdventureWorks Customer допускает значения NULL. Если инструкция SELECT используется для тестирования на значения NULL в дополнение к другим, она должна включать предикат IS NULL:

Если в SQL Server параметр ANSI_NULLS отключен, можно создать выражения, которые используют оператор равенства для сравнения со значением NULL. Однако нельзя запретить другим подключениям задавать параметры NULL для этого подключения. Использование параметра IS NULL для проверки на наличие значений NULL всегда работает, независимо от установленного значения ANSI_NULLS для подключения.

Присвоение значений NULL

Значения NULL являются специальными, и их семантика хранения и назначения различается в разных системах типов и системах хранения. Dataset предназначен для использования с различными системами типов и хранения.

В этом разделе описывается семантика значений NULL для присвоения значений NULL для DataColumn в DataRow в различных системах типов.

Назначение нескольких столбцов (строк)

Кроме того, следующие правила применяются к экземпляру назначений NULL DataRow.[«columnName»] :

Используемое по умолчанию значение default является DbNull.Value для всех столбцов, за исключением строго типизированных нулевых столбцов с допустимыми строго типизированными значениями NULL.

Значения NULL никогда не записываются во время сериализации в XML-файлы (как в xsi:nil).

Все значения, в том числе по умолчанию, отличные от NULL, всегда записываются при сериализации в XML. Это отличается от семантики XSD/XML, где значение NULL (xsi: nil) является явным, а значение по умолчанию — неявным (если отсутствует в XML, то проверяющее средство синтаксического анализа может получить его из связанной схемы XSD). Обратное верно для DataTable : значение NULL является неявным, а значение по умолчанию — явным.

Всем отсутствующим значениям столбцов для строк, считываемых из входных данных XML, присваивается значение NULL. Строкам, созданным с помощью NewRow или аналогичных методов, присваивается значение по умолчанию DataColumn.

Присвоение значений NULL для SqlTypes

Значение по умолчанию для любого экземпляра System.Data.SqlTypes— NULL.

Значения NULL могут быть назначены DataColumn, как показано в следующем примере кода. Вы можете напрямую назначить значения NULL для переменных SqlTypes без запуска исключения.

Пример

В следующем примере кода показано создание DataTable с двумя столбцами, определенными как SqlInt32 и SqlString. Код добавляет одну строку известных значений, одну строку значений NULL, а затем выполняет итерацию по DataTable, присваивая значения переменным и отображая выходные данные в окне консоли.

В этом примере отображаются следующие результаты:

Источник

Что вы должны знать о значениях NULL

Понимать использование пустых значений, чтобы избежать проблем с базой данных

Пользователи, плохо знакомые с миром баз данных, часто путаются с особым значением, относящимся к полю – значением NULL. Это значение можно найти в поле, содержащем данные любого типа, и имеет особое значение в контексте реляционной базы данных. Вероятно, лучше начать обсуждение NULL с нескольких слов о том, что такое NULL не :

Скорее, NULL – это значение, используемое для представления неизвестного фрагмента данных. Часто программисты баз данных используют фразу «значение NULL», но это неверно. Помните: NULL – это неизвестное значение, в котором поле выглядит пустым.

NULL в реальном мире

Давайте рассмотрим простой пример: стол с инвентарём для фруктовой лавки. Предположим, что наш инвентарь содержит 10 яблок и три апельсина. Мы также храним сливы, но информация о наших запасах неполная, и мы не знаем, сколько (если таковые имеются) слив есть в наличии. Используя значение NULL, мы получим таблицу инвентаризации, показанную в таблице ниже.

Инвентарь фруктовых лавок

InventoryID Item Количество
1Яблоки10
2Апельсины3
3СливыNULL

Было бы неправильно указывать количество 0 для записи слив, потому что это означало бы, что в инвентаре нет слив. Напротив, у нас может быть немного слив, но мы просто не уверены.

NULL или НЕ NULL?

Таблица может быть спроектирована для разрешения значений NULL или нет. Вот пример SQL, который создает таблицу инвентаризации, которая допускает некоторые значения NULL:

Хотя допустимое значение NULL вполне приемлемо, значения NULL могут вызвать проблемы, поскольку любое сравнение значений, в которых значение равно NULL, всегда приводит к NULL.

Чтобы проверить, содержит ли ваша таблица значения NULL, используйте оператор IS NULL или IS NOT NULL. Вот пример IS NULL:

Учитывая наш пример здесь, это вернет:

InventoryID
Вещь
Количество

3Сливы

Работает на NULL

Работа со значениями NULL часто приводит к результатам NULL, в зависимости от операции SQL. Например, предполагая, что A НЕДЕЙСТВИТЕЛЕН:

Арифметические операторы

Операторы сравнения

Это всего лишь несколько примеров операторов, которые всегда возвращают NULL, если один из операндов равен NULL. Существуют гораздо более сложные запросы, и все они усложняются значениями NULL. Главная идея заключается в том, что, если вы разрешите значения NULL в своей базе данных, поймите последствия и спланируйте их.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *