Стандарты языка реляционных баз данных SQL: краткий обзор - Набор операторов манипулирования данными
ОГЛАВЛЕНИЕ
2. 6 Набор операторов манипулирования данными
В стандарте SQL/89 определен очень ограниченный набор операторов манипулирования данными. Их можно классифицировать на группы операторов, связанных с курсором; одиночных операторов манипулирования данными; и операторов завершения транзакции. Все эти операторы можно использовать как в модулях SQL, так и во встроенном SQL. Заметим, что в SQL/89 не определен набор операторов интерактивного SQL (т. е. отсутствуют явные спецификации набора операторов SQL, которые могут задаваться в интерактивном режиме).
2. 6. 1 Операторы, связанные с курсором
Операторы этой группы объединяет то, что все они работают с некоторым курсором, объявление которого должно содержаться в том же модуле или программе со встроенным SQL. Если говорить неформально, курсор - это механизм языка SQL, предназначенный для того, чтобы позволить прикладной программе последовательно, строка за строкой, просмотреть результат связанного с курсором запроса.
2. 6. 1. 1 Оператор объявления курсора
Для удобства мы повторим здесь синтаксические правила объявления курсора, приведенные в подразделе 2. 3. 1:
<declare cursor> ::=
DECLARE <cursor name> CURSOR
FOR <cursor specification>
<cursor specification> ::=
<query expression> [<order by clause>. . . ]
<query expression> ::=
<query term>
| <query expression> UNION [ALL] <query term>
<query term> ::=
<query specification> | (<query expression>)
<order by clause> ::=
ORDER BY <sort specification>
[{, <sort specification>}. . . ]
<sort specification> ::=
{ <unsigned integer> | <column specification> }
[ASC | DESC]
В объявлении курсора могут задаваться запросы наиболее общего вида с возможностью выполнения операции UNION и сортировки конечного результата. Этот оператор не является выполняемым, он только связывает имя курсора со спецификацией курсора.
2. 6. 1. 2 Оператор открытия курсора
Оператор описывается следующим синтаксическим правилом:
<open statement> ::=
OPEN <cursor name>
В реализациях встроенного SQL обычно требуется, чтобы объявление курсора текстуально предшествовало оператору открытия курсора. Оператор открытия курсора должен быть первым в серии выполняемых операторов, связанных с заданным курсором. При выполнении этого оператора производится подготовка курсора к работе над ним. В частности, в этот момент производится связывание спецификации курсора со значениями переменных основного языка в случае встроенного SQL или параметров в случае модуля (это значит, что после выполнения оператора открытия курсора любые изменения переменных основной программные будут оказывать какие-либо действия на результат запроса, связанного с курсором).
В большинстве реализаций в случае встроенного SQL именно выполнение оператора открытия курсора приводит к компиляции спецификации курсора и подготовке выполняемого плана запроса. Можно считать (хотя фактически это делается далеко не всегда), что во время выполнения оператора открытия курсора производится построение временной таблицы, содержащей результат запроса, который связан с этим курсором.
Следующие операторы можно выполнять над открытым курсором в произвольном порядке.
2. 6. 1. 3 Оператор чтения очередной строки курсора
Синтаксис оператора чтения следующий:
<fetch statement> ::=
FETCH <cursor name> INTO <fetch target list>
<fetch target list> ::=
<target specification>[{, <target specification>}. . . ]
В операторе чтения указывается имя курсора и обязательный раздел INTO, содержащий список спецификаций назначения (список имен переменных основной программы в случае встроенного SQL или имен "выходных " параметров в случае модуля SQL). Число и типы данных в списке назначений должны совпадать с числом и типами данных списка выборки спецификации курсора.
Любой открытый курсор всегда имеет позицию: он может быть установлен перед некоторой строкой результирующей таблицы (перед первой строкой сразу после открытия курсора), на некоторую строку результата или за последней строкой результата.
Если таблица, на которую указывает курсор, является пустой, или курсор позиционирован на последнюю строку или за ней, то при выполнении оператора чтения курсор устанавливается в позицию после последней строки, параметру SQLCODE присваивается значение 100, ни какие значения не присваиваются целям, указанным в разделе INTO.
Если курсор установлен в позицию перед строкой, то при выполнении оператора чтения он устанавливается на эту строку, и значения строки присваиваются соответствующим целям.
Если курсор установлен на строку r, отличную от последней строки, то курсор устанавливается на строку, непосредственно следующую за строкой r (в порядке, определенном реализацией, если запрос не содержит раздела ORDER BY), и значения из этой следующей строки присваиваются соответствующим целям.
Возникает естественный вопрос, как им образом можно параметризовать курсор неопределенным значением или узнать, что выбранное из очередной строки значение является неопределенным. Это достигается в SQL/89 за счет использования так называемых индикаторных параметров и переменных. Если известно, что значение, передаваемое из основной программы СУБД или принимаемое основной программой от СУБД, может быть неопределенным, и этот факт интересует прикладного программиста, то спецификация параметра в операторе SQL имеет вид: <parametername>[INDICATOR]<parameter name>, а спецификация переменной -<embeddedvariable name> [INDICATOR] <embedded variable name>. Отрицательное значение индикаторного параметра или индикаторной переменной (они должны быть целого типа) соответствует неопределенному значению параметра или переменной.
2. 6. 1. 4 Оператор позиционного удаления
Синтаксис этого оператора следующий:
<delete statement: positioned> ::=
DELETE FROM <table name>
WHERE CURRENT OF <cursor name>
Если указанный в операторе курсор открыт и установлен на некоторую строку, и курсор определяет изменяемую таблицу, то текущая строка курсора удаляется, а он позиционируется перед следующей строкой. Таблица, указанная в разделе FROM оператора DELETE, должна быть таблицей, указанной в самом внешнем разделе FROM спецификации курсора.
2. 6. 1. 5 Оператор позиционной модификации
Оператор описывается следующими синтаксическими правилами:
<update statement: positioned> ::=
UPDATE <table name>
SET <set clause:positioned>
[{, <set clause:positioned>}. . . ]
WHERE CURRENT OF <cursor name>
<set clause: positioned> ::=
<object column:positioned> =
{ <value expression> | NULL }
<object column: positioned> ::= <column name>
Если указанный в операторе курсор открыт и установлен на некоторую строку и курсор определяет изменяемую таблицу, то текущая строка курсора модифицируется в соответствии с разделом SET. Позиция курсора не изменяется. Таблица, указанная в разделе FROM оператора DELETE, должна быть таблицей, указанной в самом внешнем разделе FROM спецификации курсора.
Замечание: требование указывать имя таблицы в операторах позиционного удаления и позиционной модификации является, очевидно, избыточным, поскольку до имени таблицы можно добраться через имя курсора. Единственной возможной причиной этой избыточности может быть упрощение реализации (хотя не очень понятно, что именно упрощается).
2. 6. 1. 6 Оператор закрытия курсора
Синтаксис этого оператора следующий:
<close statement>::=
CLOSE <cursor name>
Если к моменту выполнения этого оператора курсор находился в открытом состоянии, то оператор переводит курсор в закрытое состояние. После этого над курсором возможно выполнение только оператора OPEN.