ВЫПОЛНЕНИЕ ПРОСТЕЙШИХ SQL-ОПЕРАТОРОВ С ИСПОЛЬЗОВАНИЕМ СРЕДСТВ ODBC
Лабораторная работа 7
ВЫПОЛНЕНИЕ ПРОСТЕЙШИХ SQL-ОПЕРАТОРОВ С ИСПОЛЬЗОВАНИЕМ СРЕДСТВ ODBC.
Цель работы
Ознакомиться со структурой программ, использующие средства ODBC, реализовать и выполнить с использованием простейших функций ODBC запросы, связанные с модификацией таблиц.
Содержание работы и методические указания
к ее выполнению
Для выполнения работы необходимо
ознакомиться со структурой программы ODBC;
изучить функции выполнения подготовительных операций в ODBC-программе;
ознакомиться со средствами обработки ошибок в ODBC-программе;
изучить функции непосредственного и подготавливаемого выполнения SQL-операторов, передачи параметров;
настроить среду выполнения, разработать и отладить ODBC-программу.
1. Структура ODBC-программы и функции инициализации
Общая структура ODBC-программы имеет вид:
Идентификатор окружения каждого приложения ODBC описывается функцией SQLAllocEnv, который должен быть освобожден в конце приложения с помощью функции SQLFreeEnv. Тип идентификатора окружения HENV.
RETCODE SQLAllocEnv (env)
HENV env - указатель области хранения в памяти идентификатора окружения.
RETCODE SQLFreeEnv (env)
HENV env - имя идентификатора окружения, который должен быть освобожден.
Идентификатор соединения представляет собой соединение между источником данных и прикладной программой. Для каждого источника данных, с которым приложение предполагает соединиться должен быть назначен идентификатор соединения SQLAllocConnect и освобожден SQLFreeConnect. Приложение может соединиться с источником данных, используя SQLConnect и разъединиться, используя SQLDisconnect. Тип идентификатора соединения HDBC.
RETCODE SQLAllocConnect (env, dbc)
HENV env - указатель на идентификатор окружения прикладной программы.
HDBC dbc - указатель области хранения памяти для идентификатора соединения.
RETCODE SQLFreeConnect (dbc)
HDBC dbc - указатель области памяти для освобождаемого идентификатора соединения.
RETCODE SQLConnect(dbc, szDSN, sbDSN, szUID, sbUID, szAuthStr, cbAuthStr)
HDBC dbc - идентификатор соединения.
UCHAR szDSN - строка с именем источника данных, с которым прикладная программа собирается соединиться.
SWORD sbDSN - длина строки источника данных, если это имя имеет нулевое окончание, то этот параметр можно установить в SQL_NTS, который является константой ODBC и используется вместо длины параметра, если параметр содержит строку с нулевым окончанием.
UCHAR szUID - имя пользователя.
SWORD sbUID - длина имени пользователя или SQL_NTS.
UCHAR szAuthStr - пароль пользователя.
SWORD cbAuthStr - длина пароля.
RETCODE
SQLDisconnect (dbc)
HDBC dbc - идентификатор доступа для отсоединения.
Идентификатор оператора аналогичен идентификатору окружения или соединения за исключением того, что он ссылается на SQL-оператор. Идентификатор соединения может быть связан несколькими идентификаторами операторов, но каждый идентификатор оператора связан только со своим идентификатором соединения. Чтобы назначить идентификатор оператора, приложение вызывает функцию SQLAllocStmt, а для освобождения SQLFreeStmt. Тип идентификатора оператора HSTMT.
RETCODE
SQLAllocStmt (dbc, stmt)
HDBC dbc - идентификатор соединения.
HSTMT stmt - указатель области хранения в памяти для идентификатора оператора.
RETCODE
SQLFreeStmt (stmt, fOption)
HSTMT stmt -идентификатор оператора.
UWORD fOption - одна из следующих опций:
SQL_CLOSE - закрывает курсор, связанный с hstmt, (если он был определен) и отбрасывает все ожидаемые результаты. Прикладная программа может вновь открыть этот курсор позднее, вновь выполнить оператор SELECT с теми же самыми или другими значениями параметров. Если курсор не открыт, то эта опция не повлияет на программу.
SQL_DROP - освобождает hstmt, освобождает все ресурсы, связанные с ним, закрывает курсор, если он открыт, и отбрасывает все ожидаемые строки. Эта опция завершает все обращения к hstmt. hstmt обязательно должен быть переназначен для повторного использования. Эта опция освобождает все ресурсы, которые были определены с помощью функции
SQLFreeStmt.
SQL_UNBIND - освобождает все буферы столбцов, которые повторно используются функцией
SQLBindCol для данного идентификатора оператора.
SQL_RESET_PARAMS - освобождает все буферы параметров, которые были установлены функцией
SQLBindCol для данного идентификатора оператора.
2. Средства отслеживания ошибок
Для отслеживания ошибок в ODBC используется функция
SQLError, которая возвращает сообщение об ошибке при неудачном завершении какой-либо функции ODBC.
Каждая ODBC-функция возвращает RETCODE, который принимает одно из нижеследующих значений:
SQL_SUCCESS Операция выполнена без ошибки.;
SQL_SUCCESS_WITH_INFO Функция завершена, но при вызове SQLError указывает на ошибку. В большинстве случаев это возникает, когда значение, которое должно быть возвращено очень большого размера, чем это предусмотрено буфером прикладной программы;
SQL_ERROR Функция не была завершена из-за возникшей ошибки. При вызове SQLError можно будет получить больше информации о сложившейся ситуации;
SQL_INVALID_HANDLE Не правильно определен идентификатор окружения, соединения или оператора. Это часто случается, когда идентификатор используется после того, как он был освобожден или если был определен нулевой указатель;
SQL_NO_DATA_FOUND Больше нет подходящей информации. Фактически это не является ошибкой. Чаще всего такой статус возникает при использовании курсора, когда больше нет строк для его продвижения;
SQL_NEED_DATA Необходимы данные для параметра.
RETCODE
SQLError (henv, hdbc, hsmt, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, cbErrorMsg)
HENV henv - идентификатор окружения.
HDBC hdbc - идентификатор соединения.
HSTMT hsmt - идентификатор оператора.
UCHAR szSqlState - SQLSTATE в качестве строки завершения.
SDWORD pfNativeError - в этом параметре и будет возвращена ошибка, возникшая в СУБД, а также ее собственный код. Если соответствующего собственного кода ошибки не существует, то возвращается ноль.
UCHAR szErrorMsg - указатель на буфер, куда будет возвращен текст ошибки (строка с нулевым окончанием).
SWORD cbErrorMsgMax - максимальный размер вышеописанного буфера, должен быть меньше или равен SQL_MAX_MESSAGE_LENGTH-1.
SWORD cbErrorMsg
- сюда возвращается число байт, скопированных в буфер.
3. Непосредственное и подготавливаемое выполнение операторов SQL
Непосредственное выполнение используется в тех случаях, когда
SQL-операторы, которые должны быть выполнены, будут выполняться только один раз;
не требуется информации о результирующем множестве до выполнения оператора;
SQLExecDirect представляет собой самый быстрый способ запустить SQL-оператор при одноразовом выполнении.
RETCODE
SQLExecDirect (hstmt, szSqlStr, cbSqlStr)
HSTMT hstmt- идентификатор оператора.
UCHAR szSqlStr- строка с SQL-оператором.
SDWORD cbSqlStr - длина строки szSqlStr.
Подготавливаемое выполнение предпочтительнее использовать, когда необходима информация о результирующем множестве до выполнения оператора или когда требуется выполнить SQL-оператор более одного раза. Для этого необходимы две функции
SQLPrepare и
SQLExecute.
SQLPrepare подготавливает SQL-строку для выполнения:
RETCODE
SQLPrepare (hstmt, szSqlStr, cbSqlStr)
HSTMT hstmt
- идентификатор оператора
UCHAR szSqlStr- строка с SQL-оператором
SDWORD cbSqlStr - длина строки szSqlStr
SQLExecute выполняет подготовленный оператор:
RETCODE
SQLExecute(hstmt)
HSTMT hstmt
- идентификатор оператора
SQLPrepare и
SQLExecDirect отличаются тем, что при вызове
SQLPrepare оператор SQL в действительности не выполняется, вместо этого определяется путь доступа к данным источника данных. Использование подготавливаемого выполнения удобно для операторов, которые будут выполняться более одного раза. Так как путь доступа к данным уже определен, то выполнение может осуществляться несколько быстрее, чем при использовании
SQLExecDirect. Кроме того, каждый вызов
SQLExecute передает базе данных только идентификатор для планирования обращения, а не весь SQL-оператор.
4. Использование параметров при выполнении
Параметры используются при непосредственном и подготавливаемом выполнении.
Маркеры параметров определяются в SQL-операторах с помощью знаков "?". Например, SELECT n_post FROM s WHERE town=? или INSERT INTO p(name, town) VALUES (?,?). Для того, чтобы связать буфер с маркерами параметров, прикладная программа должна вызвать
SQLBindParameter:
RETCODE
SQLBindParameter (hsmt, ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, cbValueMax, pcValue)
HSTMT hsmt - идентификатор оператора, он должен быть точно тем же идентификатором оператора, с которым этот оператор подготавливается и выполняется.
UWORD ipar - номер параметра для связи. В операторе SQL операторы нумеруются слева направо, начиная с 1. Например, для следующего SQL-оператора используется три параметрических маркера :
INSERT INTO j (n_izd, name, town) VALUES (?,?,?).
Чтобы связать эти параметры,
SQLBindParameter вызывается три раза с ipar, установленным в 1, 2 и 3 соответственно.
SWORD fParamType - является типом параметра для связи и может принимать одно из трех значений: SQL_PARAM_INPUT, SQL_PARAM_INPUT_OUTPUT или SQL_PARAM_OUTPUT. SQL_PARAM_INPUT используется для процедур, использующих параметры ввода. SQL_PARAM_INPUT_OUTPUT маркирует параметр ввода/вывода в процедуре. SQL_PARAM_OUTPUT маркирует значение возврата или параметр вывода в процедуре.
SWORD fCType
- является С-типом данных для параметра. Это тип данных из которого необходимо конвертировать данные.
SWORD fSqlType - является ODBC типом данных для параметра. Это тип данных в которых конвертируются данные и он должен совпадать с SQL-типом столбца, соответствующего этому параметрическому маркеру.
UDWORD сbColDef - точность
столбца или выражения соответствующего маркера параметра.
SWORD ibScale - размер столбца или выражения соответствующего маркера параметра
PTR rgbValue - указатель буфера для данных параметра, который при вызове
SQLExecute или
SQLExecuteDirect содержит действительные значения параметра.
SDWORD сbValueMax - максимальная длина буфера rgbValue.
SDWORD pcbValue - указатель буфера для длины параметра.
Ниже приведены основные значения С- и SQL-типов параметров.
|
С-тип |
SQL-тип |
|
SQL_C_BINARY |
SQL_C_FLOAT |
SQL_BINARY |
SQL_DOUBLE |
|
SQL_C_BIT |
SQL_C_TIME |
SQL_BIT |
SQL_FLOAT |
|
SQL_C_CHAR |
SQL_C_DEFAULT |
SQL_CHAR |
SQL_INTEGER |
|
SQL_C_DATE |
SQL_C_SLONG |
SQL_DATE |
SQL_REAL |
|
SQL_C_DOUBLE |
SQL_C_SSHORT |
SQL_DECIMAL |
SQL_SMALLINT |
| |
|
SQL_TIME |
SQL_VARCHAR |
5. Настройка доступа к источнику данных
Настройка доступа к источнику данных включает:
редактирование файла .odbc.ini.;
определение переменной ODBCINI;
установка переменных окружения СУБД;
включение необходимых заголовочных файлов.
Для настройки источника данных, необходимо проверить находится ли системный текстовый файл
.odbc.ini в домашней директории пользователя и отредактировать его, настроив на требуемые источники данных.
В файле .odbc.ini должен быть под некоторым идентификатором описан требуемый источник данных, имя которого используется функцией
SQLConnect(), и далее должен присутствовать раздел с данным именем, в котором содержатся атрибуты, описывающие источник данных. Файл
.odbc.ini должен содержать имя источника данных, имя сервера баз данных, имя базы данных и другие атрибуты.
В переменной окружения ODBCINI необходимо указать полное имя системного файла
.odbc.ini из домашней директории. Сделать это можно, либо введя с консоли соответствующую команду, либо поместив эту команду в файл загрузки .login. Форма записи команды зависит от используемой программы Shell-интерпретатора.
Системные требования зависят от той СУБД, с которой работает пользователь. Например, при работе с СУБД Informix это обеспечивается переменными окружения, выставленными в файле
.cshrc в домашней директории пользователя.
Для получения доступа до ODBC-функций, в программе должен быть описан заголовочный файл sqlext.h. В файле sqltypes.h находятся описание типов данных используемых в ODBC.
Как и любой исходный файл, написанный на языке Си, файл с программой, вызывающей ODBC-функции, должен иметь расширение .с.
При компиляции необходимо подключить необходимые библиотеки, используемые в вызываемых функциях. Поскольку в этом случае командная строка принимает достаточно сложный вид, целесообразно на уровне системного администратора оформить командный файл, в котором подключаются необходимые библиотеки.
Последовательность выполнения лабораторной работы
Убедиться в наличии и заполненности базы данных поставщиков, деталей, изделий, поставок.
Разработать ODBC-программу для решения задачи 1 из соответствующего варианта с помощью функций непосредственного выполнения.
Разработать ODBC-программу для решения задачи 2 из соответствующего варианта с помощью функций подготавливаемого выполнения.
После выполнения лабораторной работы привести базу данных в исходное состояние.
Требования к разрабатываемой программе
Разрабатываемая программа должна удовлетворять следующим требованиям:
все используемые функции ODBC должны анализироваться на корректность кода возврата;
в программе должен быть предусмотрен вывод сообщений обо всех шагах ее выполнения, в том числе и о возможных ошибках;
при выполнении запросов должно быть предусмотрено использование параметров; параметры варианта задания должны быть введены в ходе выполнения программы и переданы в SQL-запрос;
при выполнении программы должна контролироваться целостность базы данных;
программа должна быть достаточно документирована.
Варианты заданий
Вариант 1
Из таблицы поставок удалить поставки при заданных параметрах номера поставщика (имени поставщика) и номера детали.
Увеличить рейтинг поставщика, выполнившего наибольшую поставку некоторой детали, на указанную величину.
Вариант 2
Удалить всех поставщиков из указанного города.
Изменить цвет самой тяжелой детали на указанный.
Вариант 3
Вставить поставщика с заданными параметрами.
Удалить самую легкую деталь.
Вариант 4
Удалить поставщика, выполнившего меньше всего поставок.
Изменить название детали указанного цвета и веса.
Вариант 5
Удалить изделие из заданного города.
В таблице поставок изменить номер поставщика при заданном номере детали и изделия.
Вариант 6
Увеличить рейтинг поставщика, выполнившего больший суммарный объем поставок, на указанную величину.
Вставить деталь с заданными параметрами.
Вариант 7
Изменить название и город детали с максимальным весом на указанные значения.
Удалить из таблицы поставок все поставки конкретного поставщика.
Вариант 8
Увеличить рейтинг поставщика, выполнившего большее число поставок, на указанную величину.
Увеличить вес деталей из Лондона на некоторую величину.
Контрольные вопросы
Какова структура ODBC-программы? Перечислите ее основные компоненты.
С помощью каких средств ODBC можно отследить наличие ошибки?
В каких случаях непосредственное выполнение операторов является наиболее эффективным?
Когда используется подготавливаемое выполнение?
Как описываются маркеры параметров, и какая для этого предусмотрена функция? Каким образом можно связать несколько параметров?
С помощью какого параметра можно освободить буферы всех столбцов?
Как описать доступ до необходимой базы данных?
С помощью какой функции описывается соединение с необходимым источником данных? Каковы ее параметры?