Программирование >>  Sql: полное руководство 

1 ... 172 173 174 [ 175 ] 176 177 178 ... 264


/* Эта программа выводит список служащих, у которых

фактический объем продаж превьаиает план */ tinclude <sqlcli.h> /♦ файл с объявлениями структур и функций CLI */

main О

SQLHENV

env hdl;

дескриптор среды SQL */

SQLHDBC

conn hdl;

дескриптор сеанса подключения */

SQLHSTMT

stmt hdl;

дескриптор инструкции */

SQLRETURN

status;

код, возвращаемый функцией CLI */

char

*svr name =

demo

/*

имя сервера */

char

*user name =

]oe ;

имя пользователя для подключения */

char

*user pswd =

xyz ;

пароль для подключения */

char

repname[16];

имя служащего */

float

repquota;

плановый объем продаж */

float

repsales;

фактический объем продаж */

long

repquota ind.

индикатор значения NULL

для планового объема продаж */

Char

stmt buf[128]

буфер для инструкции SQL */

/* Получаем необходимые дескрипторы и подключаемся к базе данных */ SQLAllocHandle(SQL HANDLE ENV, SQL NULL HANDLE, &env hdl); SQLAllocHandle(SQL HANDLE DBC, env hdl, Sconn hdl>; SQLAllocHandle (SQL HANDLE STMT, conn hdl, Sst!nt hdl); SQLConnect(conn hdl, svr name, SQL NTS,

user name, SQL NTS,

user pswd, SQL NTS);

/* Запрашиваем выполнение инструкции SQL */

strcpy(stmt buf, select name, quota, sales from salesreps ); strcat(stmt buf, where sales > quota order by name ); SQLExecDirect(stmt hdl, stmt buf, SQL NTS);

/* Связываем извлекаемые столбцы с программными буферами */ SQLBindCol(stmt hdl, 1, SQL C CHAR, repname, 15, NULL); SQLBindCol(stmt hdl, 2, SQL C FLOAT, Srepquota, 0, Srepquota ind] ; SQLBindCol(stmt hdl, 3, SQL C FLoAT, Srepsales, 0, NULL);

/* Цикл обработки результатов запроса for ( ; , )

/ * Извлекаем следующую строку из таблицы результатов запроса */ if (SQLFetch(stmt hdl) = SQL SUCCESS) break;

/* Отображаем полученные данные */ printf( Имя: %s\n , repname); if (repquota ind < 0)

printf( План не назначен.\n >; else

printf( План: %f\n , repquota); printf( Объем продаж: if\n , repsales);

/* Отключаемся от сервера, освобождаем дескрипторы

и выходим из программы */ SQLDisconnect(conn hdl);

SQLFreeHandle(SQL HANDLE STMT, stmt hdl>;

SQLFreeHandle(SQL HANDLE DBC, conn hdl);

SQLFreeHandle(SQL HANDLE ENV, env hdl); exit (0);

jpoca ci



с помощью функций, приведенных на рис. 19.17, можно реализовать альтернативный способ получения результатов запроса, который заключается в следующем. Столбцы в таблице результатов запроса не привязываются заранее к программным буферам. Вместо этого функция SQLFetchO просто перемещает указатель набора записей к следующей строке таблицы, но данные в буферы не заносятся. Чтобы их по:тучить, нужно вызвать другую функцию - SQLGetData (). Один из параметров этой функции определяет, какой столбец требуется получить. Остальные задают тип возвращаемых данных и адрес буфера, в который их нужно записать, а также адрес сопутствующего буфера для записи длины полученных данных или индикатора значения NULL.

В принципе, функция SQLGetData () дает тот же результат, что и связывание столбцов с программными буферами с помощью функции SQLBindCol (). Однако при работе с большими элементами данных у этого метода есть важное преимущество. Некоторые СУБД позволяют определять столбцы, которые могут содержать тысячи или даже миллионы байтов данных. Выделять в приьложении буфер для хранения данных такого объема зачастую бывает неудобно, особенно если это не требуется с точки зрения программной логики - например, в случае, когда программа могла бы обрабатывать эти данные по частям. Именно такую возможность и предоставляет программисту функция SQLGetData (): вы можете зарезервировать буфер разумного размера и обрабатывать получаемые данные ограниченными порциями.

Ничто не препятствует и смешиванию обеих методик для обработки результатов одного запроса. Если часть столбцов из таблицы результатов запроса вы свяжете с программными буферами посредством функции SQLBindCol (), а остальные оставите несвязанными и затем вызовете фушшию SQLFetchO, она поместит содержимое связанных столбцов текущей строки в буферы, а значения остальных столбцов можно будет извлечь отдельно с помощью фун(<ции SQLGetData (). Так удобнее действовать в тех случаях, когда запрос извлекаетиз базы данных часть столбцов небольшого размера, например фамилии, даты, денежные суммы, а один или два столбца - с данными большого объема, такими, например, как текст контракта. Однако учтите, что в некоторых реализациях CLI возможности смешивания этих двух способов обработки результатов запроса могут быть ограничены. В частности, иногда требуется, чтобы все связанные столбцы шли подряд в начале списка возвращаемых столбцов, а несвязанные столбцы следовали за ними.

Наборы записей с произвольным доступом

Стандарт SQL/CLI поддерживает наборы записей с произвольным доступом, аналогичные тем, которые с самого начала были включены в стандарт SQL2 для встроенного SQL. Перемещение по набору записей обеспечивает функция SQLFetchScroll о , объявление которой приведено на рис. 19.17. Эта функция представляет собой реализацию инструкции FETCH с несколько расширенными возможностями. Она позволяет перемещать указатель вперед, назад и на указанную строку. Первым параметром функции SQLFetchScroll () передается дескриптор инструкции SQL. Два других параметра определяют направление перехода и величину смещения (которое может отсчитываться от первой или от текущей записи набора). Что касается использования функций SQLBindCol () и SQLGetData (), то в комплексе с функцией SQLFetchScroll () они используются точно так же, как и с функцией SQLFetch О.

Именованные наборы записей

Обратите внимание на то, что в стандарте SQL/CLI отсутствует функция для объявления набора записей, эквивалентная инструкции DECLARE CURSOR встроенного SQL. Текст запроса на выборку просто передается CLI для вьшолнения - точно



так же, как текст любой другой инструкции SQL - с помощью функции SQLExecDirect () Или пары функций SQLPrepare О/SQLExecute (). Таблица результатов запроса идентифицируется дескриптором инструкции, и доступ к ней осуществляется с помощью функций SQLFetch (), SQLBindCol () и т п. Таким образом, роль имени набора записей играет дескриптор инструкции SQL.

Слабым местом этой схемы являются позиционные обновления и удаления записей из набора. Как рассказывалось в главе 17, встроенный SQL позволяет модифицировать или удалить текущую строку из таблицы результатов запроса (выбранную с помощью инструкции fetch) посредством специальных инструкций update. . .where current of и DELETE. . . WHERE current of. В этих инструкциях указывается имя набора записей, поскольку программа может одновременно открыть несколько наборов записей, чтобы обрабатывать результаты нескольких запросов.

Для поддержки аналогичных возможностей в приложениях, использующих CLI, стандартом определена функция SQLSetCursorName (), объявление которой приведено на рис. 19.17. Она назначает набору записей заданное вами имя: вы указываете это имя в одном ее параметре, а дескриптор инструкции SQL, идентифицирующий набор записей, - в другом. Назначенное набору записей имя можно затем использовать в позиционных инструкциях UPDATE и DELETE, которые вы передаете CLI для выполнения. Сопутствующая функция SQLGetCursorName () позволяет получить заданное ранее имя набора записей, указав дескриптор инструкции.

Выполнение динамических запросов

Если столбцы в таблице результатов запроса заранее (при разработке программы) не известны, то их характеристики можно узнать в процессе выполнения профаммы с помошью функций, объявления которых приведены на рис. 19.19. Эти функции реализуют возможности динамического SQL, описанного в главе 18. Чтобы выполнить с их помощью динамически определяемый запрос, приложению нужно предпринять следующие действия (предполагается, что соединение с базой данных уже установлено):

1 Получить дескриптор инструкции с помощью функции SQLAllocHandle (). 2. Вызвать ф)41кцию SQLPrepare (), передав ей текст инсГрукции SELECT. 3 Вызвать функцию SQLExecute () для выполнения запроса.

4. Вызвать функцию SQLNumResultCols (), чтобы узнать количество столбцов в таблице результатов запроса.

5. Вызвать функцию SQLDescribeCol О по одному разу для каждого столбца, который должен быть возвращен приложению. При каждом вызове функции возвращается тип данных столбца, его размер, специальная константа-индикатор, указывающая, может ли столбец содержать значения null, и т.п.

6. Выделить буферы для получения результатов запроса и связать их со столбцами с помощью функции SQLBmdCol () (по одному вызову для каждого столбца).

7. Используя функцию SQLFetch (), по очереди извлечь все строки из таблицы результатов запроса, пока при очередном вызове функции не будет возвращено значение, указывающее, что все сфоки получены. Функция SQLFetch () помещает содержимое сфоки в профаммные буферы, предварительно связанные со столбцами таблицы результатов запроса с помощью функции SQLBindCol ().

8- Когда все результирующие данные получены, профамма должна вызвать функцию SQLCloseCursor () ДЛЯ прекращения доступа к таблице результатов запроса.



1 ... 172 173 174 [ 175 ] 176 177 178 ... 264

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика