Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #52, МАРТ 2005 г.

DataBase Connectivity в твоей программе

Alexander S. Salieff

Спецвыпуск: Хакер, номер #052, стр. 052-056-5


MYSQL_ROW row;

while((row = mysql_fetch_row(res)))

printf("ID=%s NAME=%s AGE=%s\n", row[0], row[1], row[2]);

Если бы мы заранее не знали, сколько именно полей вернет наш запрос, то на помощь нам пришла бы функция int mysql_num_fields(MYSQL_RES *). Теперь осталось провести завершающие операции. Проверим, завершился ли цикл, потому что данных для фетчинга больше не осталось (а не из-за ошибки). Освободим объект, в котором сохранен результат запроса, и завершим соединение:

if (!mysql_eof(res)) exiterr(1);

mysql_free_result(res);

mysql_close(&mysql);

Как видишь, часто использование нативного API очень удобно, код приведенного примера получился у меня меньше, чем при использовании OTL, а размер исполняемого файла меньше, чем при использовании ODBC. Справедливым будет отметить, что для поставленных условий это решение было самым компактным.

А как же PostgreSQL?

Конечно же, компактный нативный API предоставляют не только разработчики MySQL. Для полноты картины разведаем конфиденциальную информацию о возрасте Васи и Маши с помощью PostgreSQL DBC API, который не менее популярен среди программистов при специфической постановке задачи.

По старой доброй традиции начнем с подключения заголовков:

#include <libpq-fe.h>

Соединение сохраняется в переменной типа PGconn, база стоит на локальном хосте, а аутентификация у моего PostgreSQL настроена через PAM, поэтому из опций указываем только имя БД (и тут тоже одна СУРБД может управлять несколькими БД) и имя пользователя:

PGconn * conn=PQconnectdb("dbname=test user=salieff");

if(PQstatus(conn) == CONNECTION_BAD)

{

fprintf(stderr, "Connection to database failed - %s.\n", PQerrorMessage(conn));

PQfinish(conn);

exit(1);

}

Запрос выполняем посредством PQexec, а его результат сохраняется в переменной типа PGresult. Статус исполнения может отличаться в разных запросах, а нас интересует значение PGRES_TUPLES_OK, означающее выполнение запроса и возврат результатов:

PGresult * res = PQexec(conn, "SELECT id, name, age FROM mytable ORDER BY id");

if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)

{

fprintf(stderr, "SELECT failed\n");

PQclear(res);

PQfinish(conn);

exit(1);

}

Теперь мы узнаем количество строк, которое вернул наш запрос, и выведем их на экран. Если бы нам не было известно, что в каждой строке по три столбца, то можно было бы узнать количество столбцов с помощью int PQnfields(const PGresult *res). Значения будем запрашивать функцией PQgetvalue, которая конвертирует все подряд в печатные строки:

int rows = PQntuples(res);

for (int r=0; r<rows; r++)

{

char * myid=PQgetvalue(res, r, 0);

char * myname=PQgetvalue(res, r, 1);

char * myage=PQgetvalue(res, r, 2);

printf("ID=%s NAME=%s AGE=%s\n", myid, myname, myage);

}

Ну и теперь, как и полагается высокопрофессиональным программистам, освободим все неиспользуемые ресурсы для экономии и разорвем соединение с базой данных:

Назад на стр. 052-056-4  Содержание  Вперед на стр. 052-056-6