3.6. Манипулирование данными

Как и в языке SQL/89, в SQL/92 определены два набора операторов манипулирования данных. Операторы первого набора связаны с курсором, и для них осмысленно использование только в режиме встраивания в некоторый традиционный язык программирования. Операторы второго набора предназначены для индивидуального использования и могут применяться как в режиме встраивания, так и в интерактивном режиме. Общие идеи организации обоих наборов операторов манипулирования данными в SQL/92 не изменились, но их возможности существенно расширены. Поэтому в основном мы будем останавливаться на расширениях, не обсуждая подробно всю схему выполнения операторов.

3.6.1. Операторы, связанные с курсором

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

<declare cursor> ::=
       DECLARE <cursor name> [ INSENSITIVE ] [ SCROLL ] CURSOR
       FOR <cursor specification>
<cursor specification> ::=
       <query expression> [ <order by clause> ]
       [ <updatability clause> ]
<updatability clause> ::=
       FOR { READ ONLY | UPDATE [ OF <column name list> ] }
<order by clause> ::=
       ORDER BY <sort specification list>
<sort specification list> ::=
       <sort specification> [ { <comma> <sort specification> }... ]
<sort specification> ::=
       <sort key> [ <collate clause > ] [ <ordering specification> ]
<sort key> ::=
       <column name> <unsigned integer>
<ordering specification> ::= ASC DESC

Пояснения:

  1. Пусть T обозначает таблицу, получаемую при вычислении выражения запроса, которое входит в спецификацию курсора.
  2. Если раздел обновляемости курсора (updatabilityclause) не специфицирован, то
  3. Если T является обновляемой таблицей, то пусть TU обозначает базовую таблицу, на которой в конечном счете базируется вычисление выражения запроса.
  4. Если в спецификации сортировки содержится раздел задания порядка сортировки (collateclause), то столбец сортировки должен иметь тип данных символьных строк.
  5. Если специфицирован раздел обновляемости с FORUPDATE и явным или неявным указанием списка имен столбцов, то таблица T должна быть обновляемой, и спецификация курсора не должна содержать ключевого слова INSENSITIVE.
  6. Если раздел обновляемости с FORUPDATE без списка имен столбцов специфицирован или неявно подразумевается, то по умолчанию предполагается наличие списка имен столбцов, включающего имена каждого столбца TU.
  7. Если специфицирован раздел обновляемости с FORUPDATE со списком имен столбцов, каждое имя в этом списке должно быть именем столбца TU.
  8. Если T является обновляемой таблицей, то для каждой строки T, существует в точности одна соответствующая строка TU, из которой порождена эта строка T.
  9. Спецификация INSENSITIVE означает, что после открытия курсора изменения, производимые в той же транзакции над строками таблицы TU, не должны оказывать влияния на состояние таблицы T; спецификация SCROLL означает, что после открытия курсора разрешается произвольное изменение его позиции.

Оператор открытия курсора определяется следующим синтаксическим правилом:

<open statement> ::= OPEN <cursor name>

Пояснения:

  1. Пусть S обозначает спецификацию открываемого курсора.
  2. При выполнении оператора открытия курсора выполняются следующие действия:

Оператор выборки по курсору определяется следующими синтаксическими правилами:

<fetch statement> ::=
       FETCH [ [ <fetch orientation> ] FROM ]
       <cursor name> INTO <fetch target list>
<fetch orientation> ::=
       NEXT
       |PRIOR
       |FIRST
       |LAST { ABSOLUTE | RELATIVE } <simple value specification>
<fetch target list> ::=
       <target specification>
       [ { <comma> <target specification> }... ]

Пояснения:

  1. Если отсутствует указание ориентации чтения (fetchorientation), неявно предполагается наличие ориентации NEXT.
  2. Если неявная или явная ориентация отличается от NEXT, то в объявлении курсора должна присутствовать спецификация SCROLL.
  3. Если в указании ориентации чтения присутствует спецификация простого значения, то тип данных этого значения должен быть типом точных чисел с масштабом 0.
  4. Определим J следующим образом:
  5. Пусть Tt обозначает таблицу той же степени, что таблица T, соответствующая результату спецификации курсора; тогда
  6. Пусть N обозначает число строк в Tt. Если J положительно, то пусть K равняется J. Если J отрицательно, то пусть K равняется N+J+1. Если J равно нулю, и специфицировано ABSOLUTE, то пусть K равняется нулю; если же J равно нулю, и специфицировано RELATIVE, то пусть K равняется 1.
  7. Операция чтения выполняется следующим образом:

Оператор позиционного удаления имеет тот же синтаксис, что и соответствующий оператор языка SQL/89:

<delete statement: positioned> ::=
       DELETE FROM <table name>
       WHERE CURRENT OF <cursor name>

В принципе, оператор и выполняется так же, как предписано в SQL/89, однако в стандарте SQL/92 приводятся некоторые уточнения поведения оператора:

  1. Если текущая транзакция имеет режим доступа "только чтение" и таблица, из которой удаляется кортеж не является временной, то возбуждается исключительное условие.
  2. Текущая строка помечается для удаления.
  3. Если оказалось, что помечаемая строка уже помечена для удаления оператором поискового удаления или оператором позиционного удаления, связанным с другим курсором, или помечена для обновления оператором поисковой модификации или оператором позиционной модификации, связанным с другим курсором, то в условии завершения текущего оператора сообщается соответствующее предупреждение.
  4. Строка, помеченная для удаления, реально удаляется в конце выполнения оператора позиционного удаления до проверки каких-либо ограничений целостности.
  5. Если удаляется последний кортеж, то курсор устанавливается в позицию после последней строки; в противном случае курсор устанавливается в позицию перед следующей строкой.

Оператор позиционной модификации также мало отличается от соответствующего оператора SQL/89:

<update statement: positioned> ::=
       UPDATE <table name>
       SET <set clause list>
       WHERE CURRENT OF <cursor name>
<set clause list> ::=
       <set clause> [ { <comma> <set clause> }... ]
<set clause> ::=
       <object column> <equals operator> <update source>
<update source> ::=
       <value expression>
       |<null specification>
       |DEFAULT
<object column> ::= <column name>

Как и для оператора позиционного удаления, мы поясним только отличия и расширения по отношению к SQL/89:

  1. Изменения, производимые с использованием упорядоченного курсора, не должны затрагивать столбцы сортировки;
  2. Если текущая транзакция выполняется в режиме только чтения, возбуждается исключительное условие.
  3. Будем называть объектной строкой ту строку, из которой порождена текущая строка курсора.
  4. Если оказалось, что к моменту выполнения операции позиционного обновления объектная строка уже помечена для удаления некоторым поисковым оператором удаления или позиционным оператором удаления, связанным с другим курсором, или если она помечена для обновления некоторым поисковым оператором обновления или поисковым оператором обновления, связанным с другим курсором, генерируется условие завершения с соответствующим предупреждением.
  5. Ключевое слово DEFAULT в разделе SET означает, что в соответствующий столбец обновляемой таблицы должно быть помещено его значение по умолчанию.
  6. Выражение, вырабатывающее значение, в разделе SET вычисляется до обновления объектной строки; если это выражение содержит ссылку на столбец изменяемой таблицы, то это рассматривается как ссылка на значение столбца до его изменения.
  7. Курсор остается позиционированным на текущую строку.

Оператор закрытия курсора в SQL/92 имеет такие же синтаксис и семантику, что и соответствующий оператор языка SQL/89.

3.6.2. Одиночные операторы

Основной набор одиночных операторов манипулирования данными и смысл этих операторов в SQL/92 не изменился (или незначительно изменился) по сравнению с SQL/89.

Одиночный оператор выборки в SQL/92 имеет следующий синтаксис:

<select statement: single row> ::=
       SELECT [ <set quantifier> ] <select list>
       INTO <select target list>
       <table expression>
<select target list> ::=
       <target specification>
       [ { <comma> <target specification> }... ]

Смысл этого оператора, если не вдаваться в формализмы стандарта, ничем не отличается от смысла оператора одиночной выборки SQL/89: табличное выражение должно вырабатывать таблицу, состоящую ровно из одной строки, причем число столбцов в этой таблице должно совпадать с числом элементов в списке целей выборки (selecttargetlist).

Оператор поискового удаления строк имеет точно такой же синтаксис, что и в SQL/89:

<delete statement: searched> ::=
       DELETE FROM <table name>
       [ WHERE <search condition> ]

Как обычно, основные расширения касаются более мощных возможностей спецификации условия поиска. Кроме того:

  1. Если текущая транзакция выполняется в режиме только чтения, и таблица, из которой удаляются строки, не является временной, возбуждается исключительное условие.
  2. Пометка строк для удаления производится следующим образом:
  3. Как и в случае позиционных операторов обновления, если для некоторой строки обнаруживается, что она уже помечена для обновления (удаления или модификации) другим оператором (позиционным или поисковым), то в условии завершения оператора поискового удаления возвращается предупреждение.
  4. Все строки, помеченные для удаления, реально удаляются в конце оператора до проверки какого-либо ограничения целостности.
  5. Если не удалена ни одна строка, вырабатывается условие завершения "нет данных".

Оператор поисковой модификации обладает почти таким же синтаксисом, что и соответствующий оператор в SQL/89, если не считать некоторых расширений раздела SET (для полноты мы повторим здесь синтаксическое определение конструкции <setclauselist>):

<update statement: searched> ::=
       UPDATE <table name>
       SET <set clause list>
       [ WHERE <search condition> ]
<set clause list> ::=
       <set clause> [ { <comma> <set clause> }... ]
<set clause> ::=
       <object column> <equals operator> <update source>
<update source> ::=
       <value expression>
       | <null specification>
       | DEFAULT
<object column> ::= <column name>

И в этом случае основные расширения по сравнению с SQL/89 относятся к более мощным возможностям определения условия поиска. Другие расширения и уточнения затрагивают следующее:

  1. Если текущая транзакция выполняется в режиме только чтения и таблица, строки которой модифицируются, не является временной, то возбуждается исключительное условие.
  2. Пометка строк для модификации производится следующим образом:
  3. Как и в случае позиционных операторов обновления, если для некоторой строки обнаруживается, что она уже помечена для обновления (удаления или модификации) другим оператором (позиционным или поисковым), то в условии завершения оператора поисковой модификации возвращается предупреждение.
  4. Если набор объектных строк пуст, вырабатывается условие завершения "нет данных".

Синтаксис оператора вставки строк в SQL/92 на вид довольно значительно отличается от синтаксиса соответствующего оператора SQL/89, но это произошло главным образом за счет расширения конструкции выражения запроса:

<insert statement> ::=
       INSERT INTO <table name>
       <insert columns and source>
<insert columns and source> ::=
       [ <left paren> <insert column list> <right paren> ]
       <query expression>
       | DEFAULT VALUES
<insert column list> ::= <column name list>

Пояснения относительно расширений и уточнений:

  1. Если в разделе вставляемых столбцов и источников данных указано DEFAULTVALUES, то это эквивалентно заданию выражения запроса в форме VALUES(DEFAULT, . . .), где число элементов "DEFAULT" равно числу столбцов в таблице T, в которую заносится строка.
  2. Столбец, указанный в списке вставляемых столбцов, называется объектным.
  3. Если текущая транзакция выполняется в режиме только чтения и T не является временной таблицей, возбуждается исключительное условие.
  4. Выполнение оператора происходит так же, как это специфицировано в стандарте SQL/89.

Наконец, последним оператором, который в стандарте SQL/92 отнесен к набору операторов манипулирования данными (аналог в SQL/89 отсутствует), является оператор объявления временной таблицы. Реальное создание такой таблицы происходит при первом вызове какой-либо процедуры модуля, содержащего объявление. Объявляемая временная таблица видна только процедурам этого модуля. Синтаксис объявления следующий:

<temporary table declaration> ::=
       DECLARE LOCAL TEMPORARY TABLE <qualified local table name>
       <table element list>
       [ ON COMMIT { PRESERVE DELETE } ROWS ]
<qualified local table name> ::=
       MODULE <period> <local table name>

Пояснения:

  1. Объявляемая временная таблица существует в течение SQL-сессии. При завершении сессии такие таблицы уничтожаются путем выполнения неявного оператора DROPTABLE.
  2. Ссылки на объявляемую временную таблицу не должны появляться в определениях представлений.

3.7. Управление транзакциями

На неформальном уровне мы кратко обсудили возможности управления транзакциями, поддерживаемые в стандарте SQL/92, в п.3.1.4. В этом разделе будут приведены синтаксические определения операторов управления транзакциями и соответствующие пояснения.

3.7.1. Оператор установки параметров транзакции

Оператор SETTRANSACTION служит для задания параметров следующей транзакции для данного SQL-агента. Оператор определяется следующими синтаксическими правилами:

<set transaction statement> ::=
       SET TRANSACTION <transaction mode>
       [ { <comma> <transaction mode> }... ]
<transaction mode> ::=
        <isolation level>
        | <transaction access mode>
        | <diagnostics size>
<isolation level> ::=
       ISOLATION LEVEL <level of isolation>
<level of isolation> ::=
       READ UNCOMMITTED
       | READ COMMITTED
       | REPEATABLE READ
       | SERIALIZABLE
<transaction access mode> ::=
       READ ONLY
       | READ WRITE
<diagnostics size> ::=
       DIAGNOSTICS SIZE <number of conditions>
<number of conditions> ::= <simple value specification>

Пояснения:

  1. Если уровень изоляции не специфицирован, то неявно полагается заданным уровень изоляции SERIALIZABLE.
  2. Если специфицирован режим доступа READWRITE, то уровень изоляции не должен быть READUNCOMMITTED.
  3. Если неспецифицирован режим доступа транзакции и указан уровень изоляции READUNCOMMITTED, то неявно полагается заданным режим доступа READONLY; в противном случае неявно полагается заданным режим доступа READWRITE.
  4. Попытка выполнения оператора SETTRANSACTION в активной транзакции приводит к возбуждению исключительной ситуации.
  5. Пусть TXN обозначает следующую транзакцию данного SQL-агента.
  6. Режим доступа TXN устанавливается в соответствии со спецификациями, заданными в операторе SETTRANSACTION.
  7. Уровень изоляции TXN устанавливается в зависимости от реализации, но таким образом, чтобы не проявлялись эффекты, которые не должны проявляться на уровне изоляции, явно или неявно задаваемом оператором SETTRANSACTION.
  8. Размер области диагностики TXN устанавливается в соответствии с параметром <numberofconditions>, если он задан; в противном случае размер области диагностики зависит от реализации, но должен быть не меньше того, который был бы выделен при явном задании числа условий равного единице.

3.7.2. Оператор установки режима ограничений

При выполнении в активной транзакции оператор устанавливает режим проверки ограничений целостности для этой транзакции в текущей SQL-сессии. При выполнении вне активной транзакции оператор устанавливает режим проверки ограничений целостности для следующей транзакции данного агента в текущей сессии. Оператор имеет следующий синтаксис:

<set constraints mode statement> ::=
       SET CONSTRAINTS <constraint name list>
       { DEFERRED | IMMEDIATE }
<constraint name list> ::=
       ALL
       | <constraint name> [ { <comma> <constraint name> }... ]

Пояснения:

  1. Указанные в параметрах оператора ограничения должны быть откладываемыми.
  2. Пусть TXN обозначает текущую или следующую транзакцию данного агента в зависимости от того, в транзакции или вне транзакции выполняется оператор.
  3. Если в операторе SETCONSTRAINTS указано IMMEDIATE, то
  4. Если указано DEFERRED, то

3.7.3. Оператор фиксации транзакции

Синтаксически оператор фиксации транзакции имеет ту же форму, что и аналогичный оператор в языке SQL/89:

<commit statement> ::= COMMIT [ WORK ]

В дополнение к функциональности оператора COMMITSQL/89 по поводу оператора COMMITSQL/92 следует сделать следующие пояснения:

  1. Для каждой временной таблицы T в каждом модуле, ассоциированном с текущей транзакцией, если для таблицы было указано ONCOMMITDELETE, и эта таблица обновлялась при выполнении текущей транзакции, в течении фиксации транзакции выполняется неявный оператор DELETEFROMT.
  2. Проверяются все ранее отложенные ограничения целостности, и если хотя бы одно из них не удовлетворяется, все изменения данных или схемы ликвидируются, и вырабатывается исключительное условие: "откат транзакции по причине нарушения ограничений".
  3. Иначе, изменения, произведенные текущей транзакцией над данными и/или схемой становятся доступными другим транзакциям, и текущая транзакция завершается.

3.7.4. Оператор отката транзакции

Оператор имеет тот же синтаксис и тот же смысл, что и соответствующий оператор SQL/89:

<rollback statement> ::= ROLLBACK [ WORK ]

Дополнительные пояснения не требуются.

Назад | Содержание | Вперед