1. Введение
2. Мотивация SQL/CLI
3. Обзор SQL/CLI
4. Итоги и перспективы
Библиография

1. Введение

В июле 1995 года американские и международные комитеты, ответственные за стандарт языка SQL, завершили работу над спецификацией нового стиля связывания, названного Call Level Interface (SQL/CLI - Интерфейс уровня вызовов) [2]. Этот новый стиль связывания является приложением к существующему стандарту SQL [1] и войдет как новая часть в следующую версию этого стандарта. В данной статье дается исчерпывающее представление об SQL/CLI и поясняется, почему он столь важен для современных приложений.

Статья состоит из четырех разделов. В разделе 2 приводится мотивация необходимости разработки нового стиля связывания и поясняется его соотношение с существующими стилями связывания. Обсуждается также история и эволюция SQL/CLI. В разделе 3 содержится обзор SCL/CLI, исследуются различные его аспекты и функциональные возможности. Наконец, раздел 4 подытоживает главные идеи данной статьи и представляет взгляд авторов на будущее.

2. Мотивация SQL/CLI

Стандарт SQL определяет подъязык данных, который используется в контексте другого языка, называемого включающим, для того, чтобы выполнять специализированные задачи управления базами данных. Такая взаимосвязь между включающим языком и подъязыком данных SQL называется стилем связывания.

2.1. Традиционные стили связывания

SQL-92 2) определяет три стиля связывания - Встроенный SQL (Embedded SQL), Модульный язык (Module Language) и Непосредственный вызов (Direct Invocaton). Далее кратко обсуждается каждый из них, однако внимание при этом фокусируется лишь на тех аспектах, которые необходимы для убедительной мотивации SQL/CLI. Заинтересованного читателя отсылаем к [1], где можно найти исчерпывающую информацию.

2.1.1. Встроенный SQL

Встроенный SQL, несомненно, является наиболее популярным из трех упомянутых выше традиционных стилей связывания. При этом методе операторы SQL непосредственно встраиваются в текст программы на включающем языке. Прежде чем можно будет компилировать код приложения, содержащий встроенный SQL, его следует подвергнуть прекомпиляции с использованием препроцессора, предоставляемого поставщиком данной СУБД. Препроцессор "расщепляет" код встроенного SQL на операторы SQL и операторы включающего языка. Затем результирующий исходный код компилируется и связывается обычным образом. Операторы SQL передаются для исполнения Системе Управления Базами Данных (СУБД) некоторым способом, который определяется реализацией.

Динамический SQL - это вариант встроенного SQL, который позволяет приложению конструировать операторы SQL на стадии исполнения. Однако сами эти динамические операторы выполняются с помощью операторов статического SQL - PREPARE (подготовить), EXECUTE (выполнить) и EXECUTE IMMEDIATE (выполнить непосредственно), встроенных во включающий язык и прекомпилируемых специальным препроцессором СУБД.

2.1.2. Модульный язык

В модульном языке все операторы SQL представляются в одном или более модулей (например единица компиляции в PL/1, объектный файл в "C" и т.д.). Каждый модуль содержит одну или более процедур; процедура имеет некоторое множество параметров и содержит какой-либо из операторов SQL. Каждая процедура может быть вызвана из других модулей в данном приложении. Модуль SQL записывается с использованием модульного языка, компилируется и ассоциируется с приложением с помощью некоторого механизма, определяемого конкретной СУБД.

2.1.3. Непосредственный вызов

Непосредственный вызов определяет множество операторов SQL, которые могут выполняться непосредственно. В непосредственном вызове каждый поставщик СУБД определяет метод вызова этих операторов, возвращения результатов, возникающие условия, а также способы доступа к диагностической информации.

2.2. Почему нужен новый стиль связывания?

2.2.1. Независимость от СУБД

В ранних системах баз данных приложения проектировались и реализовывались для того, чтобы выполнять привычные профессиональные функции. Такие приложения были тесно связаны с самой СУБД - и приложение, и СУБД часто функционировали на одной и той же машине.

В современном мире системы баз данных все более широко структурируются в соответствии с архитектурой "клиент-сервер"; приложения исполняются на машине клиента, а база данных функционирует на отдельной машине-сервере. Такая среда стимулировала разработку обобщенных приложений баз данных, для которых целевая база данных может быть неизвестной во время разработки приложения. Поскольку встроенный SQL требует использования препроцессора, зависящего от реализации, приложение, как минимум, придется перекомпилировать для каждой СУБД, с которой оно должно работать.

Подобным же образом модульный язык и непосредственный вызов опираются на определяемые СУБД механизмы для выполнения операторов SQL, и приложение, которое написано и скомпилировано для одной СУБД, не будет работать с какой-либо другой.

SQL/CLI обеспечивает независимость от СУБД благодаря тому, что он дает возможность разработки переносимых объектных модулей, выполняющих операции над базой данных с помощью вызовов функций. Такие вызовы функций реализуются в библиотеке стадии исполнения, которая называется реализацией CLI. Таким образом, не требуется никаких трансформаций исходного кода (таких как обработка препроцессором), зависящих от реализации.

2.2.2. Параллельная обработка

Во многих приложениях имеется необходимость выполнения параллельных операций, в том числе параллельных операций над базой данных. В связи с существованием областей глобальных данных как во встроенном SQL, так и в модульном языке, возникает вопрос относительно области действия и видимости (visibility) изменений таких данных параллельными операциями.

SQL/CLI устраняет области глобальных данных путем введения концепции указателя (handle). Указатель идентифицирует структуру данных, которая находится в реализации CLI. Все данные в реализации CLI, которые доступны приложению, ассоциируются с конкретным указателем. Параллельные операции над базой данных выполняются с использованием различных указателей.

2.2.3. Параллельная обработка множества транзакций

Традиционные стили связывания используют для разграничения транзакций операторы COMMIT (зафиксировать) и ROLLBACK (произвести откат). Транзакция начинается неявно, когда приложение инициирует операцию над базой данных. Такая модель хорошо работает в случае, когда активна единственная транзакция при единственном подключении (connection). Ее трудно обобщить на случай, когда приложение хочет иметь множество транзакций, активных на множестве подключений.

В SQL/CLI существует указатель среды, который обеспечивает глобальный контекст для доступа к базе данных. В среде может быть один или более указателей подключения, каждый из которых имеет отношение к какой-либо активной транзакции. Хотя существование множества активных транзакций в SQL/CLI зависит от реализации, разработанная модель может быть расширена таким образом, чтобы допустить такие функциональные возможности.

2.3. Эволюция SQL/CLI

В конце 80-х годов некоторые поставщики СУБД и приложений начали осознавать необходимость разработки способа доступа к неоднородным источникам данных. Многие поставщики располагали обобщенными приложениями, для которых требовался доступ более, чем к одному хранилищу данных. Хотя язык SQL был относительно переносимым и интероперабельным, разработчики приложений нуждались в такой модели, в которой бы не требовалась перекомпиляция приложения каждый раз, когда был необходим доступ к новому хранилищу данных.

К концу 1989 года компании Microsoft Corp., Lotus Development, Sybase и DEC совместно разработали спецификации, названные SQL Connectivity, в которых было определено некоторое множество функций для доступа к базам данных. Примерно в то же самое время был сформирован промышленный консорциум поставщиков в области баз данных SQL Access Group (SAG) с целью способствовать распространению интероперабельной модели для SQL. В июне 1990 года SAG принял спецификации SQL Connectivity в качестве базового документа для интерфейса уровня вызовов (Call Level Interface - CLI). В последующие два года SAG интенсивно работал над CLI и в конце 1992 года выпустил предварительные спецификации. Эти спецификации были приняты комитетами ANSI SQL и ISO DBL в качестве базовых документов по новому стилю связывания для SQL.

Тем временем компания Microsoft Corp. разработала инструментарий для разработки программного обеспечения (Software Development Kit - SDK), основанный на своей расширенной версии CLI и получивший название Open DataBase Connectivity (или ODBC). К 1993 году большое число поставщиков приложений и СУБД уже использовало инструментарий, предоставляемый в ODBC SDK, для реализации этой ранней версии CLI.

К концу 1994 года SAG влился в X/Open, и связанная с CLI деятельность стала осуществляться рабочей группой в X/Open. В апреле 1995 года был опубликован X/Open CLI. А в июле того же года SQL/CLI был одобрен как международный стандарт, официально названный "ISO/IEC 9075-3:1995, Information Technology - Database Languages - SQL - Part 3, Call Level Interface (SQL/CLI)". Публикация этого стандарта планировалась ISO на конец 1995 года.

3. Обзор SQL/CLI

SQL/CLI представляет собой множество функций, которые может использовать приложение для доступа к базам данных SQL. Оно содержит функции для запроса на выделение (allocating) и на отказ от выделения (deallocating) ресурсов, для подключения к SQL-серверам 3) и отключения от них, для исполнения операторов языка SQL, получения диагностической информации, управления завершением транзакций и получения информации о данной реализации.

3.1. Системная модель

Системная модель SQL/CLI состоит из трех компонентов - приложения, реализации CLI и SQL-сервера. Приложение производит вызовы функций, определяемых SQL/CLI. Реализация SQL/CLI - это библиотека стадии исполнения, которая реализует функции CLI и связывается (linked) с данным приложением. Реализация CLI обращается к SQL-серверу, который обрабатывает операторы SQL.

3.2. Типы аргументов

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

1. Входные аргументы - позволяют приложению передавать данные реализации CLI.

2. Выходные аргументы - позволяют реализации CLI возвращать данные приложению.

3. Входные аргументы с отсроченным присваиванием значений (Deffered Input argument) - используются для того, чтобы передавать значения динамическим параметрам в операторе SQL. Если функция вызывается с таким аргументом, реализация CLI сохраняет адрес этого аргумента, а выборку его значения производит в более позднее время.

4. Выходные аргументы с отсроченным присваиванием значений (Deffered Output argument) - используются для выборки значений столбцов таблицы. Реализация CLI производит запись значения в аргумент с отсроченным присваиванием в некоторый момент, иной, чем тот, когда вызывается данная функция.

3.3. Указатели и атрибуты

Указатель идентифицирует некоторую структуру данных в реализации CLI. В SQL/CLI имеется четыре типа указателей - указатель среды (environment handle), указатель подключения (connection handle), указатель оператора (statement handle) и указатель дескриптора (descriptor handle). Функция AllocHandle() используется для того, чтобы запросить назначение указателя какого-либо типа. Например, приведенный ниже вызов в "C" запрашивает указатель подключения:

SQLAllocHandle(SQL_HANDLE_DBC, EnvHandle, &ConnectionHandle);

Здесь первый аргумент задает тип желаемого указателя, второй аргумент - это указатель среды, в контексте которого должен запрашиваться желаемый указатель, а третий параметр - выходной параметр, через который реализация CLI будет возвращать запрашиваемый указатель подключения.

Среда является глобальным контекстом для доступа к базе данных. Она содержит любые данные, которые должны быть глобальными для всего приложения, например текущие значения атрибутов среды, которые определяют подключения, а также сведения о том, к какому подключению относится текущая информация.

Подключение представляет собой ассоциацию между приложением и SQL-сервером. С подключением ассоциируются любые данные, которые должны быть глобальными для этого подключения в целом, такие как информация о состоянии транзакций, определенные порции диагностической информации и текущие значения атрибутов подключения. Указатель подключения запрашивается в контексте среды. Приложение может быть подключено к нескольким SQL-серверам в одно и то же время и/или может быть установлено более одного подключения к одному и тому же SQL-серверу. Указатель оператора представляет состояние отдельного оператора SQL. С указателем оператора ассоциируется информация об исполнении данного оператора, в частности динамические параметры, текущие значения атрибутов оператора, результирующие значения и информация о состоянии. Указатель оператора запрашивается в контексте подключения, и подключение может иметь дело с одним или более операторов.

Дескриптор содержит информацию либо о столбцах, либо о динамических параметрах. Дескриптор CLI аналогичен области дескриптора SQL во встроенном SQL. Более подробно дескрипторы будут обсуждаться в разделе 3.8.

Среды, подключения и операторы характеризуются определенными атрибутами. Для установки значений атрибутов среды используется функция SetEnvAttr(), а для получения текущих значений атрибутов среды - функция GetEnvAttr(). Аналогичным целям для операций с атрибутами подключений служат функции SetConnectAttr() и GetConnectAttr(), а с атрибутами операторов - SetStmtAttr() и GetStmtAttr().

3.4. Осуществление подключения

Прежде чем установить подключение, приложение должно сначала запросить указатель среды, а затем запросить указатель подключения в контексте этой среды. Функция Connect() устанавливает подключение к SQL-серверу. Рассмотрим следующий вызов, сделанный в "C":

SQLConnect(ConnHandle,SvrName, Len1,UsrName,Len2,Auth,Len3)

Здесь ConnHandle - указатель подключения. Каждая функция SQL/CLI выполняется в контексте одного из четырех типов указателей, и этот указатель передается как входной аргумент. Далее, параметр SvrName - это строковый буфер, содержащий имя сервера, а Len1 задает длину этого буфера в октетах. Для параметра Len1 может быть установлено значение, равное мнемонической константе SQL_NTS (null terminated string). Такое значение показывает, что строка в SvrName завершается 0-символом. Вообще, любой строковый входной аргумент для какой-либо функции всегда имеет связанный с ним аргумент, который может содержать либо его фактическую длину, либо константу SQL_NTS, указывающую на завершение рассматриваемого значения 0-символом.

Параметр SvrName (имя сервера) обычно содержит какое-либо "дружественное имя", например "Payroll Database" (база данных платежных ведомостей) или "Accounts Database" (база данных счетов). Такое имя отображается в фактический физический адрес сервера способом, определенным реализацией. В результате приложение оказывается защищенным от сложностей, связанных с адресацией сетей и серверов. Параметры UsrName (имя пользователя) и Auth (аутентификация) предоставляют информацию, используемую для начала сеанса, с помощью которой SQL-сервер осуществляет аутентификацию пользователя. Параметры Len2 (длина-2) и Len3 (длина-3) задают длины этих буферов либо содержат значение SQL_NTS.

Приложение может запросить другой указатель подключения и вызвать функцию Connect() для того, чтобы установить второе подключение к тому же самому или иному SQL-серверу. Максимально возможное количество таких подключений определяется реализацией.

3.5. Выполнение операторов SQL

После того как подключение произведено, приложение запрашивает указатель оператора в контексте этого подключения. Как требует SQL/CLI, прежде, чем запрашивать указатель оператора, следует сначала установить подключение.

Операторы SQL могут выполняться одним из двух способов.

1. Вызов функции Prepare() с последующим вызовом Execute(). Для функции Prepare() нужно задать три аргумента: указатель оператора, строковый буфер, содержащий оператор, который должен быть подготовлен к выполнению, а также связанный с ним аргумент длины. Реализация CLI передает этот оператор SQL-серверу, который подготавливает его для выполнения. Далее приложение вызывает функцию Execute() с использованием того же указателя оператора, что и при вызове функции Prepare(), с тем, чтобы выполнить этот оператор. После подготовки данного оператора приложение может вызывать Execute() столько раз, сколько необходимо повторять его выполнение. Такой способ эквивалентен применению операторов PREPARE/ EXECUTE (подготовить/выполнить) во встроенном SQL.

2. Вызов функции ExecDirect(). Эта функция требует задания в качестве аргументов указателя оператора, самого оператора SQL, который должен быть выполнен, и его длины. Такой способ используется для однократного выполнения оператора. Он похож на метод EXECUTE IMMEDIATE (выполнить непосредственно) во встроенном SQL, за исключением того, что при этом становится возможной поддержка динамических параметров точно так же, как в модели Prepare/Execute.

Рассмотренные способы позволяют выполнять любые операторы SQL, которые могут быть подготовлены с использованием динамического SQL в том виде, как он специфицирован в SQL-92. К их числу относятся операторы: CREATE (создать), спецификации курсора, DELETE (удалить строку) с поиском, DELETE с динамическим позиционированием, DROP (уничтожить), GRANT (предоставить привилегию), INSERT (вставить), REVOKE (отменить привилегию), UPDATE (обновить) с поиском, UPDATE с динамическим позиционированием. Для операторов COMMIT (зафиксировать транзакцию) и ROLLBACK (выполнить откат) - специально исключена возможность выполнения с использованием CLI, поскольку имеются в распоряжении иные методы разграничения транзакций (см. разд. 3.11).

3.6. Параметризованное выполнение

Операторы, выполняемые с помощью SQL/CLI, могут содержать маркеры динамических параметров. Маркеры динамических параметров появляются как символы вопросительных знаков ("?") в тексте оператора, и реализация SQL/CLI подставляет вместо них во время исполнения текущие значения из ячеек памяти приложения. Такая взаимосвязь маркеров параметров с ячейками памяти приложения называется связыванием (binding) параметров. В качестве альтернативы связыванию параметров приложение может специфицировать параметрические данные во время исполнения, используя программу PutData().

Динамические параметры полезны для многократного выполнения отдельного подготовленного оператора с различными значениями параметров.

3.7. Модель курсора CLI

Достаточно часто операторы SQL возвращают от SQL-сервера множество строк. Традиционные языки программирования не имеют хорошего оснащения для того, чтобы оперировать такими множествами строк. Во встроенном SQL и в модульном языке для обеспечения решения этой задачи используется концепция курсора. Курсор представляет собой нечто подобное указателю (pointer), который позиционируется на заданной строке в возвращаемом множестве строк, называемом иногда результирующим набором (result set). Курсор перемещается по результирующему набору (или "прокручивает" его), давая возможность приложению осуществлять выборку по одной строке одновременно. Оператор SQL, который может генерировать результирующий набор, называется спецификацией курсора. Во встроенном SQL и модульном языке требуется, чтобы спецификация курсора выполнялась с помощью оператора OPEN (открыть), который открывает курсор, а не операторов EXECUTE или EXECUTE IMMEDIATE.

В SQL/CLI также используется концепция курсора. Однако, в отличие от встроенного SQL и модульного языка, спецификация курсора может выполняться здесь точно так же, как и другие операторы SQL - с помощью функций Prepare()/Execute() или ExecDirect(). При этом курсор автоматически открывается реализацией CLI. Функция Fetch() перемещает курсор в прямом направлении - каждый вызов Fetch() перемещает курсор на следующую строку в результирующем наборе.

По умолчанию курсор всегда будет вида "только вперед". Иными словами, он может перемещаться только в прямом направлении. Однако приложение может установить значение SQL_SCROLLABLE для атрибута SQL_ATTR_CURSOR_SCROLLABLE выполняемого оператора с тем, чтобы получить "прокручиваемый" (scrollable) курсор. В таком случае приложение имеет возможность перемещать курсор как в прямом, так и в обратном направлении. В SQL-92 требуется, чтобы "прокручиваемые" курсоры поддерживались на промежуточном уровне SQL [1]. Для перемещения курсора в любом направлении используется функция FetchScroll(). Аргументами этой функции являются указатель оператора, флаг, задающий направление перемещения, а также смещение. Совокупность аргументов флага и смещения определяет строку, на которой будет позиционироваться курсор после завершения выполнения функции. Если, например, заданы значение флага SQL_FETCH_RELATIVE и смещение 10, то курсор переместится на 10 строк вперед.

При ассоциировании областей памяти приложения со столбцами результирующего набора (которое принято называть связыванием столбцов), приложение может также осуществлять выборку строки в его буферы, в тех случаях, когда оно вызывает функции Fetch() или FetchScroll(). Этот и другие способы выборки значений столбцов результирующего набора более подробно рассматриваются в следующем разделе.

3.8. Области дескрипторов CLI

SQL/CLI предоставляет функции для доступа к областям дескрипторов, определенным в динамическом SQL. Такие области дескрипторов используются для описания динамических параметров и столбцов результирующего набора. Доступ к дескрипторам осуществляется с помощью указателей дескрипторов. Каждый дескриптор описывает одно из следующих.

1. Множество, состоящее из нуля или более динамических параметров. Существует два типа дескрипторов параметров:

  • дескриптор параметров приложения или APD (Application Parameter Descriptor), содержащий информацию о переменных приложения, которые поставляют значения динамических параметров;
  • дескриптор параметров реализации или IPD (Implementation Parameter Descriptor), который содержит информацию о тех же самых параметрах после любых специфицированных преобразований данных.
  • 2. Отдельную строку результирующих данных. Допускается два типа дескрипторов строк:

  • дескриптор строк реализации или IRD (Implementation Row Descriptor), который содержит описание некоторой строки из базы данных;
  • дескриптор строк приложения или ARD (Application Row Descriptor), содержащий описание той же самой строки после любого преобразования данных, которое могло быть специфицировано приложением базы данных.
  • Дескриптор представляет собой концептуальную таблицу с записью-заголовком и одной или более детализирующими записями. Запись-заголовок содержит поля, которые описывают таблицу в целом. Например, поле COUNT (счетчик) указывает количество имеющихся детализирующих записей. В случае ARD и IRD - это количество столбцов в результирующем наборе, а для APD и IPD - число динамических параметров.

    Каждая детализирующая запись описывает один столбец результирующего набора или один динамический параметр. В детализирующей записи имеется множество полей, и мы не будем здесь пытаться описать их все, ограничившись лишь рассмотрением некоторых из них. Заинтересованного читателя отсылаем к документу [2]. Поле TYPE (тип) - это целочисленное поле, содержащее код типа данных. В IRD это поле указывает тип данных соответствующего столбца на SQL-сервере. В случае ARD оно указывает тип данных буфера приложения, который будет содержать этот столбец. Специфицируя в ARD иной тип, приложение может выполнить преобразование данных. Подобным же образом поле TYPE для IPD содержит тип данных динамического параметра, когда он появляется на SQL-сервере. Приложение может специфицировать другое значение поля TYPE в APD, чтобы указать, что реализация CLI должна преобразовать данные перед тем, как произвести выполнение.

    Другие поля в детализирующей записи описывают динамический параметр или столбец результирующего набора более подробно. Так, например, поле LENGTH (длина) в IRD или IPD указывает максимальную длину в литерах строкового динамического параметра или столбца результирующего набора. В качестве значения поля OCTET_LENGTH (длина в октетах) в ARD устанавливается длина буфера, который связывается с некоторым столбцом.

    Области дескрипторов 4) содержат также три поля с отсроченным присваиванием значений (deferred fields) - DATA_PTR (указатель данных), INDICATOR_PTR (указатель индикатора) и OCTET_LENGTH_PTR (указатель длины в октетах). Если приложению нужно осуществить связывание с некоторым столбцом результирующего набора, оно устанавливает значение поля DATA_PTR в ARD, равное адресу переменной, которая должна будет содержать эти данные. Когда вызывается функция Fetch() или FetchScroll(), реализация CLI наполняет этот буфер данными столбца. Аналогичным образом приложение может установить в качестве значения поля DATA_PTR в APD-адрес буфера, который будет содержать данные этого параметра. Прежде чем вызвать Execute() или ExecDirect(), приложение наполняет этот буфер данными фактического параметра.

    Приложение устанавливает в качестве значения поля INDICATOR_PTR в ARD или APD-адрес той переменной, которая будет содержать индикаторную информацию. Индикаторная переменная используется для того, чтобы передавать и получать значение NULL SQL (неопределенное значение) от программ на включающих языках, которые могут не иметь представлений для строковых или числовых неопределенных значений. Далее, приложение устанавливает значение поля OCTET_LENGTH_PTR в ARD или APD, равное адресу переменной, которая будет содержать фактическое число октетов для столбца результирующего набора или динамического параметра.

    Когда запрашивается указатель оператора, реализация CLI автоматически выделяет четыре дескриптора - IRD, IPD, ARD и APD - и ассоциирует их с указателем оператора. Приложение может также вызвать функцию AllocHandle() для того, чтобы явно запросить дескриптор. Явно запрашиваемые дескрипторы могут быть ассоциированы как ARD или APD с указателем оператора с помощью функции SetSttAttr(). Значения дескрипторов IRD и IPD не могут быть изменены. Функция CopyDesc() копирует значения полей из одного дескриптора в другой.

    3.9. Комбинированные функции

    Операция связывания со столбцом результирующего набора с использованием функции SetDescField() требует получения указателя дескриптора и выполнения множества вызовов для того, чтобы установить значения индивидуальных полей дескриптора. Функция BindCol() специфицирует все эти значения для оператора без получения указателя дескриптора. Подобным же образом функция BindParam() в единственном вызове специфицирует множество полей дескриптора, ассоциируемых со связыванием параметров.

    Функции SetDescRec() и GetDescRec() устанавливают и получают значения множества полей дескриптора в единственном вызове, однако требуют задания указателя дескриптора.

    Следует отметить, что, хотя указанные комбинированные функции (concise function) являются полезными "стенограммами", они не являются расширяемыми. Причина заключается в том, что поля, которые они могут читать, являются жестко закодированными в их списках параметров. Вместе с тем функции GetDescField() и SetDescField() являются расширяемыми.

    3.10. Диагностика

    SQL/CLI обладает богатой диагностической моделью для обработки исключительных ситуаций. Каждая функция возвращает код завершения SQL_SUCCESS, если она была выполнена успешно. Если функция выполнена успешно, но были сгенерированы некоторые предупреждения (например в случае, когда функция Fetch() дает в результате данные в столбце, которые были усечены), то возвращается код завершения SQL_SUCCESS_WITH_INFO. Наконец, если при выполнении функции имела место ошибка, возвращается SQL_ERROR.

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

    Диагностическая область состоит из записи-заголовка и одной или более детализирующих записей. Запись-заголовок, в свою очередь, состоит из нескольких полей, которые служат для возвращения информации, такой, например, как код завершения рассматриваемой функции, количество детализирующих записей, а также количество строк, подвергнувшихся воздействию функций SQL Update (обновить) или Delete (удалить). Значения полей в записи-заголовке диагностической области доступны, независимо от того, каково значение кода завершения рассматриваемой функции.

    Если выполняемая функция возвращает значение кода SQL_SUCCESS_WITH_INFO или SQL_ERROR, то доступна дополнительная диагностическая информация, содержащаяся в одной или более детализирующих записей в связанной с этой операцией диагностической области. В каждой детализирующей записи имеется несколько полей, значениями которых являются 5-литерный код SQLSTAT 5) (состояние SQL), MESSAGE_TEXT (текст сообщения) и зависящий от реализации текст сообщения об ошибке или предупреждения.

    Программа приложения вызывает функцию GetDiagField() для того, чтобы прочитать значение конкретного поля в диагностической области, или функцию GetDiagRec() для чтения значений множества полей с помощью единственного вызова.

    3.11. Разграничение транзакций

    Когда приложение подключается к SQL-серверу и выполняет некоторую работу, неявным образом начинается транзакция. Приложение осуществляет фиксацию или откат транзакции, вызывая функцию EndTran(), которая оперирует указателем подключения. Возможность иметь более одного подключения, для каждого из которых имеется активная транзакция, определяется реализацией.

    4. Итоги и перспективы

    SQL/CLI определяет интерфейс программирования, который состоит из вызовов функций, используемых для выполнения работ с базой данных. Построение SQL/CLI на основе указателей (handles) исключает необходимость областей глобальных данных - приложение получает доступ ко всей информации через посредство указателей. Такой стиль связывания не нуждается в препроцессоре и, следовательно, дает возможность разрабатывать переносимые приложения.

    Рассматриваемый стиль связывания получил широкую индустриальную поддержку. Компания Microsoft Corp. объявила о своих планах создания новой версии ODBC, которая будет соответствовать стандарту SQL/CLI. Активно разрабатываются некоторые новые расширения для следующей версии SQL/CLI. К их числу относятся эффективное управление большими объектами данных с помощью локаторов (locators), а также усовершенствованная поддержка в CLI долговременно живущих хранимых модулей (persistent stored modules), которая обеспечивает выигрыш производительности за счет исключения необходимости перекомпиляции кода SQL.

    Библиография

    [1] IS 9075 International Standard for Database Language SQL, document ISO/IEC 9075:1992, эквивалентен документу American National Standard ANSI X3.135-1992, J.Melton, Editor. October 1992.

    [2] IS 9075-3 International Standard for Database Language SQL. - Part 3: Call Level Interface, document ISO/IEC 9075-3:1995, эквивалентен документу - American National Standard ANSI/ISO/IEC 9075-3:1995, J.Melton, Editor. Publication expected Fall 1995.


    1) SQL/CLI- A New Binding Style For SQL. Mirali Venkatrao, Microsoft Corp., e-mail: muraliv@microsoft.com Michael Pizzo, Microsoft Corp., e-mail: mikep@microsoft.com //SIGMOD Record, Vol.24, No.4, December 1995.- p.72-77.
    Переведено с разрешения АСМ.
    (с) 1996 АСМ.Inc

    2) Всюду в тексте данной статьи термин "SQL-92" следует рассматривать как ссылку на (идентичные) документы ANSI X3.135-1992 и ISO/IEC 9075:1992, "Database Language SQL".
    Перевод с англ. М.Р. Когаловского.

    3) В тексте данной статьи термин "SQL-сервер" используется для обозначения источника данных, для которого существует реализация CLI.

    4) Имеются в виду, вероятно, детализирующие записи областей дескрипторов. (Прим. пер.)

    5) Значениями SQLSTAT являются 5-литерные коды, которые обозначают стандартные ситуации ошибок/предупреждений. Эти коды определяются в SQL-92.