Прямой вызов операторов SQL
Как мы уже упоминали, в стандарте SQL/92 специфицирован набор операторов, которые могут вызываться напрямую не будучи встроены в модуль или программу на языке программирования. Обычно прямой вызов производится с помощью некоторой утилиты СУБД, обеспечивающей возможности интерактивного ввода и редактирования SQL-операторов и отображение результатов на экран терминала. Наиболее естественным способом написания такой утилиты является использование динамического SQL.
Набор прямо вызываемых операторов определяется следующими синтаксическими правилами:
<direct SQL statement> ::= <directly executable statement> <semicolon> <directly executable statement> ::= <direct SQL data statement> | <SQL schema statement> | <SQL transaction statement> | <SQL connection statement> | <SQL session statement> | <direct implementation-defined statement> <direct SQL data statement> ::= <delete statement: searched> | <direct select statement: multiple rows> | <insert statement> | <update statement: searched> | <temporary table declaration> <direct implementation-defined statement> ::= См. пояснения ниже
Пояснения:
Прямые операторы манипулирования данными (directSQLdatastatement) не должны содержать спецификацию параметров, спецификацию динамических параметров и спецификацию переменных. Спецификация значения, представляющего неопределенное значение, определяется в реализации. Синтаксические правила для прямых операторов, определяемых в реализации, (directimplementation-definedstatement) определяются в реализации. Инициирующими транзакцию являются следующие прямые операторы SQL:
(a) операторы, являющиеся инициирующими транзакцию операторами, которые могут входить в SQL-процедуру;
(b) прямой оператор выборки, возвращающий несколько строк (directselectstatement: multiplerows);
(c) инициирующий транзакцию прямой оператор, определяемый в реализации.
После последнего вызова оператора SQLSQL-агентом в SQL-сессии происходит следующее:
(a) выполняется оператор ROLLBACK или оператор COMMIT; если возникает невосстанавливаемая ошибка или если прямой вызов SQL завершается непредусмотренным образом (это определяется в реализации), или если не удовлетворяется некоторое ограничение, то выполняется оператор ROLLBACK; в противном случае выбор между выполнением операторов ROLLBACK и COMMIT определяется в реализации;
(b) пусть D - имя дескриптора в некоторой области дескрипторов, который выделен в пределах текущей сессии; тогда выполняется следующий оператор: DEALLOCATEDESCRIPTORD;
(c) все SQL-сессии, связанные с данным SQL-агентом, завершаются.
Пусть S обозначает прямой оператор SQL. Текущим идентификатором авторизации для выполнения S является идентификатор авторизации SQL-сессии. При вызове SSQL-агентом происходит следующее:
(a) если S - это оператор подключения, то
(i) очищается область диагностики;
(ii) S выполняется;
(iii) если оператор S успешно инициировал или возобновил SQL-сессию, то последующие вызовы операторов прямого SQL данным SQL-агентом связываются с этой сессией, пока SQL-агент не завершит ее или не сделает потенциальной;
(b) в противном случае:
(i) если для SQL-агента не существует текущая SQL-сессия, то:
(*) если SQL-агент не выполнял оператора подключения и с ним не связана SQL-сессия по умолчанию, то выполняется следующий оператор подключения: CONNECTTODEFAULT;
(**) если SQL-агент не выполнял оператора подключения и с ним связана SQL-сессия по умолчанию, то выполняется следующий оператор установки подключения: SETCONNECTIONDEFAULT;
(***) в противном случае возникает исключительное условие;
(ii) если для данного SQL-агента существует активная транзакция, то S связывается с этой транзакцией SQL-transaction; если S - прямой оператор SQL, определяемый в реализации, то в реализации же определяется, может ли S ассоциироваться с текущей транзакцией, если не может, то возбуждается исключительное условие;
(iii) если для данного SQL-агента не существует активной транзакции, то
(*) если S является инициирующим транзакцию оператором, то инициируется SQL-транзакция;
(**) если S является прямым оператором, определяемым в реализации, то в реализации же определяется, инициирует ли S транзакцию; если инициирует, то инициируется SQL-транзакция.
(***) если оператор S инициировал транзакцию, то пусть T обозначает эту транзакцию; тогда:
(****) T ассоциируется с данным вызовом и со всеми последующими вызовами прямых операторов SQL и процедур, производимых данным SQL-агентом, до тех пор, пока этот агент не завершит T;
(*****) если после завершения последней транзакции в данной SQL-сессии был выполнен оператор установки параметров транзакции, то режим доступа, режим проверки ограничений и уровень изоляции T устанавливаются в соответствии с заданными параметрами;
(******) в противном случае для T устанавливается режим доступа "чтение-запись", режим проверки ограничений "немедленный" и уровень изоляции;
(*******) T ассоциируется с текущей SQL-сессией;
(iv) область диагностики очищается;
(v) S выполняется.
Если в одной транзакции происходит вызов прямого оператора манипулирования данными и оператора манипулирования схемой и это не допускается реализацией, возбуждается исключительное условие. Если выполнение S завершилось успешно, то вырабатывается условие завершения "успешное выполнение", либо "предупреждение", либо "нет данных". Если выполнение S завершилось неуспешно, то все изменения, произведенные S над данными или над схемой, ликвидируются, и возбуждается исключительное условие. Диагностическая информация по поводу выполнения S помещается в область диагностики; способ доступа к диагностической информации определяется в реализации, но в любом случае содержимое области диагностики не меняется.
Как видно из синтаксических правил, определяющих набор прямых операторов SQL, в состав этого набора входит специальный оператор выборки, не употребляемый в других контекстах и потому не рассмотренный нами ранее. Синтаксис этого оператора следующий:
<direct select statement: multiple rows> ::= <query expression> [ <order by clause> ]
Пояснения:
Как видно, синтаксис этого оператора очень напоминает синтаксис спецификации курсора: отсутствует только раздел изменяемости (updatabilityclause). Однако, поскольку это прямой оператор, то в его выражении запроса и разделе сортировки не должны содержаться спецификации значений, отличные от литералов, CURRENT_USER, SESSION_USER и SYSTEM_USER. Пусть Q обозначает результат вычисления выражения запроса. Если Q пусто, то вырабатывается условие завершения оператора "нет данных". Если оператор не содержит раздела сортировки, то порядок строк в Q зависит от реализации; иначе порядок строк устанавливается в соответствии с параметрами раздела сортировки. Если Q непусто, то возвращается оператором, причем используемый способ возврата определяется в реализации.
Все публикации раздела