КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Создание приложений баз данных средствами ODBC
Различные СУБД представляют собственные API для взаимодействия с БД. Прикладные API включают наборы функций, обеспечивающие программиста разнообразными типами доступа к БД, такими как: подключение, выполнение операторов, выборка отдельных строк данных из результирующего множества запросов. Недостатком такого подхода является отсутствие универсальности – программа должна быть обработана предкомпилятором и связана с API, поставляемым в составе конкретной целевой СУБД. Чтобы упорядочить данный подход, фирма Microsoft разработала стандарт, получивший название Open Database Connectivity – (ODBC). Технология ODBC предусматривает использование единого интерфейса для доступа к смешанным базам данных SQL, причем SQL рассматривается как базовое стандартное средство доступа к данным. Данный интерфейс (который встраивается непосредственно в язык С) обеспечивает высокую степень универсальности, в результате чего одно и тоже приложение может получать доступ к данным, хранящимся в базах различных целевых СУБД, без необходимости внесения изменений в его программный текст. Таким образом, разработчики получили инструмент, позволяющий создавать и распространять приложения архитектуры “клиент - сервер”, способные работать с широким спектром различных целевых СУБД. Для связи приложения с любой выбранной пользователем целевой СУБД достаточно лишь иметь соответствующий ODBC – драйвер. Архитектура ODBC. Общая структура ODBC включает в себя следующие элементы: приложение, менеджер драйверов, драйверы баз данных, источники данных.(рис нарисовать)!. Приложение выполняет обработку данных и вызов функций библиотеки ODBC для отправки SQL – операторов в СУБД и выборки возвращаемой СУБД информации. Менеджер драйверов выполняет загрузку драйверов по требованию приложения. Представляет собой библиотеку DLL. Драйверы баз данных обрабатывают вызовы функций ODBC и направляют SQL – запросы в конкретные источники данных, а также возвращают полученные результаты приложению. При необходимости драйверы выполняют модификацию исходного запроса приложения с целью привидения его в соответствие синтаксическим требованиям целевой СУБД. От них не требуется собственной реализации тех возможностей, которые данная СУБД не поддерживает. Единственным исключением из этого правила являются драйверы для СУБД, не имеющих собственных ядер. В этом случае ядро СУБД, обеспечивающее хотя бы минимальную поддержку языка SQL, должно быть реализовано в самом драйвере. В свете вышесказанного для драйверов ODBC можно говорить об их уровнях соответствия SQL. Различают драйверы с минимальным уровнем поддержки SQL, основным и расширенным уровнями поддержки. Источники данныхсодержат те данные, доступ к которым необходим пользователю приложения. Данные сохраняются в базе данных, контролируемой целевой СУБД, операционной системой, а также сетевыми сервисами ОС. Коды возврата. Все функции ODBC возвращают коды, чтобы показать в каком состоянии выполнения находится та или иная функция. Код возврата или RETCODE указывает на то, был ли вызов функции ошибочным или нет не указывает точной причины возникновения той или иной ошибки. В таблице приведены коды возврата ODBC и их краткие описания. Таблица Коды возврата ODBC
Проверка кодов возврата может выполняться посредством макросов RETCODE_IS_FAILURE или RETCODE_IS_SUCCESSFUL. Данные макросы приведены ниже:
#define RETCODE_IS_FAILURE (x) ((x) = = SQL_ERROR || \ (x) = = SQL_INVALID_HANDLE || \ (x) = = SQL_STILL_EXECUTING)
#define RETCODE_IS_SUCCESSFULL(x) (!RETCODE_IS_FAILURE(x))
Для использования макросов в программах ODBC, необходимо применять переменные типа кодов возврата, т.е. типа RETCODE, например:
#include <sql.h> #include <windows.h> RETCODE rc; HENV henv; rc =SQLAllocEnv(&henv); if (RETCODE_IS_SUCCESSFULL(rc)) {операторы, выполняющиеся в случае истинности условия оператора if};
В приведенном примере переменная rc предназначена для определения кода возврата функции SQLAllocEnv(). Основной алгоритм программ ODBC. Основной алгоритм программ, использующих интерфейс ODBC, представлен на рисунке в виде блок-схемы алгоритма работы. Как видно из рисунка любая программа с использованием ODBC может быть разделена на три основные части: инициализация, обработка оператора SQL и завершение программы. Главной частью программы ODBC является обработка оператора SQL, которая в свою очередь может быть разбита на собственные составные части. В ODBC, так же как и в динамическом PL/SQL при обработке произвольного SQL-оператора, необходимо выполнять связывание параметров. Собственно связывание выполняет драйвер ODBC, однако программа посредством API-функций должна корректно указать какие данные “связываются” и как в процессе связывание их трактовать. Если выполняемая инструкция это запрос на извлечение информации из базы данных, программа должна указать, куда считывать строки результирующего множества оператора и считать их.
Рисунок Основной алгоритм использования ODBC в прикладных программах
Функции инициализации и завершения. Прежде чем прикладная программа сможет вызвать какую-либо из функций ODBC, она обязана выполнить инициализацию ODBC и установить окружение. ODBC использует окружение для отслеживания соединений с БД, установленного прикладной программой. В рамках одного окружения можно установить произвольное число соединений. Назначение окружения производится функцией ODBC SQLAllocEnv() и имеет следующий синтаксис:
RETCODE SQLAllocEnv (phenv) Описание параметра phenv приведено в таблице. Таблица Параметр SQLAllocEnv
Освобождение идентификатора окружения происходит при вызове функции SQLFreeEnv(), который производится в программе последним. Описание функции имеет следующий вид:
RETCODE SQLFreeEnv(phenv)
Здесь параметр phenv имеет тот же смысл, что и в функции назначения окружения, однако в данном случае – это не “назначаемый”, а “освобождаемый” идентификатор и в отличие от SQLAllocEnv является входным (аналог in в PL/SQL). Так же, как окружение прикладной программы представляется с помощью идентификатора окружения, идентификатор соединения представляет соединение между источником данных и прикладной программой. В отличие от окружения, идентификатор которого в программе один, идентификаторов соединения может назначаться несколько, для каждого источника данных, с которым прикладная программа предполагает соединиться. Назначение идентификаторов соединения производится посредством функции SQLAllocConnect(). Синтаксис следующий:
RETCODE SQLAllocConnect(henv, phdbc)
При вызове функция может возвращать: SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, SQL_INVALID_HANDLE. Параметры представлены в таблице:
Таблица Параметры SQLAllocConnect()
Менеджер драйверов распределяет память для соединения и возвращает идентификатор через phdbc. Парная для SQLAllocConnect() функция SQLFreeConnect() освобождает идентификатор доступа и возвращает все назначенные SQLAllocConnect() ресурсы (освобождает всю связанную с ним память):
RETCODE SQLFreeConnect(hdbc)
где параметр hdbc – входной параметр, представляющий освобождаемое соединение. Освобождение идентификатора соединения производится после разрыва соединения с источником данных ODBC на этапе завершения, когда необходимо освободить все ресурсы занятые прикладной программой. В случае необходимости соединения с очередным источником данных, назначенный ранее идентификатор можно использовать без каких-либо ограничений, однако после освобождения, идентификатор становится недействительным и не пригоден для соединения. В этом случае требуется выполнить его повторное назначение. На базовом уровне API поддерживается лишь одна функция соединения, хотя на расширенных уровнях их достаточно много. Рассмотрим функцию SQLConnect() базового уровня. SQLConnect() загружает драйвер и устанавливает соединение с источником данных. Идентификатор соединения ссылается на местоположение области хранения всей информации о соединении, включая его статус, состояние транзакции и информацию об ошибке. Синтаксис данной функции следующий:
RETCODE SQLConnect (hdbc, szDSN, sbDSN, szUID, sbUID, szAuthStr, cbAuthStr)
Таблица Параметры SQLConnect
Значение SQL_NTS (null terminated string) удобно использовать в случае задания строковых литералов либо указателей на таковые в качестве имен источника данных, пользователя и пароля. В синтаксисе языка С строкой-константой с автоматически выставляемым нулевым окончанием является, как известно последовательность символов взятая в парные двойные кавычки. Если источник данных не требует имени пользователя, то в функцию должны быть переданы либо нулевое значение, либо пустая строка (строка, состоящая лишь из нуль-терминатора), в качестве же размера указывается либо нулевое значение, либо SQL_NTS соответственно. То же самое касается и строки авторизации. Так для того, чтобы установить соединение с источником данных, требующим имя пользователя и пароль, вызов SQLConnect() может быть следующим:
RETCODE rc; //…промежуточные операторы rc =SQLConnect (hdbc, “RESTAURANTS”, SQL_NTS, “OWNER”, SQL_NTS, “ICE-CREAM”, SQL_NTS).
Разрыв соединения с источником данных выполняет вызов SQLDisconnect():
RETCODE SQLDisconnect (hdbc)
где hdbc – входной параметр функции, представляющий идентификатор доступа для отсоединения. Выполнение операторов. В данном разделе рассмотрим два набора функций: функции управления каталогом и выполнения SQL – операторов. Функции управления каталогом возвращают информацию из системного каталога источника данных: имена таблиц, столбцов, табличную статистику и т. д. Функции выполнения операторов включают в себя функции непосредственного и подготовленного выполнения и связывания параметров. Любая функция, которая имеет отношение к обработке или передаче SQL – оператора, требует в качестве параметра идентификатор оператора. Идентификатор оператора аналогичен идентификатору окружения или соединения за исключением того, что он ссылается на SQL – оператор. Идентификатор соединения может быть связан с несколькими идентификаторами операторов, но каждый идентификатор оператора связан только со своим идентификатором соединения. Назначение идентификатора оператора производится вызовом SQLAllocStmt(), которая выделяет область хранения в памяти для идентификатора оператора и связывает его с соединением, которое определяется собственным идентификатором. Синтаксис для SQLAllocStmt() имеет вид:
RETCODE SQLAllocStmt(hdbc, phstmt)
Таблица Описание параметров SQLAllocStmt()
Парная для SQLAllocStmt() функция SQLFreeStmt() выполняет следующие действия: - останавливает любые SQL – операторы, которые в данный момент обрабатываются и связаны с заданным идентификатором оператора, - закрывают любые открытые курсоры, которые имеют отношение к определенному идентификатору оператора, - отбрасывает ожидаемые результаты, - дополнительно, освобождает все ресурсы, связанные с определенным идентификатором оператора. Синтаксис SQLFreeStmt() имеет следующий вид:
RETCODE SQLFreeStmt (hstmt, fOption)
Таблица Функция SQLFreeStmt
Опция SQL_CLOSE отбрасывает неизвлечённые результаты и закрывает любые связанные с ними курсоры. Эта опция не влияет на соответствующие параметры, подготовленные операторы или соответствующие столбцы результата. SQL_DROP освобождает все ресурсы, связанные с идентификатором, закрывает курсор, если он открыт и отбрасывает все ожидаемые строки результирующего множества. Эта опция завершает все обращения к hstmt, так как после успешного вызова SQLFreeStmt с этим параметром, идентификатор становится недействительным. SQL_UNBIND освобождает (“отвязывает”) все буферы столбцов, связанные со столбцами результирующего множества запроса посредством SQLBindCol(). Описание данной функции приведено в разделе 2.5 данного методического пособия. SQL_RESET_PARAMS освобождает все буферы параметров с фактическими значениями, связанные с маркерами параметров строки запроса. Связывание формальных параметров запроса (маркеров) с буферами фактических значений производится функцией SQLBindParametr(), описание которой приводится ниже в данном разделе. Функции управления каталогом. Первая информация, которая может понадобиться прикладной программе для соединения с неизвестным источником данных – это информация о таблицах. ODBC-функция SQLTables возвращает список имен таблиц, которые содержит указанный источник данных. Используя идентификатор оператора, драйвер возвращает информацию в виде результирующего множества. Синтаксис SQLTables имеет вид:
RETCODE SQLTables (hstmt, szTableQualifier, sbTableQualifier, szTableOwner, sbTableOwner, szTableName, sbTableName, szTableType, sbTableType)
Таблица Описание параметров SQLTables
В образцах строк для поиска возможно использование символов-заменителей, так ‘%’ заменяет любую последовательность символов, а ‘-‘ – произвольный одиночный символ. Список типов таблиц для выбора может содержать следующие типы таблиц: ‘TABLE’,’VIEW’, ‘SYSTEM TABLE’, ‘ALIAS’ и некоторые таблицы. Представления (‘VIEW’) вообще-то не являются таблицами БД, но зачастую носят имя “виртуальных таблиц” в силу похожести использования для операторов извлечения. Если символ ‘%’ используется в каком-то из аргументов функции в качестве шаблона выбора, а все остальные аргументы шаблонов – пустые строки, то можно получить список всех квалификаторов, владельцев или таблиц для выбранного источника. При использовании такого способа вызова все столбцы в результирующем множестве, кроме одного, устанавливаются в NULL. Например, следующий вызов возвратит список всех таблиц и представлений:
rc=SQLTables (hstmt, “”, SQL_NTS, “”,SQL_NTS, “%”, SQL_NTS, “’TABLE’, ‘VIEW’”, SQL_NTS).
Результирующее множество функции SQLTables одно и тоже для любого её вызова и представлено в таблице. Таблица Результирующее множество SQLTables
Как только информация о таблицах получена, зачастую бывает необходимо получить информацию о столбцах интересующей таблицы. Чтобы выбрать эту информацию, программа должна вызвать SQLColumns(). При вызове драйвер, используя идентификатор оператора, возвращает эту информацию в результирующем множестве: Таблица Результирующее множество SQLColumns()
Столбцы DATA_TYPE и TYPE_NAME определяют тип данных по разному. DATA_TYPE является ODBC SQL – типом данных, а TYPE_NAME является специфическим типом данных источника. Один и тот же ODBC SQL –тип может иметь разные типы данных для каждого источника. Столбцы PRECISION и SCALE можно использовать в других функциях (например в функции SQLBindParameter). PRECISION определяет общее число цифр или максимальную длину, а SCALE определяет количество цифр справа от десятичной точки и используется для числовых столбцов. Синтаксис же функции следующий:
RETCODE SQLColumns (hstmt, szTableQualifier, sbTableQualifier, szTableOwner, sbTableOwner, szTableName, sbTableName, szColumnName, sbColumnName)
Таблица Описание параметров SQLColumns
Первые семь параметров общие для большинства функций работы с системным каталогом. Оставшиеся два специфичны для данной функции. Для приложений может оказаться оправданным возвращение всех таблиц баз данных посредством SQLTables, однако это не совсем справедливо по отношению к столбцам. В больших базах список всех столбцов по всем таблицам очень большой. Поэтому для прикладной программы важно тщательное использование параметров, ограничивающих результирующее множество. Непосредственное выполнение. Непосредственное выполнение целесообразно использовать в следующих случаях: - SQL – операторы, которые должны быть выполнены, выполняются только один раз; - не требуется информация о результирующем множестве до выполнения оператора. Непосредственное выполнение реализуется с помощью функции SQLExecDirect() и представляет наиболее быстрый способ запуска SQL – оператора при одноразовом выполнении. Синтаксис функции имеет вид:
RETCODE SQLExecDirect(hstmt, szSqlStr, sbSqlStr) Таблица Описание параметров SQLExecDirect()
Например, следующий вызов функции непосредственного выполнения будет возвращать все строки из таблицы STAFF:
rc=SQLExecDirect (hstmt, “ select * from staff”, SQL_NTS).
Подготавливаемое выполнение. Данный способ выполнения оператора предпочтителен в случае, если оператор предполагается выполнять несколько раз и требуется предварительная информация о результирующем множестве. Для подготавливаемого выполнения необходимы две функции: SQLPrepare() и SQLExecute(). SQLPrepare() подготавливает SQL – строку для выполнения. Синтаксис её ничем не отличается от синтаксиса SQLExecDirect(). Синтаксис SQLExecute() следующий:
RETCODE SQLExecute (hsmt) где HSMT – предварительно назначенный идентификатор оператора.
SQLPrepare() отличается от SQLExecDirect() тем, что при вызове SQLPrepare() оператор на самом деле не выполняется. Вместо этого определяется путь доступа к данным и информация о результирующем множестве становится доступной для использования. Так функции SQLNumResultCols() и SQLRowCount() при вызове возвращают количество столбцов и строк результирующего множества. Так как план выполнения оператора после его подготовки известен, то его выполнение может выполняться несколько быстрее, чем при использовании SQLExecDirect(). Кроме того, каждый вызов SQLExecute() передает базе данных только идентификатор, а не строку запроса, что может несколько снизить сетевой трафик. ИСПОЛЬЗОВАНИЕ ПАРАМЕТРОВ ПРИ ВЫПОЛНЕНИИ. Параметры могут использоваться как при непосредственном, так и при подготавливаемом выполнении. Маркеры параметров определяются в SQL – операторах с помощью символа ‘?’. Например: select * from staff where position =? или insert into staff (fname, lname, position) values (?,?,?). Маркеры параметров необходимо связать с областью хранения, из которой во время выполнения выбирается значение параметра. Чтобы связать параметры прикладная программа вызывает функцию SQLBindParameter(). Эта функция связывает буфер с маркером параметра в SQL – операторе.
RETCODE SQLBindParameter(hstmt, ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, cbValueMax, pcbValue)
Таблица Параметры функции SQLBindParameter()
В данной функции fCType – тип данных, из которых происходит конвертирование, fSqlType – тип данных в которые происходит конвертирование, и он должен совпадать с SQL – типом столбца, соответствующего этому параметрическому маркеру. SQL – тип данных столбца может быть получен с помощью SQLColumns(), cbColDef и ibScale являются точностью и размером столбца источника данных, информация о которых тоже может быть получена посредством SQLColumns(). Если fSqlType этого параметра является SQL_LONGVARBINARY или SQL_LONGVARCHAR, то cbColDef должен содержать длину значения параметра, который посылается вместо соответствующего столбца. Параметр rgbValue может быть либо параметром ввода, либо вывода, либо ввода – вывода в зависимости от значения в fParamType. Параметр cbValueMax используется только тогда, когда тип параметра является двоичным или символьным. В этом случае он определяет длину буфера rgbValue. Для типов фиксированной длины он игнорируется и вместо него используется длина С – типа данных. Параметр pcbValue – указатель буфера, в котором может содержаться одно из следующих значений: длина значения параметра в rgbValue, SQL_NTS, SQL_NULL_DATA, SQL_DATA_AT_EXEC или SQL_DEFAULT_PARAM. Если pcbValue определяет длину значения параметра, то он применяется только в случае, если тип параметра в fCType является двоичным или символьным. Для типов фиксированной длины он игнорируется (хотя и должен быть определен). SQL_DATA_AT_EXEC используется при передаче параметров во время выполнения. SQL_DEFAULT_PARAM применяется только при использовании процедур, сообщая процедуре, что лучше использовать значение по умолчанию. Для параметров, определяемых во время выполнения два аргумента функции SQLBindParameter() используются иначе, чем было описано ранее. Вместо передачи длины параметра в pcbValue, посылается значение SQL_DATA_AT_EXEC, что сообщает драйверу, что данные для маркера будут переданы во время выполнения оператора. Аргумент rgbValue также используется иначе, а именно вместо указания на связываемый буфер, он устанавливается в определенное прикладной программой значение, идентифицирующее параметр (например, его номер). Данное значение должно быть сохранено в программе, так как именно оно будет возвращаться при вызове SQLParamData(), сообщая программе какой именно параметр запрашивает данные. Описание параметров SQLParamData() приведено в таблице 30. Как и любая функция ODBC эта функция возвращает данные типа RETCODE.
Таблица Описание параметров SQLParamData()
Как только параметр, определяемый во время выполнения, будет связан, прикладная программа может выполнить SQL – оператор. Кодом возврата функции выполнения (SQLExecute() или SQLExecDirect()) будет SQL_NEED_DATA. Затем прикладная программа предоставляет необходимые данные с помощью функции SQLParamData() и SQLPutData(). Функция SQLPutData() позволяет передавать данные в качестве значений параметров во время выполнения оператора. Функция использует следующие аргументы: Таблица Описание параметров SQLPutData()
Сначала посредством rgbValue функция SQLBindParameter() идентифицирует параметр, для которого передаются данные. Например, если необходимо передавать значения двум параметрам, используя rgbValue можно установить значение 1 для первого параметра (его номер), а для второго установить значение 2. Если следующий за выполнением опреатора вызов SQLParamData() возвращает SQL_NEED_DATA, то в prgbValue возвращается указатель на параметр, требующий пересылки данных. По данному адресу возвращается идентификатор (номер) параметра, определенный посредством SQLBindParameter(). Требуемые данные затем посылаются порциями посредством SQLPutData(). После передачи последней порции данных необходимо сделать “контрольный” вызов SQLParamData(), чтобы проинформировать драйвер о последней порции данных для текущего параметра. Вызов SQLParamData() может вернуть номер следующего параметра оператора требующего данных. Вызовы SQLPutData() передают необходимые данные до последней порции. Если больше параметров требующих данных во время выполнения нет, то “контрольный” вызов SQLParamData() возвращает SQL_SUCCESS. На этом цикл передачи значений параметров заканчивается. В последующем примере демонстрируется возможности функций SQLBindParameter(), SQLParamData() и SQLPutData().
RETCODE UpdateBigCols (HSTMT hstmt) { RETCODE rc; SDWORD cbDataLen; // Подготовка оператора rc=SQLPrepare(hstmt, “insert into MEMOTABLE (MEMCOL, PICTURECOL) values (?,?)”, SQL_NTS); // Связывание параметров. Аргумент rgbValue определяет номер параметра if (RETCODE_IS_SUCCESSFULL(rc)) { rc=SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, 100000, 0, (SDWORD) 1, 0, &cbDataLen); } if (RETCODE_IS_SUCCESSFULL(rc)) { rc=SQLBindParameter (hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 100000, 0, (SDWORD) 2, 0, &cbDataLen); } cbDataLen=SQL_DATA_AT_EXEC; if (RETCODE_IS_SUCCESSFULL(rc)) { rc=SQLExecute(hstmt); } //Загрузка данными while (rc= = SQL_NEED_DATA) { SDWORD iWhatParam; UCHAR rgbData[500]; SDWORD cbData;
rc=SQLParamData (hstmt, &iWhatParam);
if (rc= = SQL_NEED_DATA) { switch (iWhatParam) case 1: do { GetMemoData(rgbData, cbData, sizeof (rgbData));
if (cbData!=0) { SQLPutData(hstmt, rgbData, cbData);
} } while (cbData!=0); break;
case 2: do { GetPictData(rgbData, cbData, sizeof (rgbData));
if (cbData!=0) { SQLPutData(hstmt, rgbData, cbData);
} } while (cbData!=0);
} } }
В приведенном примере предполагаются имеющимися функции пользовательские функции GetMemoData() и GetPictData(), размещающие порции данных в массиве rgbData, а cbData определяет количество оставшейся информации. Выборка результатов. Большинство описанных выше функций генерируют результат. Результат может быть либо результирующим множеством, либо числом строк, на которые воздействовал оператор. Результирующее множество представляет собой набор строк и столбцов, которые были определены SQL – оператором или функцией каталога. После создания, результирующее множество, тем не менее, располагается на сервере базы данных и требует извлечения прикладной программой клиента. Продвижение по строкам результирующего множества возможно посредством курсора. Курсор отмечает текущую позицию в результирующем множестве. Продвижение в пределах результирующего множества выполняется относительно позиции курсора. Курсор автоматически генерируется для каждого результирующего множества. Непосредственно после создания результирующего множества, курсор устанавливается перед первой строкой данных. Для продвижения курсора следует вызывать функцию SQLFetch(). Данная функция продвигает курсор вперед на одну строку до тех пор, пока он не будет установлен за последней строкой результирующего множества.
ВЫБОРКА ИНФОРМАЦИИ О РЕЗУЛЬТИРУЮЩЕМ МНОЖЕСТВЕ. Прежде чем выбрать данные из результирующего множества прикладной программе может понадобиться некоторая информация о нём. В ODBC существует несколько таких функций, в данном же пособии рассматриваются только две из них. Для определения числа столбцов, которые были возвращены с помощью подготовленного или выполненного оператора, прикладная программа выполняет функцию SQLNumResultCols(), которая имеет следующий синтаксис:
RETCODE SQLNumResultCols (hstmt, pccol)
Таблица Параметры SQLNumResultCols
Для возвращения числа строк, на которые воздействовал SQL – оператор, прикладная программа вызывает функцию SQLRowCount(). Данная функция возвращает число строк на которые воздействовал оператор update, insert или delete и имеет следующий синтаксис:
RETCODE SQLRowCount (hstmt, pcrow)
Таблица Параметры SQLRowCount()
БАЗОВЫЕ ФУНКЦИИ ВЫБОРКИ ДАННЫХ. Как только закончена выборка информации о результирующем множестве, можно приступать к выборке собственно результирующего множества. В ODBC существует две функции базового уровня для выборки результатов: SQLBindCol() и SQLFetch(). Функция SQLBindCol() определяет область хранения данных результирующего множества, а SQLFetch() осуществляет выборку данных в области хранения. Алгоритм программы, использующей эти функции для возвращения данных из всех строк результирующего множества, предполагает выполнение следующих шагов: 1. Вызов SQLBindCol() один раз для каждого столбца, который должен быть возвращен из результирующего множества, 2. Вызов SQLFetch() для перемещения курсора на следующую строку и возврата данных из связанных столбцов, 3. Повторение шага 2 до тех пор пока SQLFetch() не возвратит SQL_NO_DATA_FOUND. Это указывает на то, что был достигнут конец результирующего множества. Если результирующее множество является пустым, то SQL_NO_DATA_FOUND будет возвращен сразу же при первом вызове SQLFetch(). Функция SQLFetch() извлекает строку данных из результирующего множества для выполненного SQL – оператора. Драйвер возвращает данные для всех столбцов, которые были связаны для предварительного хранения данных с помощью функции SQLBindCol(). Синтаксис функции SQLFetch():
RETCODE SQLFetch (hstmt) Здесь HSTMT – идентификатор выполненного оператора.
Если необходимо определить область хранения данных результирующего множества, которые должны быть извлечены, то вызывается функция SQLBindCol(). Каждый столбец, который требуется выбрать, связывается с помощью отдельного вызова функции. Функция SQLBindCol() назначает область хранения в памяти и тип данных для столбца результирующего множества. Она определяет: - буфер хранения для получения содержимого столбца данных в результирующем множестве; - длину указанного буфера хранения; - область памяти для хранения длины столбца выборки; - преобразование типа данных. Синтаксис данной функции имеет следующий вид:
RETCODE SQLBindCol (hstmt, icol, fcType, rgbValue, cbValueMax, pcbValue)
Таблица Параметры функции SQLBindCol()
Приведем пример программы, использующей средства ODBC:
#include <sql.h> #include <stdio.h> #include <stdlib.h> #define MAX_STMT_LEN 100 main() { HENV henv; /*идентификатор среды*/ HDBC hdbc; /*идентификатор соединения*/ HSTMT hstmt; /*идентификатор оператора*/ RETCODE rc; /*код возврата*/ UCHAR selstmt [MAX_STMT_LEN] /*строка оператора*/ UCHAR address [30]; UCHAR tel_no [15]; UCHAR pos [25]; SDWORD address_len, tel_no_len, pos_len; SQLAllocEnv (&henv); SQLAllocConnect (henv, &hdbc);
rc=SQLConnect (hdbc, “drhome”, SQL_NTS, “student”, SQL_NTS, “student”, SQL_NTS); if (rc = = SQL_SUCCESS || rc = = SQL_SUCCESS_WITH_INFO) { SQLAllocStmt (hdbc,&hstmt); lstrcpy (selstmt, “ select address, tel_no, position from staff where lname = ‘Иванов’ and fname = ‘Иван’ ”); if (SQLExecDirect (hstmt, selstmt, SQL_NTS)!= SQL_SUCCESS) exit (-1); SQLBindCol (hstmt, 1, SQL_C_CHAR, address, (SDWORD)sizeof(address), address_len); SQLBindCol (hstmt, 2, SQL_C_CHAR, tel_no, (SDWORD)sizeof(tel_no), tel_no_len); SQLBindCol (hstmt, 3, SQL_C_CHAR, pos, (SDWORD)sizeof(pos), pos_len);
while(RETCODE_IS_SUCCESSFULL(rc)) { rc=SQLFetch (hstmt); if (RETCODE_IS_SUCCESSFULL(rc)) { /*…вывод возвращенных строк…*/ } } SQLFreeStmt (hstmt, SQL_DROP); SQLDisconnect (hdbc); } SQLFreeConnect (hdbc); SQLFreeEnv(henv); }
П одробный алгоритм использования ODBC в прикладных программах. О бобщенную блок-схему алгоритма использования ODBC в прикладных программах (рисунок) операторов SQL можно представить в виде, изображенном на рисунке.
Рисунок Блок схема обработки SQL-операторов в ODBC
Литература 1. Коннолли, Т. Базы данных: проектирование, реализация и сопровождение. Теория и практика / Т. Коннолли, К. Бегг. - 3 изд., перераб. - M.: Вильямс, 2003 -1440 с. 2. Кайт, Том. Oracle для профессионалов. В 2-х томах / Том Кайт; пер. с англ. – СПб.1: ООО «ДиаСофтЮП», 2005. – Ч. 1 – 672 с.; – Ч. 2 – 816 с. 3. Скотт, Урман. Oracle 8.i Новые возможности программирования на языке PL/SQL / Урман Скотт. - M.: Лори, 2001. - 680 с. 4. Скотт, Урман. Oracle Database 10g. Программирование на языке PL/SQL. / Урман Скотт, Рон Хардман, Майкл МакЛафлин. - M.: Лори, 2007. - 816 с. 5. Гринвальд,Рик. Oracle. Справочник. Пер. с англ. / Рик Гринвальд, Дэвид К. Крейнс – СПб: Символ-Плюс, 2005. – 976 с. 6. Кайт, Том. Oracle для профессионалов: архитектура, методики программирования и основные особенности версий 9i и 10g / Том Кайт; пер. с англ. – М.: Лори, 2008. – 848 с. 7. Кайт, Том. Эффективное проектирование приложений / Том Кайт; пер. с англ. – М.: Издательство "Лори", 2006. – 656 с. 8. Бобровски, С. Oracle 8.i Архитектура / С. Бобровски. - М.: Лори, 2001. - 224с.
Дата добавления: 2014-01-04; Просмотров: 983; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |