Что означает в oracle
Специальное значение 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ов:
Пустой набор данных:
Обработка ошибок
В PL/SQL любая ошибка или предупреждение называется исключением (exception). В PL/SQL есть кое-какие определенные внутренне ошибки, но также допускается определять и свои собственные. При возникновении любой ошибки инициируется исключение, и управление переходит в отвечающий за обработку исключений раздел программы PL/SQL. В случае определения своих собственных ошибочных ситуаций необходимо обеспечивать инициирование исключений за счет применения специального оператора RAISE.
Ниже приведен пример использования оператора RAISE для обработки исключений:
Курсорные переменные
Курсорные переменные указывают на текущую строку в многострочном результирующем наборе. В отличие от обычного курсора, однако, курсорная переменная является динамической, что позволяет присваивать ей новые значения и передавать ее другим процедурами и функциям. Создаются курсорные переменные в PL/SQL следующим образом.
Сначала определяется тип REF CURSOR, как показано ниже:
Затем объявляются сами курсорные переменные типа EmpCurType в анонимном блоке кода PL/SQL либо в процедуре (или функции):
Процедуры, функции и пакеты
Процедуры в PL/SQL могут применяться для выполнения различных DML-операций. Ниже приведен пример простой процедуры Oracle:
В отличие от процедур, функции в PL/SQL возвращают значение, как показано в следующем примере:
Пакеты (packages) в Oracle представляют собой объекты, которые обычно состоят из нескольких взаимосвязанных процедур и функций и, как правило, применяются для выполнения какой-нибудь функции приложения путем вызова всех находящихся внутри пакета взаимосвязанных процедур и функций. Пакеты являются чрезвычайно мощным средством, поскольку могут содержать большие объемы функционального кода и многократно выполняться несколькими пользователями.
Каждый пакет обычно состоит из двух частей: спецификации и тела. В спецификации пакета объявляются все входящие в его состав переменные, курсоры и подпрограммы (процедуры и функции), а в теле пакета содержится фактический код этих курсоров и подпрограмм.
В листинге А.6 приведен пример простого пакета Oracle.
При желании использовать пакет emp_pkg для награждения какого-то сотрудника надбавкой к зарплате, все, что потребуется сделать — выполнить следующую команду:
Я пытаюсь проверить, является ли значение из столбца в запросе oracle (10g) числом, чтобы сравнить его. Что-то вроде:
Есть идеи, как это проверить?
Предполагая, что столбец идентификатора в myTable не объявлен как ЧИСЛО (что кажется странным выбором и, вероятно, будет проблематичным), вы можете написать функцию, которая пытается преобразовать идентификатор (предположительно VARCHAR2) в число, перехватывает исключение и возвращает «Y» или «N». Что-то вроде
Затем вы можете встроить этот вызов в запрос, т.е.
Обратите внимание, что хотя PL / SQL имеет логический тип данных, SQL его не имеет. Таким образом, хотя вы можете объявить функцию, возвращающую логическое значение, вы не можете использовать такую функцию в запросе SQL.
Приятно то, что вам не нужна отдельная функция PL / SQL. Потенциально проблематичная часть состоит в том, что регулярное выражение может быть не самым эффективным методом для большого количества строк.
Ответ Саиша с использованием REGEXP_LIKE является правильной идеей, но не поддерживает плавающие числа. Этот будет .
Возвращаемые числовые значения
Возвращаемые значения не числовые
Вот решение на основе Майкла Дарранта, которое работает для целых чисел.
Адриан Карнейро опубликовал решение, которое работает с десятичными и другими знаками. Однако, как указал Джастин Кейв, это приведет к неправильной классификации строк как «123.45.23.234» или «131 + 234».
Если вам нужно решение без PL / SQL или REGEXP_LIKE, это может помочь.
Вы можете использовать функцию регулярного выражения regexp_like в ORACLE (10g), как показано ниже:
Я против использования when others , поэтому я бы использовал (возвращает "логическое целое число" из-за того, что SQL не поддерживает логические значения)
В вызове SQL вы должны использовать что-то вроде
Это мой запрос, чтобы найти все, что НЕ является числом:
В моей области я. и, к сожалению, десятичные числа пришлось принять во внимание, иначе вам понадобится только одно из ограничений.
Как определяется столбец? Если это поле varchar, то это не число (или не хранится как единица). Oracle может выполнить преобразование за вас (например, выбрать * from someTable, где charField = 0), но он вернет только строки, в которых преобразование выполнено и возможно. Это тоже далеко не идеальная ситуация с точки зрения производительности.
Итак, если вы хотите провести сравнение чисел и рассматривать этот столбец как число, возможно, его следует определить как число?
Тем не менее, вот что вы можете сделать:
Вы также можете включить другие параметры, которые есть у обычного to_number. Используйте так:
Он не вернет строки, которые Oracle считает недопустимым числом.
Обратите внимание, что он не будет рассматривать 45e4 как число, но вы всегда можете изменить регулярное выражение, чтобы добиться противоположного.
@JustinCave - Замена «when value_error» на «when others» является хорошим усовершенствованием вашего подхода, описанного выше. Эта небольшая дополнительная настройка, хотя концептуально такая же, устраняет необходимость определения и последующего выделения памяти для вашей переменной l_num:
Также примечание для тех, кто предпочитает имитировать логику числового формата Oracle с использованием «более рискованного» подхода REGEXP, пожалуйста, не забывайте учитывать NLS_NUMERIC_CHARACTERS и NLS_TERRITORY.
Ну, вы можете создать функцию is_number для вызова, чтобы ваш код работал.
РЕДАКТИРОВАТЬ: пожалуйста, ответьте на ответ Джастина. Забыл эту маленькую деталь для чистого вызова SQL .
Вы можете использовать этот пример
Функция для мобильного номера длиной 10 цифр и начиная с 9,8,7 с использованием регулярного выражения
Обратите внимание, что подходы с использованием регулярных выражений или функций - это в несколько раз медленнее, чем обычное условие sql.
Таким образом, некоторые эвристические обходные пути с ограниченной применимостью подходят для огромного сканирования.
Существует решение для случаев, когда вы точно знаете, что нечисловые значения будут содержать некоторые буквы алфавита:
И если вы знаете, что какая-то буква всегда будет присутствовать в нечисловых случаях:
Когда числовые регистры всегда будут содержать ноль:
Если условие равно нулю, то это число
Вот простой метод, который:
- не полагается на TRIM
- не полагается на REGEXP
- позволяет указать десятичный разделитель и / или разделители тысяч (в моем примере "." и ",")
- очень хорошо работает с такими древними версиями Oracle, как 8i (лично протестирован на 8.1.7.4.0; да, вы все правильно прочитали)
Конечно, это, возможно, не самый мощный метод из всех; например, "." ошибочно идентифицируется как числовое. Однако это довольно просто и быстро, и он может очень хорошо выполнять свою работу, в зависимости от фактических значений данных, которые необходимо обработать.
Для целых чисел мы можем упростить операцию Translate следующим образом:
Как это работает
Из приведенного выше обратите внимание на синтаксис функции Translate : TRANSLATE(string, from_string, to_string) . Теперь функция Translate не может принимать NULL в качестве аргумента to_string . Таким образом, если указать 'a0123456789' как from_string и 'a' как to_string , произойдут две вещи:
- символ a остается в покое;
- числа от 0 до 9 ничего не заменяются, поскольку для них не указана замена в to_string .
Фактически числа отбрасываются. Если результатом этой операции является NULL , это означает, что вначале были чисто числа.
Использование оператора SELECT в PL/SQL
При использовании оператора SELECT в PL/SQL нужно сохранять извлекаемые значения в переменных, как показано ниже:
Базовый блок PL/SQL
Блоком в PL/SQL называется исполняемая программа. Блок кода PL/SQL, независимо от того, инкапсулируется он внутри какой-то программной единицы наподобие процедуры или задается в виде анонимного блока в свободной форме, состоит из следующих структур, которые представляют собой четыре ключевых оператора, только два из которых являются обязательными.
- DECLARE . Этот оператор является необязательным и представляет собой то место, в котором при желании объявляются переменные и курсоры программы.
- BEGIN . Этот оператор является обязательным и указывает, что далее будут идти операторы SQL и PL/SQL, т.е. обозначает начало блока кода PL/SQL.
- EXCEPTION . Этот оператор является необязательным и описывает методы обработки ошибок.
- END . Этот оператор является обязательными и обозначает конец блока кода PL/SQL.
Ниже приведен пример простого блока кода PL/SQL:
Неявные курсоры
В приведенном ниже блоке кода PL/SQL оператор SELECT, например, предусматривает применение неявного курсора:
Условное управление
Главной разновидностью условной управляющей структуры в PL/SQL является оператор IF, который обеспечивает условное выполнение операторов. Он может применяться в одной из трех следующих форм: IF-THEN, IF-THEN-ELSE и IF-THEN-ELSEIF. Ниже приведен пример простого оператора IF-THEN-ELSEIF:
Конструкции циклов в PL/SQL
Конструкции циклов в PL/SQL позволяют обеспечивать итеративное выполнение кода либо заданное количество раз, либо до тех пор, пока определенное условие не станет истинным или ложным. В следующих подразделах описываются основные виды этих конструкций.
Простой цикл
Конструкция простого цикла подразумевает помещение набора SQL-операторов между ключевыми словами LOOP и END LOOP. Оператор EXIT завершает цикл. Конструкция простого цикла применяется тогда, когда точно неизвестно, сколько раз должен выполняться цикл. В случае ее применения решение о том, когда цикл должен завершаться, принимается на основании содержащейся между операторами LOOP и END LOOP логики.
В следующем примере цикл будет выполняться до тех пор, пока значение quality_grade не достигнет 6:
Еще один простой вид цикла позволяет выполнять конструкция LOOP. EXIT. WHEN, в которой длительность цикла регулируется оператором WHEN. Внутри WHEN указывается условие, и когда это условие становится истинным, цикл завершается. Ниже показан простой пример:
Цикл WHILE
Цикл WHILE указывает, что определенный оператор должен выполняться до тех пор, пока определенное условие остается истинным. Обратите внимание на то, что условие вычисляется за пределами цикла, и вычисляется оно всякий раз, когда выполняются операторы, указанные между операторами LOOP и END LOOP. Когда условие перестает быть истинным, происходит выход из цикла. Ниже приведен пример цикла WHILE:
Цикл FOR
Цикл FOR применяется тогда, когда требуется, чтобы оператор выполнялся определенное количество раз. Он имитирует классический цикл do, который существует в большинстве языков программирования. Ниже приведен пример цикла FOR:
Написание исполняемых операторов PL/SQL
После оператора BEGIN можно начинать вводить все свои желаемые SQL-операторы. Выглядеть эти операторы должны точно так же, как обычные операторы SQL. При использовании операторов SELECT и INSERT в PL/SQL, правда, необходимо помнить об особенностях, о которых более подробно речь пойдет в следующих разделах.
Использование DML-операторов в PL/SQL
Любые операторы INSERT, DELETE или UPDATE работают в PL/SQL точно так же, как в обычном SQL. Однако в PL/SQL после каждого из них можно также применять оператор COMMIT, как показано ниже:
Явные курсоры
Явные курсоры создаются разработчиком приложения и облегчают операции с набором строк, которые могут обрабатываться друг за другом. Они применяются всегда, когда известно, что SQL-оператор будет возвращать более одной строки. Обратите внимание, что явный курсор необходимо всегда объявлять в начале блока PL/SQL внутри раздела DECLARE, в отличие от неявного курсора, на который никогда не нужно ссылаться в коде.
После объявления явного курсора он будет проходить через следующие этапы обработки.
- Конструкция OPEN будет определять строки, которые находятся в курсоре, и делать их доступными для программы PL/SQL.
- Команда FETCH будет извлекать данные из курсора в указанную переменную.
- По завершении процесса обработки курсор должен всегда закрываться явным образом.
В листинге А.4 показан пример создания курсора и затем его использования внутри цикла.
Управляющие структуры в PL/SQL
В PL/SQL предлагается несколько видов управляющих структур (control structures), которые позволяют обеспечивать итерацию кода или условное выполнение определенных операторов. Все они кратко описаны в последующих разделах моего блога.
3 ответа 3
В Oracle PL\SQL при вызовах процедур и функций можно явно указать какому параметру какое значение передается.
- Если у нас есть несколько перегруженных функций, с разными типами параметров, то иногда это единственный способ вызвать нужную нам функцию.
- Можно указывать параметры в произвольном порядке
- Улучшает читаемость кода
Правильно ли я понимаю, что если в параметр при вызове вписано
Существуют три способа задать параметры в вызове подпрограмм:
Positional notation - актуальные параметры задаются в том же порядке, в котором они объявлены при декларации.
Named notation - актуальные параметры задаются в любом порядке используя синтаксис:
formal => actual
Mixed notation - сначала задаются параметры используя positional notation, затем используется named notation для остальных параметров.
Отличие в регистре в примере вопроса не играет никакой роли, до символа => формальный параметр (formal), а после актуальный (actual). Их имена могут полностью совпадать.
Named notation имеет ряд преимуществ по сравнению с positional и mixed notation:
Лучшая читаемость кода.
Порядок указания параметров не важен и не может быть неправильным.
Вызов подпрограммы должен быть изменён только если в декларации добавлен новый обязательный формальный параметр.
Позволяет избежать трудно диагностируемых ошибок при нарушении порядка указания актуальных параметров, особенно если они литералы.
и является рекомендуемым для вызова подпрограмм при написании нового или рефакторинге старого кода, и особенно тех, которые поддерживаются кем-то другим.
Программа PL/SQL представляет собой последовательность команд, состоящих из одной или нескольких строк текста. Набор символов, из которых составляются эти строки, зависит от используемого в базе данных набора символов. Для примера в табл. 1 приведены символы набора US7ASCII.
Каждое ключевое слово, оператор и лексема PL/SQL состоит из разных комбинаций символов данного набора. Остается разобраться, как связать эти символы друг с другом!
А теперь любопытный факт о PL/SQL. В документации Oracle (а также в предыдущих изданиях этой книги) символы &, < >и [ ] также были отнесены к стандартному набору символов. Хотя эти символы допустимы в литеральных строках, Oracle не использует их в коде PL/SQL. Более того, эти символы не могут непосредственно включаться в идентификаторы, определяемые программистом.
Запомните, что язык PL/SQL не учитывает регистр символов. Это означает, что символы верхнего регистра интерпретируются так же, как символы нижнего регистра (кроме символов, заключенных в ограничители, с которыми они интерпретируются как литеральная строка). В книге встроенные ключевые слова языка (а также некоторые идентификаторы, используемые Oracle в качестве имен встроенных функций и пакетов) обычно записываются в верхнем регистре, а идентификаторы, определяемые программистом, — в нижнем регистре.
Некоторые символы — как по отдельности, так и в сочетании с другими символами — имеют в PL/SQL специальное значение. Эти специальные символы (простые и составные) перечислены в табл. 2.
Символы | Описание |
; | Завершает объявления и команды |
% | Индикатор атрибута (атрибут курсора, подобный %ISOPEN, или атрибут неявных объявлений, например %ROWTYPE) также используется в качестве символа подстановки в условии LIKE |
_ | Обозначение подстановки одного символа в условии LIKE |
@ | Признак удаленного местоположения |
: | Признак хост-переменной, например :block.item в Oracle Forms |
** | Оператор возведения в степень |
<> или != или ^= или ~= | Оператор сравнения «не равно» |
|| | Оператор конкатенации |
> | Ограничители метки |
= | Операторы сравнения «меньше или равно» и «больше или равно» |
:= | Оператор присваивания |
=> | Оператор ассоциации |
.. | Оператор диапазона |
-- | Признак однострочного комментария |
/* и */ | Начальный и конечный ограничители многострочного комментария |
Символы группируются в лексические единицы, которые называются атомарными, поскольку они представляют собой наименьшие самостоятельные элементы языка. В PL/SQL лексическими единицами являются идентификатор, литерал, разделитель и комментарий. Мы рассмотрим их в следующей статье моего блога.
Хотя язык SQL и является легким в изучении и обладает массой мощных функциональных возможностей, он не позволяет создавать такие процедурные конструкции, которые возможны в языках третьего поколения вроде C. Язык PL/SQL является собственным расширением языка SQL от Oracle и предлагает функциональность серьезного языка программирования. Одно из главных его преимуществ состоит в том, что он позволяет использовать в базе данных такие программные единицы, как процедуры и пакеты, и тем самым увеличивать возможность повторного использования кода и его производительность.
Объявление переменных в PL/SQL
В операторе DECLARE можно объявлять как переменные, так и константы. Прежде чем использовать какую-либо переменную ее нужно обязательно объявить. Переменная в PL/SQL может представлять собой как переменную встроенного типа, такого как DATE, NUMBER, VARCHAR2 или CHAR, так и составного вроде VARRAY. Помимо этого, в PL/SQL еще применяются такие типы данных, как BINARY_INTEGER и BOOLEAN.
Ниже приведены некоторые типичные примеры объявления переменной в PL/SQL:
Помимо переменных также можно объявлять и константы, как показано в следующем примере:
Еще можно использовать атрибут %TYPE и с его помощью указывать при объявлении переменной, что ее тип данных должен совпадать с типом данных определенного столбца таблицы:
Посредством атрибута %ROWTYPE можно указывать, что тип данных записи (строки) должен совпадать с типом данных определенной таблицы базы данных. Например, в следующем коде указано, что запись DeptRecord должна содержать все те же столбцы, что и таблица department, а типы данных и длина этих столбцов в ней должны выглядеть абсолютно идентично:
Курсорный цикл FOR
Обычно при использовании явных курсоров требуется открывать курсор, извлекать данные и по завершении закрывать курсор. Курсорный цикл FOR позволяет выполнять эти процедуры по открытию, извлечению и закрытию автоматически, чем очень сильно упрощает дело. В листинге А.5 показан пример применения конструкции курсорного цикла FOR.
NULL в OLAP
Очень коротко ещё об одной особенности, связанной с агрегатами. В многомерных кубах NULL в результах запроса может означать как отсутствие данных, так и признак группировки по измерению. Самое противное, что на глаз эти две его ипостаси никак не различишь. К счастью, есть специальные функции GROUPING и GROUPING_ID , у которых глаз острее. GROUPING(столбец) вернёт единицу, если NULL в столбце измерения означает признак группировки по этому столбцу и ноль, если там содержится конкретное значение (в частности, NULL). Функция GROUPING_ID — это битовый вектор из GROUPING ов, в этой заметке она точно лишняя.
В общем, такая вот краткая и сумбурная информация про дуализм NULLа в многомерном анализе. Ниже пример использования GROUPING , а за подробностями велкам ту Data Warehousing Guide, глава 21.
Удобная фишка sqlplus: при выводе данных заменяет NULL на указанную строку:
До смешного мелкий вопрос, и все же гугл плохо реагирует на спец знаки, выдавая вариации на тему "больше или равно" >=, но тут у нас какой-то переход и я не понимаю смысл (пытаюсь разобрать чужой код).
Есть вызов функции:
Вот и возникает вопрос, что это за морфема в месте ввода параметров, где имена параметров отличаются только регистром?
ищите по строке oracle named parameters по крайней мере в большинстве языков такой знак означает именно задание имени именованного параметра или что нибудь из той же оперы. первый раз вижу в оракле, но судя по выдаче гугла это то о чем я подумал
Пока в предложенных ответах не упомянается явно, как это собственно называется: positional notation vs. named notation, что быстро находится гуглом.
Записи в PL/SQL
Записи (records) в PL/SQL позволяют воспринимать взаимосвязанные данные как одно целое. Они могут содержать поля, каждое из которых может представлять отдельный элемент. Можно использовать атрибут ROW%TYPE и с его помощью объявлять записью столбцы определенной таблицы, что подразумевает применение таблицы в качестве шаблона курсора, а можно создавать и свои собственные записи. Ниже приведен простой пример записи:
Для ссылки на отдельное поле внутри записи применяется точечное обозначение, как показано ниже:
NULL в OLAP
Очень коротко ещё об одной особенности, связанной с агрегатами. В многомерных кубах NULL в результах запроса может означать как отсутствие данных, так и признак группировки по измерению. Самое противное, что на глаз эти две его ипостаси никак не различишь. К счастью, есть специальные функции GROUPING и GROUPING_ID , у которых глаз острее. GROUPING(столбец) вернёт единицу, если NULL в столбце измерения означает признак группировки по этому столбцу и ноль, если там содержится конкретное значение (в частности, NULL). Функция GROUPING_ID — это битовый вектор из GROUPING ов, в этой заметке она точно лишняя.
В общем, такая вот краткая и сумбурная информация про дуализм NULLа в многомерном анализе. Ниже пример использования GROUPING , а за подробностями велкам ту Data Warehousing Guide, глава 21.
Удобная фишка sqlplus: при выводе данных заменяет NULL на указанную строку:
До смешного мелкий вопрос, и все же гугл плохо реагирует на спец знаки, выдавая вариации на тему "больше или равно" >=, но тут у нас какой-то переход и я не понимаю смысл (пытаюсь разобрать чужой код).
Есть вызов функции:
Вот и возникает вопрос, что это за морфема в месте ввода параметров, где имена параметров отличаются только регистром?
ищите по строке oracle named parameters по крайней мере в большинстве языков такой знак означает именно задание имени именованного параметра или что нибудь из той же оперы. первый раз вижу в оракле, но судя по выдаче гугла это то о чем я подумал
Пока в предложенных ответах не упомянается явно, как это собственно называется: positional notation vs. named notation, что быстро находится гуглом.
Использование курсоров
Курсором (cursor) в Oracle называется указатель на область в памяти, в которой содержится результирующий набор SQL-запроса, позволяющий индивидуально обрабатывать содержащиеся в результирующем наборе строки. Курсоры, которые используются Oracle при выполнении DML-операторов, называются неявными, а курсоры, которые создают и используют разработчики приложений — явными.
Атрибуты курсоров
В примере, приведенном в листинге А.4, для указания того, когда цикл должен завершаться, используется специальный атрибут курсора %NOTFOUND. Атрибуты курсоров очень полезны при работе с явными курсорами. Наиболее важные из них перечислены ниже.
- %ISOPEN. Булевский атрибут, который после завершения выполнения SQL-оператора возвращает false. До тех пор, пока курсор остается открытым, он возвращает true.
- %FOUND. Булевский атрибут, который выполняет проверку на предмет наличия подходящих для SQL-оператора строк, т.е. остались ли у курсора еще какие-то строки для извлечения.
- %NOTFOUND. Булевский атрибут, который сообщает о том, что не удалось обнаружить ни одной подходящей для SQL-оператора строки, т.е. у курсора больше не осталось никаких строк для извлечения.
- %ROWCOUNT. Атрибут, который возвращает информацию о том, сколько курсору удалось извлечь строк на текущий момент.
Читайте также: