Добавить пустые строки oracle
Коллекции присутствую в том или ином виде в большинстве языков программирования и везде имеют схожую суть в плане использования. А именно – позволяют хранить набор объектов одного типа и проводить над всем набором какие-либо действия, либо в цикле проводить однотипные действия со всеми элементами набора.
Таким же образом коллекции используются и в Oracle.
Содержание статьи
Общие сведения о коллекциях в pl/sql
-
Создание коллекции происходит в два этапа
Сначала мы объявляем тип(type) коллекции (конструкции assoc_array_type_def, varray_type_def и nested_table_type_def будут приведены далее)
Типы коллекций
Тип коллекции | Количество элементов | Тип индекса | Плотная или разреженная | Без инициализации | Где объявляется | Использование в SQL |
---|---|---|---|---|---|---|
Ассоциативный массив (index by table) | Не задано | String Pls_integer | Плотная и разреженная | Empty | PL/SQL block Package | Нет |
Varray (variable-size array) | Задано | Integer | Только плотная | Null | PL/SQL block Package Schema level | Только определенные на уровне схемы |
Nested table | Не задано | Integer | При создании плотная, может стать разреженной | Null | PL/SQL block Package Schema level | Только определенные на уровне схемы |
Плотность коллекции означает, что между элементами коллекции нет пропусков, пустых мест. Некоторые коллекции, как видно из таблицы, могут быть разреженными – т.е. могут иметь разрывы между элементами. Это значит, что в коллекции, например, могут быть элементы с индексом 1 и 4, а с индексом 2 и 3 элементов нет. При этом слоты памяти под 2-й и 3-й элементы будут существовать и будут принадлежать коллекции (в случае nested table), но не содержать при этом объектов и попытка прочитать содержимое этих элементов вызовет ошибку no_data_found.
Подробности можно узнать из видео-лекции в конце статьи.
Ассоциативный массив
- Набор пар ключ-значение
- Данные хранятся в отсортированном по ключу порядке
- Не поддерживает DML-операции (не может участвовать в селектах, не может храниться в таблицах)
- При объявлении как константа должен быть сразу инициализирован функцией
- Порядок элементов в ассоциативном массиве с строковым индексом зависит от параметров NLS_SORT и NLS_COMP
- Нельзя объявить тип на уровне схемы, но можно в пакете
- Не имеет конструктора
- Индекс не может принимать значение null (но допускает пустую строку — подробности и ссылка на пример в первом комментарии)
- Datatype – это любой тип данных, кроме ref cursor
- Для помещения в память небольших таблиц-справочников
- Для передачи в качестве параметра коллекции
Restrictions:
При изменении параметров NLS_SORT и NLS_COMP во время сессии после заполнения ассоциативного массива, можем получать неожиданные результаты вызовов методов first, last, next, previous. Также могут возникнуть проблемы при передаче ассоциативного массива в качестве параметра на другую БД с иными настройками NLS_SORT и NLS_COMP
Varray
Представляет собой массив последовательно хранящихся элементов
Тип описывается следующим образом (varay_type_def):
- Размер задается при создании
- Индексируется с 1
- Инициализируется конструктором
- Если параметры в конструктор не передаются, возвращается пустая коллекция
- Datatype – это любой тип данных, кроме ref cursor
- Знаем максимально возможное количество элементов
- Доступ к элементам последовательный
Restrictions:
Максимальный размер – 2 147 483 647 элементов
Nested table
Тип описывается следующим образом (nested_table_type_def):
- Размер коллекции изменяется динамически
- Может быть в разряженном состоянии, как показано на картинке
- Инициализируется конструктором
- Если параметры в конструктор не передаются, возвращается пустая коллекция
- Datatype – это любой тип данных, кроме ref cursor
- Если содержит только одно скалярное значение, то имя колонки – Column_Value
Set operations с nested tables
Операции возможны только с коллекциями nested table. Обе коллекции, участвующие в операции, должны быть одного типа.
Результатом операции также является коллекция nested table.
Операция | Описание |
---|---|
MULTISET UNION | Возвращает объединение двух коллекций |
MULTISET UNION DISTINCT | Возвращает объединение двух коллекций с дистинктом (убирает дубли) |
MULTISET INTERSECT | Возвращает пересечение двух коллекций |
MULTISET INTERSECT DISTINCT | Возвращает пересечение двух коллекций с дистинктом (убирает дубли) |
SET | Возвращает коллекцию с дистинктом (т.е. коллекцию без дублей) |
MULTISET EXCEPT | Возвращает разницу двух коллекций |
MULTISET EXCEPT DISTINCT | Возвращает разницу двух коллекций с дистинктом (убирает дубли) |
Небольшой пример (обратите внимание на результат операции MULTISET EXCEPT DISTINCT)
Мне нужно написать компонент, который воссоздает таблицы SQL Server (структуру и данные) в базе данных Oracle. Этот компонент также должен принимать новые данные, введенные в базу данных Oracle, и копировать их обратно в SQL Server.
Преобразование типов данных из SQL Server в Oracle не проблема. Однако критическая разница между Oracle и SQL Server вызывает большую головную боль. SQL Server считает, что пустая строка ("") отличается от значения NULL , поэтому столбец char может быть определен как NOT NULL и при этом по-прежнему содержать пустые строки в данных.
Oracle считает, что пустая строка совпадает со значением NULL , поэтому, если столбец char определен как NOT NULL , вы не можете вставить пустую строку. Это приводит к тому, что мой компонент ломается всякий раз, когда столбец символов NOT NULL содержит пустую строку в исходных данных SQL Server.
До сих пор мое решение заключалось в том, чтобы не использовать NOT NULL ни в одном из моих определений зеркальных таблиц Oracle, но мне нужно более надежное решение. Это должно быть кодовое решение, поэтому ответ не может быть «используйте такой-то продукт SQL2Oracle».
Как бы вы решили эту проблему?
Обновлено: вот единственное решение, которое я придумал до сих пор, и оно может помочь проиллюстрировать проблему. Поскольку Oracle не допускает "" в столбце NOT NULL, мой компонент может перехватить любое такое значение, поступающее от SQL Server, и заменить его на "@" (только для примера).
Когда я добавляю новую запись в свою таблицу Oracle, мой код должен писать «@», если я действительно хочу вставить «», и когда мой код копирует новую строку обратно в SQL Server, он должен перехватить «@» и вместо этого напишите "".
Я надеюсь, что есть более элегантный способ.
Изменить 2: возможно ли, что есть более простое решение, например, какой-то параметр в Oracle, который заставляет его обрабатывать пустые строки так же, как и все другие основные базы данных? И будет ли этот параметр также доступен в Oracle Lite?
Что касается вашего Edit 2: существует ужасное решение, связанное с использованием CLOB для всех этих столбцов. Oracle различает NULL и пустой CLOB. Вы можете сохранить CLOB в таблице, чтобы снизить влияние на производительность. Я бы не стал этого делать (см. Мой ответ ниже).
@WW .: Вы совершенно правы - это ужасное решение.
Святая корова. В SQL Server есть своя доля глупости, но это полная чушь. (Это все еще с Oracle 2014+ и добавлен ли для него параметр «ANSI NULL»? У SQL Server были некоторые проблемы, подобные этой обработке до «ANSI NULL».)
@SimonMourier Весело, что они говорят вам относиться к ним по-другому, но не могут предоставить инструменты для этого разумным способом . и теперь им, вероятно, будет трудно изменить это из-за обратной совместимости, поскольку много dbs используют хаки для решения этой проблемы, которая, вероятно, сломается, когда она будет исправлена .
Я пытаюсь вставить пустую строку в столбец, не допускающий значения NULL, в Oracle, но мне это не удается. Вот такой случай:
Что я делаю неправильно?
Да, это все еще действует в Oracle 12c, как и в Oracle 9i (другой вопрос).
В чем смысл ограничения not null на название торговой марки, если вы просто собираетесь ввести не-значение? Было ли это намерением разработчика схемы, что, хотя вы должны указать имя, ничего страшного, если это будет '' ? Похоже, что до сих пор не вводится название торговой марки. (Это помимо того, что Oracle не имеет '' в качестве отдельного значения, как уже упоминалось в ответах ниже.)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно.
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей.
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то.
Ответы 2
Oracle обрабатывает пустые строки как NULL. Это ошибка. Запишите это и надейтесь, что он никогда не укусит вас в задницу в процессе производства.
Ошибка настоящий заключается в том, что всегда не обрабатывает пустые строки как нулевые. 'foo'||'' возвращает 'foo' . Но еще больше сбивает с толку то, что 'foo'||null также возвращает 'foo'
@a_horse_with_no_name - но что является все еще обрабатывает пустую строку так же, как и null? Путаница в том, что оператор конкатенации не возвращает null в обоих случаях, как я думаю, как можно было ожидать от поведения других вещей. (Раньше я не замечал, что в документации говорится, что однажды это может измениться . это та же шкала времени, что и переопределение varchar ?)
@AlexPoole: тогда оператор конкатенации не работает в соответствии со стандартом SQL. Потому что каждое выражение с участием null должно давать null , как в 42 * null .
@a_horse_with_no_name Я перешел из Oracle на SQL Server до того, как в Oracle появился синтаксис ANSI. Я был безнадежно сбит с толку тем, что объединение нуля со строкой в SQL Server привело к нулю [ухмылка]. Прямо противоположно твоему опыту. Это были 15 минут отладки, я бы хотел вернуться :-)
Причина в том, как объяснил @Captain Kenpachi. Если вы хотите сравнить две строки (или другие одинаковые типы) и хотите быть терпимыми к NULL (или пустой строке в Oracle, поскольку он обрабатывает ее как одно и то же), вам необходимо задействовать тест IS.
Вы можете попробовать распространенный обман, заключающийся в использовании мошеннического значения, которое никогда не будет использоваться, но закон Мерфи гласит, что однажды кто-нибудь это сделает. Этот метод также имеет недостаток, заключающийся в том, что мошенническое значение должно соответствовать типу объекта, который вы сравниваете, то есть сравнивая строки, в которых вам нужна мошенническая строка, при сравнении дат, когда вам нужна красная дата. Это также означает, что вы не можете обильно вырезать и вставлять его, не задумываясь. Пример: WHERE NVL(col1,'MyRougeValue')=NVL(col2,'MyRougeValue')
Стандартная версия - это явная проверка на NULL. WHERE (col1=col2 OR (col1 IS NULL AND col2 IS NULL))
Противоположное становится WHERE NOT(col1=col2 OR (col1 IS NULL AND col2 IS NULL))
Я видел длинную противоположную версию (как видно в инструменте сравнения данных Toad) WHERE (col1<>col2 OR (col1 IS NULL AND col2 IS NOT NULL) OR (col1 IS NOT NULL AND col2 IS NULL))
У Oracle есть удобная функция DECODE , которая по сути является IF a IS b THEN c ELSE d , поэтому равенство - это WHERE DECODE(col1,col2,1,0)=1 , а противоположное - WHERE DECODE(col1,col2,1,0)=0 . Вы можете найти это немного медленнее, чем явный тест IS. Он является проприетарным для Oracle, но помогает решить проблему с пустой строкой.
Спасибо @William Robertson, я исправил. Это был только «косметический» вопрос.
Специальное значение NULL означает отсутствие данных, констатацию того факта, что значение неизвестно. По умолчанию это значение могут принимать столбцы и переменные любых типов, если только на них не наложено ограничение NOT NULL . Также, СУБД автоматически добавляет ограничение NOT NULL к столбцам, включенным в первичный ключ таблицы.
Основная особенность NULLа заключается в том, что он не равен ничему, даже другому NULLу. С ним нельзя сравнить какое-либо значение с помощью любых операторов: = , < , >, like … Даже выражение NULL != NULL не будет истинным, ведь нельзя однозначно сравнить одну неизвестность с другой. Кстати, ложным это выражение тоже не будет, потому что при вычислении условий Oracle не ограничивается состояниями ИСТИНА и ЛОЖЬ . Из-за наличия элемента неопределённости в виде NULLа существует ещё одно состояние — НЕИЗВЕСТНО .
Таким образом, Oracle оперирует не двухзначной, а трёхзначной логикой. Эту особенность заложил в свою реляционную теорию дедушка Кодд, а Oracle, являясь реляционной СУБД, полностью следует его заветам. Чтобы не медитировать над “странными” результатами запросов, разработчику необходимо знать таблицу истинности трёхзначной логики. Ознакомиться с ней можно, например, на английской википедии: Three-valued_logic.
Для удобства сделаем процедуру, печатающую состояние булевого параметра:
Привычные операторы сравнения пасуют перед NULLом:
Существуют специальные операторы IS NULL и IS NOT NULL , которые позволяют производить сравнения с NULLами. IS NULL вернёт истину, если операнд имеет значение NULL и ложь, если он им не является.
Соответственно, IS NOT NULL действует наоборот: вернёт истину, если значение операнда отлично от NULLа и ложь, если он является NULLом:
Кроме того, есть пара исключений из правил, касающихся сравнений с отсутствующими значениями. Во-первых, — это функция DECODE , которая считает два NULLа эквивалентными друг другу. Во-вторых, — это составные индексы: если два ключа содержат пустые поля, но все их непустые поля равны, то Oracle считает эти два ключа эквивалентными.
DECODE идёт против системы:
Пример с составными индексами находится в параграфе про индексы.
Обычно, состояние НЕИЗВЕСТНО обрабатывается так же, как ЛОЖЬ . Например, если вы выбираете строки из таблицы и вычисление условия x = NULL в предложении WHERE дало результат НЕИЗВЕСТНО , то вы не получите ни одной строки. Однако, есть и отличие: если выражение НЕ(ЛОЖЬ) вернёт истину, то НЕ(НЕИЗВЕСТНО) вернёт НЕИЗВЕСТНО . Логические операторы AND и OR также имеют свои особенности при обработке неизвестного состояния. Конкретика в примере ниже.
В большинстве случаев неизвестный результат обрабатывается как ЛОЖЬ :
Отрицание неизвестности даёт неизвестность:
Оператор OR :
Оператор AND :
Для начала сделаем несколько предварительных действий. Для тестов создадим таблицу T с одним числовым столбцом A и четырьмя строками: 1, 2, 3 и NULL
Включим трассировку запроса (для этого надо обладать ролью PLUSTRACE ).
В листингах от трассировки оставлена только часть filter, чтобы показать, во что разворачиваются указанные в запросе условия.
Предварительные действия закончены, давайте теперь поработаем с операторами. Попробуем выбрать все записи, которые входят в набор (1, 2, NULL) :
Как видим, строка с NULLом не выбралась. Произошло это из-за того, что вычисление предиката "A"=TO_NUMBER(NULL) вернуло состояние НЕИЗВЕСТНО . Для того, чтобы включить NULLы в результат запроса, придётся указать это явно:
Попробуем теперь с NOT IN :
Вообще ни одной записи! Давайте разберёмся, почему тройка не попала в результаты запроса. Посчитаем вручную фильтр, который применила СУБД, для случая A=3 :
Из-за особенностей трёхзначной логики NOT IN вообще не дружит с NULLами: как только NULL попал в условия отбора, данных не ждите.
Здесь Oracle отходит от стандарта ANSI SQL и провозглашает эквивалентность NULLа и пустой строки. Это, пожалуй, одна из наиболее спорных фич, которая время от времени рождает многостраничные обсуждения с переходом на личности, поливанием друг друга фекалиями и прочими непременными атрибутами жёстких споров. Судя по документации, Oracle и сам бы не прочь изменить эту ситуацию (там сказано, что хоть сейчас пустая строка и обрабатывается как NULL, в будущих релизах это может измениться), но на сегодняшний день под эту СУБД написано такое колоссальное количество кода, что взять и поменять поведение системы вряд ли реально. Тем более, говорить об этом они начали как минимум с седьмой версии СУБД (1992-1996 годы), а сейчас уже двенадцатая на подходе.
NULL и пустая строка эквивалентны:
непременный атрибут жёсткого спора:
Если последовать завету классика и посмотреть в корень, то причину эквивалентности пуcтой строки и NULLа можно найти в формате хранения varchar`ов и NULLов внутри блоков данных. Oracle хранит строки таблицы в структуре, состоящей из заголовка, за которым следуют столбцы данных. Каждый столбец представлен двумя полями: длина данных в столбце (1 или 3 байта) и, собственно, сами данные. Если varchar2 имеет нулевую длину, то в поле с данными писать нечего, оно не занимает ни байта, а в поле с длиной записывается специальное значение 0xFF , обозначающее отсутствие данных. NULL представлен точно так же: поле с данными отсутствует, а в поле с длиной записывается 0xFF . Разработчики Оракла могли бы, конечно, разделить эти два состояния, но так уж издревле у них повелось.
Лично мне эквивалентность пустой строки и NULLа кажется вполне естественной и логичной. Само название «пустая строка» подразумавает отсутствие значения, пустоту, дырку от бублика. NULL, в общем-то, обозначает то же самое. Но здесь есть неприятное следствие: если про пустую строку можно с уверенностью сказать, что её длина равна нулю, то длина NULLа никак не определена. Поэтому, выражение length('') вернёт вам NULL, а не ноль, как вы, очевидно, ожидали. Ещё одна проблема: нельзя сравнивать с пустой строкой. Выражение val = '' вернёт состояние НЕИЗВЕСТНО , так как, по сути, эквивалентно val = NULL .
Длина пустой строки не определена:
Сравнение с пустой строкой невозможно:
Критики подхода, предлагаемого Ораклом, говорят о том, что пустая строка не обязательно обозначает неизвестность. Например, менеджер по продажам заполняет карточку клиента. Он может указать его контактный телефон (555-123456), может указать, что он неизвестен (NULL), а может и указать, что контактный телефон отсутствует (пустая строка). С оракловым способом хранения пустых строк реализовать последний вариант будет проблемно. С точки зрения семантики довод правильный, но у меня на него всегда возникает вопрос, полного ответа на который я так и не получил: как менеджер введёт в поле «телефон» пустую строку и как он в дальнейшем отличит его от NULLа? Варианты, конечно, есть, но всё-таки…
Вообще-то, если говорить про PL/SQL, то где-то глубоко внутри его движка пустая строка и NULL различаются. Один из способов увидеть это связан с тем, что ассоциативные коллекции позволяют сохранить элемент с индексом '' (пустая строка), но не позволяют сохранить элемент с индексом NULL:
Использовать такие финты ушами на практике не стоит. Во избежание проблем лучше усвоить правило из доки: пустая строка и NULL в оракле неразличимы.
Этот маленький абзац писался пятничным вечером под пиво, на фоне пятничного РЕН-ТВшного фильма. Переписывать его лень, уж извините.
Задача. У Маши до замужества с Колей было неизвестное количество любовников. Коля знает, что после замужества у Маши был секс с ним, Сашей и Витей. Помогите найти Коле точное количество любовников Маши.
Очевидно, что мы ничем не сможем помочь Коле: неизвестное количество любовников Маши до замужества сводит все расчёты к одному значению — неизвестно. Oracle, хоть и назвался оракулом, в этом вопросе уходит не дальше, чем участники битвы экстрасенсов: он даёт очевидные ответы только на очевидные вопросы. Хотя, надо признать, что Oracle гораздо честнее: в случае с Колей он не будет заниматься психоанализом и сразу скажет: «я не знаю»:
С конкатенацией дела обстоят по другому: вы можете добавить NULL к строке и это её не изменит. Такая вот политика двойных стандартов.
Почти все агрегатные функции, за исключением COUNT (и то не всегда), игнорируют пустые значения при расчётах. Если бы они этого не делали, то первый же залетевший NULL привёл бы результат функции к неизвестному значению. Возьмём для примера функцию SUM , которой необходимо просуммировать ряд (1, 3, null, 2) . Если бы она учитывала пустые значения, то мы бы получили такую последовательность действий:
1 + 3 = 4; 4 + null = null; null + 2 = null .
Вряд ли вас устроит такой расчёт при вычислении агрегатов, ведь вы наверняка не это хотели получить. А какой бы был геморрой с построением хранилищ данных… Бррррр…
Таблица с данными. Используется ниже много раз:
Пустые значения игнорируются агрегатами:
Функция подсчёта количества строк COUNT , если используется в виде COUNT(*) или COUNT(константа) , будет учитывать пустые значения. Однако, если она используется в виде COUNT(выражение) , то пустые значения будут игнорироваться.
с константой:
С выражением:
Также, следует быть осторожным с функциями вроде AVG . Поскольку она проигнорирует пустые значения, результат по полю N будет равен (1+3+2)/3 , а не (1+3+2)/4 . Возможно, такой расчёт среднего вам не нужен. Для решения подобных проблем есть стандартное решение — воспользоваться функцией NVL :
Агрегатные функции возвращают состояние НЕИЗВЕСТНО , если они применяются к пустому набору данных, либо если он состоит только из NULLов. Исключение составляют предназначенные для подсчёта количества строк функции REGR_COUNT и COUNT(выражение) . Они в перечисленных выше случаях вернут ноль.
Набор данных только из NULLов:
Пустой набор данных:
Ответы 1
В Oracle пустая строка эквивалентна NULL .
Практически в любой другой базе данных они разные, но именно так Oracle определяет значения NULL для строк (по умолчанию).
Это объясняется в документация вместе с этим заманчивым примечанием:
Note:
Oracle Database currently treats a character value with a length of zero as null. However, this may not continue to be true in future releases, and Oracle recommends that you do not treat empty strings the same as nulls.
Выделенная часть принадлежит мне. Я не уверен, как вы должны следовать этой рекомендации. Я думаю, это означает явно использовать NULL , а не '' , когда вы намереваетесь использовать NULL .
Обратите внимание, что в SQL NULL представляет значение неизвестный, а не пустое значение. Существует большая разница между строкой без символов (абсолютно допустимой строкой) и неизвестным значением NULL . На практике NULL часто используется для обозначения отсутствия, но это больше условность, чем определение.
Обратите внимание, что хотя поведение Oracle нестандартно, хранение пустых строк в базе данных - плохая, плохая практика.
David Browne - Microsoft
Слава богу, Oracle остается в здравом уме и не имеет двух видов ничего.
@ DavidBrowne-Microsoft. . . Я не согласен. Пустая строка - это пустая строка; Я не вижу ничего плохого в этом как таковой.
Хранение пустых строк вместе с нулями вводит бизнес-различие между двумя видами пробелов, которые могут или не могут быть идентичными в зависимости от интерфейса отчетов.
Также мне всегда кажется, что ввод пустой строки в обязательный столбец скорее противоречит духу ограничения not null . Скажем, модель данных требует, чтобы у клиента была фамилия. ОК, я установил '' . Задача решена?
@ DavidBrowne-Microsoft - Не могли бы вы изложить причины своего мнения? Сомневаюсь, что это разделяет большинство профессионалов. Конечно, авторы стандарта SQL не согласны с этим.
@WilliamRobertson - Это чушь. Ни NULL , ни пустая строка не являются «пробелом». Если вы имели в виду «неопределенный», это просто неправда; NULL не определен, а пустая строка - нет. Пустая строка должна быть нейтральным элементом для конкатенации (так же, как 0 для сложения чисел). Длина пустой строки должна быть 0, длина NULL должна быть NULL .
Распространенным аргументом является то, что «разрешение пустой строке отличаться от NULL может вызвать множество проблем». Я никогда не понимал этого аргумента; это, конечно, неверно, но я хотел бы хотя бы понять некоторые логические возражения. (Я видел много, но они действительно не имели смысла.) Напротив, существует множество идиотских обходных решений, которые мы должны использовать именно потому, что пустая строка является совпадает с NULL в Oracle. Единственное оправдание, которое имеет смысл сохранить таким образом, состоит в том, чтобы не отображать недопустимые запросы, которые были написаны до того, как стандарт SQL потребовал правильной обработки.
@WilliamRobertson. . . Я мог представить себе некую согласованную структуру, в которой '' не допускался в поле NOT NULL . Я не могу вообразить ни одного, где = '' никогда не оценивается как истина, потому что '' интерпретируется как NULL . Итак, если цель состоит в том, чтобы избежать путаницы, Oracle, по моему опыту, сделал что-то гораздо более запутанное.
В большинстве доменов нет функциональной разницы между NULL и '', и разрешение их хранения в одном столбце создает либо скрытые ошибки в коде, который проверяет, установлены ли значения, либо дополнительную сложность при проверке того, является ли значение NULL или ''. Я не говорю, что DMBS не должна разрешать и то, и другое, просто приложение должно разрешать не более одного для каждого столбца. И NULL согласован для всех типов данных, поэтому его следует предпочесть.
David Browne - Microsoft
Независимо от того, как мы отстаиваем правильное обращение с ними, дело в том, что практически каждый язык и система оставляют интерпретацию и обработку нулевой или пустой строки разработчику в качестве детали реализации. Я не удивлен, что реализация Oracle лишает этого выбора и достаточно близорука, чтобы предполагать и объединять одно с другим.
Привет, сегодня я столкнулся со странной ситуацией. У меня было предложение where, где было условие, которое возвращает String, и я хотел проверить, пусто оно или нет. И когда он возвращает пустую строку, Oracle по-прежнему обращается с ней как с другой строкой. Я пошел дальше и подготовил простые запросы:
А теперь то, чего я не могу понять:
Даже если я проверю, разные ли они, результата все равно нет.
Кто-нибудь может мне это объяснить?
Пустая строка - это то же самое, что и нули в Oracle. См. этот вопрос и документы, особенно часть о сравнениях.
@AlexPoole Спасибо за ссылки на документы. У многих есть мнения, факты всегда приветствуются. Действительно любопытно то, что, в отличие от большей части документации Oracle, эта ясна!
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно.
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей.
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то.
NULL в OLAP
Очень коротко ещё об одной особенности, связанной с агрегатами. В многомерных кубах NULL в результах запроса может означать как отсутствие данных, так и признак группировки по измерению. Самое противное, что на глаз эти две его ипостаси никак не различишь. К счастью, есть специальные функции GROUPING и GROUPING_ID , у которых глаз острее. GROUPING(столбец) вернёт единицу, если NULL в столбце измерения означает признак группировки по этому столбцу и ноль, если там содержится конкретное значение (в частности, NULL). Функция GROUPING_ID — это битовый вектор из GROUPING ов, в этой заметке она точно лишняя.
В общем, такая вот краткая и сумбурная информация про дуализм NULLа в многомерном анализе. Ниже пример использования GROUPING , а за подробностями велкам ту Data Warehousing Guide, глава 21.
Удобная фишка sqlplus: при выводе данных заменяет NULL на указанную строку:
Читайте также: