Классика баз данных - статьи
Оператор выделения памяти под дескриптор
Оператор имеет следующий синтаксис:
::=ALLOCATE DESCRIPTOR [WITH MAX ] ::= ::=[] ::= GLOBAL | LOCAL ::=| |
Дескриптор - это динамически выделяемая часть памяти прикладной программы, служащая для принятия информации о результате или параметрах динамически подготовленного оператора SQL или задания параметров такого оператора. Смысл того, что для выделения памяти используется оператор SQL, а не просто стандартная функция alloc или какая-нибудь другая функция динамического запроса памяти, состоит в том, что прикладная программа может теперь не знать структуру дескриптора и даже его адрес. Это позволяет не привязывать SQL к особенностям какой-либо системы программирования или ОС. Все обмены информацией между собственно прикладной программой и дескрипторами производятся также с помощью специальных операторов SQL (GET и SET, см. ниже). Далее возникает вопрос: зачем вообще выделять память под дескрипторы динамически? Это нужно потому, что в общем случае прикладная программа, использующая динамический SQL, не знает в статике число одновременно действующих динамических операторов SQL, описание которых может потребоваться. С этим же связано то, что имя дескриптора может задаваться как литеральной строкой символов, так и через строковую переменную включающего языка, т. е. его можно генерировать во время выполнения программы. В операторе ALLOCATE DESCRIPTOR, помимо прочего, может указываться число описательных элементов, на которое он рассчитан. Если, например, при выделении памяти под дескриптор в разделе WITH MAX указано целое положительное число N, а потом дескриптор используется для описания M (M>N) элементов (например M столбцов результата запроса), то это приводит к возникновению исключительной ситуации.
Оператор объявления курсора над динамически подготовленным оператором выборки
Оператор определяется следующим синтаксисом: ::=DECLARE [INSENSITIVE] [SCROLL]CURSOR FOR
как определяется в новом стандарте, для всех операторов DECLARE CURSOR курсоры фактически создаются при начале транзакции и уничтожаются при ее завершении. Заметим, что в этом операторе и прямо (литерально) заданные идентификаторы.
Другая разновидность оператора
Для этого оператора действуют следующие синтаксические правила: ::=ALLOCATE [INSENSITIVE] [SCROLL]CURSOR FOR ::=[]
Курсоры, определяемые с помощью оператора ALLOCATE CURSOR, фактически создаются при выполнении такого оператора и уничтожаются при выполнении оператора DEALLOCATE PREPARE или при конце транзакции. В этом операторе имена курсора и подготовленного оператора SQL могут задаваться не только в литеральной форме, но и через переменные (т. е. может использоваться косвенное именование). относится к области видимости имен: в пределах текущего модуля или в пределах текущей сессии.
Оператор открытия курсора, связанного с динамически подготовленным оператором выборки
Синтаксис оператора открытия курсора следующий: ::=OPEN []
По сути оператор открытия курсора, связанного с динамически подготовленным оператором SQL, отличается от статического случая только возможным наличием раздела using, в котором задаются фактические параметры оператора выборки. Кроме того, имя курсора может задаваться через переменную (т. е. косвенным образом).
Оператор чтения строки по курсору, связанному с динамически подготовленным оператором выборки
Синтаксис: ::=FETCH [[] FROM]
На самом деле оператор чтения по курсору, связанному с динамически подготовленным оператором SQL, отличается от статического случая только возможным наличием раздела using, в котором задается размещение значений текущей строки результирующей таблицы. Кроме того, имя курсора может задаваться через переменную.
Оператор закрытия курсора, связанного с динамически подготовленным оператором выборки
Оператор закрытия курсора определяется следующим синтаксическим правилом: ::=CLOSE
Оператор закрытия курсора, связанного с динамически подготовленным оператором SQL, отличается от статического случая только тем, что имя курсора может задаваться через переменную.
Оператор позиционного удаления
Синтаксис: ::=DELETE FROM WHERE CURRENT OF
Оператор позиционного удаления по курсору, связанному с динамически подготовленным оператором SQL, отличается от статического случая только тем, что имя курсора может задаваться через переменную.
Оператор позиционной модификации
Оператор определяется следующим синтаксическим правилом: ::=UPDATE SET [{ }. . . ]WHERE CURRENT OF
Оператор позиционной модификации по курсору, связанному с динамически подготовленным оператором SQL, отличается от статического случая только тем, что имя курсора может задаваться через переменную.
Подготавливаемый оператор позиционного удаления
Синтаксис оператора: ::=DELETE [FROM ]WHERE CURRENT OF
Основной резон появления этого и следующего операторов состоит в том, что сочетание курсора, определенного на динамически подготовленном операторе выборки, и статически задаваемых операторах удаления и модификации по этому курсору, выглядит довольно нелепо. Поэтому в стандарте появились динамически подготавливаемые позиционные операторы удаления и вставки. Естественно, что выполняться они должны с помощью оператора EXECUTE.
Подготавливаемый оператор позиционной модификации
::=UPDATE []SET [{ }. . . ]WHERE CURRENT OF
См. . Если внимательно сравнить средства динамического SQL СУБД Oracle V. 6и стандарта SQL/92, то видно, что Oracle практически вкладывается в стандарт, если не считать небольших синтаксических различий и (что существенно более важно) разного стиля работы с дескрипторами. Думается, что примерно такая же ситуация имеет место в других СУБД, поддерживающих динамический SQL. Поэтому нашими рекомендациями при использовании динамического SQL в прикладных программах являются следующие (если, конечно, вы не хотите дождаться повсеместной и полной реализации SQL/92):ограничиться подмножеством операторов динамического SQL, реализованным в Oracle V. 6; локализовать части программы, связанные с работой с дескрипторами (т. е. как минимум не допускать прямой работы с полями области дескрипторов в стиле Oracle).
Оператор освобождения памяти из-под дескриптора
Синтаксис оператора: ::=DEALLOCATE DESCRIPTOR
Выполнение этого оператора приводит к освобождению памяти из-под ранее выделенного дескриптора. После этого использование имени дескриптора незаконно в любом операторе, кроме ALLOCATE DESCRIPTOR.
Оператор получения информации из области дескриптора SQL
Оператор определяется следующими синтаксическими правилами: ::=GET DESCRIPTOR ::=| VALUE [{ }. . . ] ::= COUNT ::=- ::=
::= ::= ::=TYPE| LENGHT| OCTET_LENGHT| RETURNED_LENGHT| RETURNED_OCTET_LENGHT| PRECISION| SCALE| DATETIME_INTERVAL_CODE| DATATIME_INTERVAL_PRECISION| NULLABLE| INDICATOR| DATA| NAME| UNNAMED| COLLATION_CATALOG| COLLATION_SCHEMA| COLLATION_NAME| CHARACTER_SET_CATALOG| CHARACTER_SET_SCHEMA| CHARACTER_SET_NAME ::=|
Оператор GET DESCRIPTOR служит для выборки описательной информации, ранее размещенной в дескрипторе с помощью оператора DESCRIBE (см. ). За одно выполнение оператора можно получить либо число заполненных элементов дескриптора (COUNT), либо информацию, содержащуюся в одном из заполненных элементов.
Оператор установки дескриптора
Оператор установки имеет следующий синтаксис: ::=SET DESCRIPTOR ::=| VALUE [{ }. . . ] ::=COUNT ::= ::= ::=- ::=
Оператор SET DESCRIPTOR служит для заполнения элементов дескриптора с целью его будущего использования в разделе USING. За одно выполнениеоператора можно поместить значение в поле COUNT (число заполненных элементов)либо частично или полностью сформировать один элемент дескриптора.
Оператор подготовки
Оператор определяется следующим синтаксисом: ::=PREPARE < SQL statement name>FROM < SQL statement variable>< SQL statement variable> ::= ::=| | | | ::=| | | | | | ::=< SQL schema statement> ::=< SQL transaction statement> ::=< SQL session statement> ::= ::=< SQL statement name> ::=| ::=[scope option] ::= [][] ::=FOR { READ ONLY | UPDATE [ OF ] } ::=| ::=SELECT [] ::= DISTINCT | ALL
Оператор PREPARE вызывает компиляцию и построение плана выполнения оператора SQL, заданного в текстовой форме. После успешного выполнения оператора PREPARE с подготовленным оператором связывается указанное (литерально или косвенно) имя этого оператора, которое потом может быть использовано в операторах DESCRIBE, EXECUTE, OPEN CURSOR, ALLOCATE CURSOR и DEALLOCATEPREPARE. Эта связь сохраняется до явного выполнения оператора DEALLOCATEPREPARE.
Оператор отказа от подготовленного оператора
Синтаксис оператора следующий: ::=DEALLOCATE PREPARE < SQL statement name>
Выполнение этого оператора приводит к тому, что ранее подготовленный оператор SQL, связанный с указанным именем оператора, ликвидируется, и, соответственно, имя оператора становится неопределенным. Если подготовленный оператор являлся оператором выборки, и к моменту выполнения оператора DEALLOCATE существовал открытый курсор, связанный с именем подготовленного оператора, то оператор DEALLOCATE возвращает код ошибки. Если же для подготовленного оператора выборки существовал неоткрытый курсор, образованный с помощью оператора ALLOCATE CURSOR, то этот курсор ликвидируется. Если курсор объявлялся оператором DECLARE CURSOR, то такой курсор переходит в состояние, существовавшее до выполнения оператора PREPARE. Если с курсором был связан подготовленный оператор (динамический DELETE или UPDATE), то для этих операторов выполняется неявный оператор DEALLOCATE.
Оператор запроса описания подготовленного оператора
Оператор определяется следующим синтаксисом: ::=| ::=DESCRIBE INPUT < SQL statement name> ::=DESCRIBE [OUTPUT] < SQL statement name> ::=| ::={ USING | INTO } [{ }. . . ] ::= ::={ USING | INTO } SQL DESCRIPTOR ::=| ::= [] ::=[INDICATOR] ::= [] ::=[INDICATOR]
При выполнении оператора DESCRIBE происходит заполнение указанного в операторе дескриптора информацией, описывающей либо результат ранее подготовленного оператора SQL (если это оператор выборки), либо количество и типы параметров подготовленного оператора. В полагается писать USING SQL DESCRIPTOR.
Оператор выполнения подготовленного оператора
Синтаксис оператора следующий: ::=EXECUTE < SQL statement name>[][] ::= ::=
Оператор EXECUTE может быть применен к любому ранее подготовленному оператору SQL, кроме . Если это оператор , то оператор EXECUTE должен содержать раздел с ключевым словом INTO. В любом случае число фактических параметров, задаваемых через разделы using, должно соответствовать числу формальных параметров, определенных в подготовленном операторе SQL.
Оператор подготовки с немедленным выполнением
Синтаксис оператора: ::=EXECUTE IMMEDIATE < SQL statement variable>
При выполнении оператора EXECUTE IMMEDIATE производится подготовка и немедленное выполнение заданного в текстовой форме оператора SQL. При этом подготавливаемый оператор не должен быть оператором выборки, не должен содержать формальных параметров и комментариев.
существенно шире того, который
Набор операторов динамического SQL в стандарте SQL/ 92 существенно шире того, который был реализован в Oracle V. 6. В основном это связано с тем, что введены операторы для работы с дескрипторами, а также появились подготавливаемые операторы позиционного удаления и позиционной модификации.
Оператор подготовки
Оператор PREPARE имеет синтаксис: ::=PREPARE FROM ::=
Во время выполнения оператора PREPARE символьная строка, содержащаяся в host-string-variable, передается компилятору SQL, который обрабатывает ее почти таким же образом, как если бы получил в статике. Построенный при выполнении оператора PREPARE код остается действующим до конца транзакции или до повторного выполнения данного оператора PREPARE в пределах этой же транзакции. В отличие от операторов SQL, статически подставляемых в программу на обычном языке программирования, в которых связь с переменными включающей программы производится по именам (т. е. в соответствии со стандартом во встроенном операторе SQL могут употребляться просто имена переменных включающей программы), динамическая природа операторов, подготавливаемых с помощью оператора PREPARE, заставляет рассматривать эти имена как имена формальных параметров. Соответствие этих формальных параметров адресам переменных включающей программы устанавливается позиционно во время выполнения подготовленного оператора.
РАЗДЕЛ FROM
Результатом выполнения раздела FROM является расширенное декартово произведение таблиц, заданных списком таблиц раздела FROM. Расширенное декартово произведение(расширенное, потому что в качестве операндов и результата допускаются мультимножества) в стандарте определяется следующим образом: "расширенное произведение R есть мультимножество всех строк r, таких, что r является конкатенацией строк из всех идентифицированных таблиц в том порядке, в котором они идентифицированы. Мощность R есть произведение мощностей идентифицированных таблиц. Порядковый номер столбца в R есть n+s, где n - порядковый номер порождающего столбца в именованной таблице T, а s - сумма степеней всех таблиц, идентифицированных до T в разделе FROM". (Возможно, читатель не испытает особого восторга от приведенного абзаца, но таков стиль стандарта.) Как видно из синтаксиса, рядом с именем таблицы можно указывать еще одно имя "correlation name". Фактически, это некоторый синоним имени таблицы, который можно использовать в других разделах табличного выражения для ссылки на строки именно этого вхождения таблицы. (Одна и та же таблица может участвовать несколько раз в списке одного раздела FROM и/или входить в списки разделов FROM нескольких (под)запросов.) Если табличное выражение содержит только раздел FROM (это единственный обязательный раздел табличного выражения), то результат табличного выражения совпадает с результатом раздела FROM.
СПЕЦИФИКАЦИЯ ЗАПРОСА
В спецификации запроса задается список выборки (список арифметических выражений над значениями столбцов результата табличного выражения и констант).В результате применения списка выборки к результату табличного выражения производится построение новой таблицы, содержащей то же число строк, но, вообще говоря, другое число столбцов, значения которых формируются на основе вычисления соответствующих арифметических выражений из списка выборки. Кроме того, в спецификации запроса могут содержаться ключевые слова ALL или DISTINCT. При наличии ключевого слова DISTINCT из таблицы, полученной применением списка выборки к результату табличного выражения, удаляются строки-дубликаты; при указании ALL (или просто при отсутствии DISTINCT)удаление строк-дубликатов не производится.
Типы данных
Набор встроенных типов данных предполагается расширить типами BOOLEAN и ENUMERATED. Хотя по причине поддержки неопределенных значений языку SQL свойственно применение трехзначной логики, тип BOOLEAN содержит только два возможных значения true и false. Для представления значения unknown рекомендуется использовать NULL, что, конечно, не вполне естественно. Перечисляемый тип ENUMERATED обладает свойствами, подобными свойствам перечисляемых типов в языках программирования. Расширены возможности работы с неопределенными значениями. Появился новый оператор CREATE NULL CLASS, позволяющий ввести именованный набор именованных неопределенных значений. При определении домена можно явно указать имя класса неопределенных значений, появление которых допустимо в столбцах, связанных с этим доменом. Смысл каждого неопределенного значения интерпретируется на уровне пользователей. Предполагается включение в язык возможности использовать определенные пользователями типы данных. Видимо, будут иметься возможности определения абстрактных типов данных с произвольно сложной внутренней структурой на основе таких традиционных спецификаций агрегирования и структуризации, как LIST, ARRAY, SET, MULTISET и TURPLE, а также возможности определения объектных типов с соответствующими методами в стиле объектно-ориентированного подхода. Появляется возможность использования принципов наследования свойств существующей таблицы (супертаблицы) при определении новой таблицы (подтаблицы). Подтаблица наследует от супертаблицы все определения столбцов и первичного ключа. Другая возможность - создать таблицу, "подобную " существующей в том смысле, что в новой таблице наследуются определения некоторых столбцов существующей таблицы.
ТИПЫ ДАННЫХ
Появилась возможность использования типа данных символьных строк переменной длины (т. е. при спецификации столбца указывается предельно допустимый размер хранимой строки в символах, а реально в базе данных хранится ровно столько символов, сколько их ввел пользователь). Введены типы данных битовых строк постоянной и переменной длины ( как они реально хранятся в базе данных, в стандарте не определяется). Наконец, стандартизованы темпоральные типы данных DATE (дата), TIME (время) и INTERVAL (временной интервал).
ДИНАМИЧЕСКИЙ SQL
В стандарте определены операторы динамического SQL. См. разд. .
ВСТРОЕННЫЙ SQL
как отмечалось в разд. 2. 5, стандарт SQL/89 формально не включал раздел, посвященный встраиванию конструкций SQL в программу на традиционном языке программирования. Этот раздел являлся приложением и, кроме того, не включал правил встраивания для языков Си и Ада. В SQL/92 полностью специфицированы правила встраивания для наиболее распространенных языков программирования(Ада, Си, Кобол, Фортран, MUMPS, Паскаль, ПЛ/1).
ИНТЕРАКТИВНЫЙ (ПРЯМОЙ) SQL
В SQL/92 специфицирован набор операторов SQL, которые должны поддерживаться в интерактивном режиме, хотя некоторые решения по-прежнему отдаются на откуп реализациям. Этим не исчерпываются расширения SQL/92 по сравнению с SQL/89. Однако не упомянутые выше новые возможности SQL не кажутся настолько важными, чтобы о них стоило писать в журнальной статье (может быть , я и ошибаюсь. . . ).
ИНТЕРНАЦИОНАЛИЗАЦИЯ И НАЦИОНАЛИЗАЦИЯ
При определении схемы базы данных или впоследствии можно определить особенности национального набора символов, включая правила упорядочения. Могут определяться наборы символов, используемые как в хранимых текстовых строках, так и в идентификаторах.
ОПРЕДЕЛЕНИЕ СХЕМЫ БД И МАНИПУЛИРОВАНИЕ СХЕМОЙ БД
Наконец-то появилась возможность создавать хранимые и представляемые таблицы и задавать или удалять привилегии доступа (операторы CREATE TABLE, CREATE VIEW, GRANT, REVOKE) в любой момент времени в любой транзакции вне оператора определения схемы. Появились операторы уничтожения таблиц (DROPTABLE и DROP VIEW), которые также можно выполнять внутри любой транзакции(при наличии соответствующих привилегий). Вообще, следует заметить, что в стандарте SQL/92 для любого оператора класса CREATE существует парный оператор класса DROP. Специфицирован также оператор ALTER TABLE, позволяющий динамически изменять характеристики ранее созданной таблицы (в частности добавлять к ней новые столбцы). Все упомянутые здесь операторы могут включаться в модуль SQL.
ОГРАНИЧЕНИЯ ЦЕЛОСНОСТИ
В добавление к возможностям SQL/89 определения ограничений целостности на уровне столбца и/или таблицы в SQL/92 допустимо отдельное определение ограничений, распространяющееся в общем случае на несколько таблиц. Появилась возможность определения отложенных (проверяемых при завершении транзакции) ограничений целостности. Расширены возможности определения ограничений внешнего ключа (ограничений ссылочной целостности). Введены средства определения (CREATE DOMAIN), изменения (ALTER DOMAIN)и отмены определения (DROP DOMAIN) домена. (На всякий случай напомним читателям, что домены имеют непосредственную связь с ограничениями целостности, поскольку домен определяет потенциально возможное множество значений некоторого типа данных, а при определении столбца таблицы можно указать, к какому домену будут относиться значения этого столбца. Тем самым другие значения допускаться не должны. )
ПРЕДСТАВЛЕНИЯ
В стандарте SQL/92 осмысленно ослаблены требования к изменяемым представлениям(в условии выборки допускаются подзапросы, не коррелирующие со столбцами таблицы разделы FROM основного запроса). Заметим, что множество изменяемых запросов SQL/92 по-прежнему не включает все представления, которые теоретически являются изменяемыми. Уточнен смысл конструкции WITH CHECK OPTION: введены ключевые слова LOCAL и CASCADE. При указании LOCAL контролируется, что измененная строка останется видимой в том представлении, для которого выполнялся оператор UPDATE. Если же указывается CASCADE, то изменение должно остаться видимым в данном представлении и во всех представлениях, которые определены над исходным представлением (на самом деле мы несколько упрощаем ситуацию, для полного анализа которой требуется длительное рассмотрение комбинаций наличия и отсутствия конструкции WITH CHECK OPTION у исходного представления и того, которое над ним определено).
ТАБЛИЧНЫЕ ВЫРАЖЕНИЯ
Появились возможности именования столбцов результирующей таблицы и самой таблицы. Именованные табличные выражения можно использовать, в частности, в разделе FROM запросов. (Раньше всегда было непонятно, почему табличное выражение, результатом которого по определению является таблица, нельзя использовать в качестве элемента списка раздела FROM. ) Появился новый класс табличных выражений, называемых "табличными выражениями с соединениями " (join-table-expression), которые можно использовать только в разделе FROM. Такие табличные выражения строятся на основе базовых и/или представляемых таблиц на основе использования разных видов операции соединения: CROSS JOIN (Декартово произведение), INNER (обычное соединение), LEFT и LEFT OUTER (левое и левое внешнее соединение), RIGHT и RIGHT OUTER (правое и правое внешнее соединение), FULL и FULL JOIN (полное и полное внешнее соединение) и UNION (объединение). (Не уверен, что от появления этого класса табличных выражений потенциальным пользователям реализаций SQL/92 станет жить легче, хотя возможно станет легче формулировать запросы людям, привыкшим к алгебраическому стилю работы с базами данных. )
ВЫРАЖЕНИЯ ЗАПРОСОВ
При построении выражений запросов (формально, согласно синтаксису SQL/92, соответствующие конструкции не называются выражениями запросов; тем не менее мы предпочитаем сохранить этот термин для сближения с семантикой SQL/89), кроме операции теоретико-множественного объединения UNION, которая присутствовала в SQL/89, стало возможным использовать операции EXCEPT (теоретико-множественное вычитание) и INTERSECT (теоретико-множественное пересечение). Заметим для точности, что возможность получения в качестве результата запроса мультимножества строк (т. е. с дубликатами) не позволяет однозначно интерпретировать сразу все эти операции. Поэтому результат одного и того же выражения запросов в разных реализациях может быть разным.
КУРСОРЫ
При определении курсора можно указывать ключевые слова SCROLL и INSENSITIVE. Указание SCROLL означает, что курсор можно явно позиционировать: на первую строку результирующего множества запроса, на последнюю строку, на строку с позицией с положительным или отрицательным смещением от текущей строки, на строку с явно указанным абсолютным номером позиции. Наличие ключевого слова INSENSITIVE означает, что какие бы изменения в базовых таблицах не производились в той же транзакции, в которой определен курсор, они не должны влиять на результирующее множество строк курсора после его открытия. Заметим, что, хотя внешне эти возможности выглядят очень привлекательно, их реализация стоит недешево. И в том и в другом случае требуется явное и почти всегда полное построение результирующего множества запроса, связанного с курсором.
УПРАВЛЕНИЕ ТРАНЗАКЦИЯМИ И УРОВНИ ИЗОЛЯЦИИ
Известно, что в большинстве SQL-ориентированных реляционных СУБД поддерживаются несколько режимов изолированности транзакций. В стандарте SQL/92 специфицирован оператор SET TRANSACTION, который, в частности, позволяет явно установить один из следующих режимов, влияющих на уровень изолированности транзакции: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, SERIALIZABLE. В соответствии со стандартом режим READ UNCOMMITTED допускает наличие чтения "грязных данных " (если транзакция T1 работает в этом режиме, то она может прочитать данные, обновленные транзакцией T2, которая заканчивается откатом; эти данные "грязные ", поскольку никогда не будут существовать в БД). При установке режима READ COMMITTED транзакция не сможет прочитать "грязные данные ", но в ней может возникнуть ситуация "неповторяющегося чтения " (пусть транзакция T1 работает в этом режиме и в ней выполняется выборка некоторой строки некоторой таблицы; после этого в транзакции T2срабатывает оператор, обновляющий эту строку; теперь в транзакции T1 снова выполняется оператор, выбирающий ту же строку, и прикладная программа или интерактивный пользователь с удивлением обнаруживают, что значения полей строки изменились). Если устанавливается режим REPEATABLE READ, "неповторяющиеся чтения "должны гарантированно отсутствовать, но возможно возникновение "строк-фантомов "(пусть транзакция T1 работает в этом режиме и выбирает некоторое множество строк некоторой таблицы в соответствии с заданным условием; после этого транзакция T2 заносит в ту же таблицу новую строку, удовлетворяющую условию выборки транзакции T1; теперь в транзакции T1 повторно срабатывает тот же самый оператор выборки, и прикладная программа или интерактивный пользователь с удивлением обнаруживают, что множество выбранных строк отличается оттого, как им оно было при первом выполнении оператора выборки). При установке режима SERIALIZABLE должно гарантироваться отсутствие всех перечисленных выше эффектов. В этом случае транзакция должна выполняться так, как если бы она выполнялась в отсутствии всех конкурирующих транзакций(другими словами, смесь транзакций, для которых требуется полная сериализация, должна обрабатываться системой так, чтобы суммарный эффект был эквивалентен некоторому последовательному выполнению этих транзакций). В соответствии со стандартом режим SERIALIZABLE должен являться режимом, устанавливаемым для транзакции по умолчанию (если в ней не встречается какой-либо оператор SET TRANSACTION). Кроме указания режима изоляции в операторе SET TRANSACTION можно указать, является ли транзакция только читающей базу данных (READ ONLY) или обновляющей(READ WRITE). По умолчанию любая транзакция считается обновляющей, если только не задан режим изоляции READ UNCOMMITTED. В последнем случае транзакция полагается только читающей. Другими словами, комбинация READ WRITE и READUNCOMMITTED является недопустимой.
Предикат сравнения
Синтаксис предиката сравнения определяется следующими правилами: ::= { | } ::== | <> | < | > | <= | >=
Через "<>" обозначается операция "неравенства". Арифметические выражения левой и правой частей предиката сравнения строятся по общим правилам построения арифметических выражений и могут включать в общем случае имена столбцов таблиц из раздела FROM и константы (не обязательно литеральные; вместо литеральной константы может использоваться имя столбца таблицы, указанной в разделе FROM более внешнего подзапроса, или имя переменной программы, написанной на объемлющем языке). Типы данных арифметических выражений должны быть сравнимыми (например, если тип столбца a таблицы A является типом символьных строк, то предикат "a = 5" недопустим). Если правый операнд операции сравнения задается подзапросом, то дополнительным ограничением является то, что мощность результата подзапроса должна быть не более единицы. Если хотя бы один из операндов операции сравнения имеет неопределенное значение или если правый операнд является подзапросом с пустым результатом, то значение предиката сравнения равняется unknown. Заметим, что значение арифметического выражения не определено, если в его вычислении участвует хотя бы одно неопределенное значение. Еще одно важное замечание из стандарта SQL/89: в контексте GROUP BY, DISTINCT и ORDER BY неопределенное значение выступает как специальный вид определенного значения, т.е. возможно, например, образование группы строк, значение указанного столбца которых является неопределенным. Для обеспечения переносимости прикладных программ нужно внимательно анализировать специфику работы с неопределенными значениями в конкретной СУБД.
Расширения языка
В языке, определяемом стандартом SQL/92, содержится много свойств, которые отсутствовали в языке SQL/89. Ниже приводится краткая сводка этих свойств.
Несовместимости
В стандарте SQL/92 содержится приложение, в котором устанавливаются несовместимости между SQL/92 и SQL/89. Формально SQL/92 не включает в себя полностью SQL/89, т. е. некоторые конструкции SQL/89 не соответствуют стандарту SQL/92. Конечно, при переходе от SQL/89 к SQL/92 нужно внимательно отнестись к этим несоответствиям. Однако, во-первых, эти несоответствия являются слишком техническими и непринципиальными, чтобы описывать их в этой статье. Во-вторых, ни один производитель СУБД никогда не пойдет на то, чтобы с использованием его нового продукта перестали работать ранее разработанные прикладные системы. Поэтому можно быть почти уверенным (или уверенной), что в реализациях SQL/89 по-прежнему будет поддерживаться. Так что по поводу несоответствий мы отсылаем читателя к тексту стандарта SQL/92.
Предикат between
Предикат between имеет следующий синтаксис: ::=[NOT] BETWEEN AND
По определению результат "x BETWEEN y AND z" тот же самый, что результат логического выражения "x >= y AND x <= z". Результат "x NOT BETWEEN y AND z" тот же самый, что результат "NOT (x BETWEEN y AND z)".
Предикат in
Предикат in определяется следующими синтаксическими правилами: ::= [NOT] IN{ | ()} ::={,}...
Типы левого операнда и значений из списка правого операнда (напомним, что результирующая таблица подзапроса должна содержать ровно один столбец)должны быть сравнимыми. Значение предиката равно true в том и только в том случае, когда значение левого операнда совпадает хотя бы с одним значением списка правого операнда. Если список правого операнда пуст (так может быть, если правый операнд задается подзапросом) или значение "подразумеваемого" предиката сравнения x = y (где x - значение арифметического выражения левого операнда)равно false для каждого элемента y списка правого операнда, то значение предиката in равно false. В противном случае значение предиката in равно unknown (например, так может быть, если значение левого операнда есть NULL).По определению значение предиката "x NOT IN S" равно значению предиката "NOT (x IN S)".
Предикат like
Предикат like имеет следующий синтаксис: ::= [NOT] LIKE [ESCAPE ] ::= ::=
Типы данных столбца левого операнда и образца должны быть типами символьных строк. В разделе ESCAPE должен специфицироваться одиночный символ. Значение предиката равно true, если pattern является подстрокой заданного столбца. При этом если раздел ESCAPE отсутствует, то при сопоставлении шаблона со строкой производится специальная интерпретация двух символов шаблона: символ подчеркивания ("_") обозначает любой одиночный символ; символ процента ("%") обозначает последовательность произвольных символов произвольной длины (может быть, нулевой). Если же раздел ESCAPE присутствует и специфицирует некоторый одиночный символ x, то пары символов "x_" и "x%" представляют одиночные символы "_" и "%", соответственно. Значение предиката like есть unknown, если значение столбца либо шаблона не определено. Значение предиката "x NOT LIKE y ESCAPE z" совпадает со значением "NOT x LIKE y ESCAPE z".
Предикат null
Предикат null описывается синтаксическим правилом ::= IS [NOT] NULL
Этот предикат всегда принимает значения true или false. При этом значение "x IS NULL" равно true тогда и только тогда, когда значение х не определено. Значение предиката "x NOT IS NULL" равно значению "NOT x IS NULL".
Предикат с квантором
Предикат с квантором имеет следующий синтаксис: ::= ::= | ::= ALL ::= SOME | ANY
Обозначим через x результат вычисления арифметического выражения левой части предиката, а через S результат вычисления подзапроса. Предикат "x ALL S" имеет значение true, если S пусто или значение предиката "x s" равно true для каждого s, входящего в S. Предикат "x ALL S" имеет значение false, если значение предиката "x s" равно false хотя бы для одного s, входящего в S. В остальных случаях значение предиката "x ALL S" равно unknown. Предикат "x SOME S" имеет значение false, если S пусто или значение предиката "x s" равно false для каждого s, входящего в S. Предикат "x SOMES" имеет значение true, если значение предиката "x s" равно true хотя бы для одного s, входящего в S. В остальных случаях значение предиката "x SOME S" равно unknown.
Предикат exists
Предикат exists имеет следующий синтаксис: < exists predicate> ::=EXISTS
Значением этого предиката всегда является true или false, и это значение равно true тогда и только тогда, когда результат вычисления подзапроса не пуст.
Одной из проблем реализации языка
Одной из проблем реализации языка SQL всегда являлась проблема распознавания "изменяемости " соединений. как известно, если представление включает соединение общего вида, то теоретически невозможно определить, можно ли однозначно интерпретировать операции обновления такого представления. Однако существует несколько важных классов соединений, которые заведомо являются изменяемыми. В SQL-3 предполагается выделить эти классы с помощью специальных синтаксических конструкций. Наконец-то появляется возможность определения триггеров как комбинации спецификаций события и действия. Действие определяется как SQL-процедура, в которой могут использоваться как операторы SQL, так и ряд управляющих конструкций. На самом деле этот механизм очень близок к тому, который реализован в Oracle V. 7. Что касается управления транзакциями, то происходит возврат к старой идее System R о возможности установки внутри транзакции точек сохранения(savepoints). В операторе ROLLBACK можно указать идентификатор ранее установленной точки сохранения, и тогда будет произведен откат транзакции не к ее началу, а к этой точке сохранения. как видно, можно ожидать наличия в SQL-3 многих интересных и полезных возможностей. Однако даже промежуточные проекты стандарта включают почтив два раза больше страниц, чем стандарт SQL/92. Поэтому трудно ожидать быстрой реализации этого стандарта после его принятия (а многие вообще сомневаются, что этот стандарт будет когда-либо реализован).
Оператор получения описания подготовленного оператора
Оператор DESCRIBE предназначен для того, чтобы определить тип ранее подготовленного оператора, узнать количество и типы формальных параметров(если они есть) и количество и типы столбцов результирующей таблицы, если подготовленный оператор является оператором выборки (SELECT). Мы не приводим синтаксис оператора DESCRIBE, поскольку этот синтаксис мало что проясняет. Действие оператора DESCRIBE состоит в том, что в указанную область памяти прикладной программы (структура этой области фиксирована и известна пользователям)помещается информация, характеризующая ранее подготовленный оператор с заданным именем.
РАЗДЕЛ WHERE
Если в табличном выражении присутствует раздел WHERE, то далее вычисляется он. Синтаксис раздела WHERE следующий: ::=WHERE ::=| OR ::=| AND ::=[NOT]