Выполняем SQL-запросы к базе данных
В качестве первого примера CGI-скрипта, работающего с СУБД MySQL рассмотрим программу из предыдущей главы,
которая выполняет SQL-запросы. Хотя MySQL наиболее часто используется под
операционной системой UNIX, существует версия MySQL и для Windows. Мы начнем с версии CGI-скрипта
под Windows, т.к. операционная система Windows знакома подавляющему большинству читателей.
Вам необходимо установить библиотеку
itcgimysql. itcgimysql - это версия ITCGI под Windows, с поддержкой функций для
работы с СУБД MySQL. Данную версию библиотеки вы можете взять на нашем сайте http://itsoft.ru/.
<form action="/cgi-bin/sql_query_mysql.exe"> База данных: <input type=text name=db><br> Пользователь: <input type=text name=user><br> Пароль: <input type=password name=pwd><br> <textarea name=query rows=10 cols=80></textarea> <input type=submit value="Отправить запрос"> </form>Запустите MS Visual Studio и создайте приложение по образу и подобию gbadd из предыдущей главы. Назовите его sql_query_mysql. В список подключаемых библиотек включите Ws2_32.lib, libmysql.lib, itcgimysql.lib. Отредактируйте sql_query_mysql.cpp следующим образом: // sql_query.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "sql_query.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // The one and only application object #include <winsock2.h> #include <mysql/mysql.h> #include <itcgi.h> CWinApp theApp; using namespace std; int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) return -1; /* Ниже идет непосредственно код программы, который мы впоследствии перенесем под UNIX. */ MYSQL* pDB; MYSQL_RES* res; //используем наш тип LString для работы со строками в библиотеке ITCGI //мы не используем MFC-класс CString, чтобы обеспечить //переносимость кода под UNIX LString* db = CreateString(); LString* user = CreateString(); LString* pwd = CreateString(); LString* sql_query = CreateString(); //инициализируем библиотеку функций для работы с MySQL pDB = mysql_init(NULL); if(!pDB) { printError("Внимание! Ошибка!!!", mysql_error(pDB)); return -1; } //получаем CGI-параметры из HTML-формы GetParamByName("user", user); GetParamByName("pwd", pwd); GetParamByName("db", db); GetParamByName("query", sql_query); //осуществляем соединение с конкретной базой данных if( !mysql_real_connect(pDB, NULL, *user, *pwd, *db, 0, NULL, 0) ) { printError("Внимание! Ошибка!!!", "mysql_real_connect: %s\n", mysql_error(pDB)); goto LABEL_END; } //выполняем SQL-запрос if( mysql_query(pDB, *sql_query) ) { printError("Внимание! Ошибка!!!", mysql_error(pDB)); goto LABEL_END; } //Сохраняем результат выполнения SQL-запоса. //Результатом любого SQL-запроса типа SELECT является таблица. //Результатом любых других запросов отличных от SELECT будет NULL. res = mysql_store_result(pDB); if( res ) { //Если результатом является таблица, печатаем ее. MYSQL_ROW row; MYSQL_FIELD* field; int i; printf("Content-type: text/html\n\n"); printf("<table border=1>\n"); //печатаем названия столбцов printf("<tr bgcolor=\"#CCCCCC\">\n"); while(field=mysql_fetch_field(res)) printf("<td>%s</td>", field->name); printf("</tr>\n"); //печатаем записи таблицы while( (row = mysql_fetch_row(res))!=NULL ) { printf("<tr>\n"); for(i=0;i<(int)res->field_count;i++) printf("<td>%s</td>", row[i]); }//while printf("</table>"); //освобождаем память, выделенную под таблицу mysql_free_result(res); } //если результатом SQL-запроса был NULL, т.е. //мы выполнили запрос типа INSERT, UPDATE, DELETE и т.п., //то возвращаем пользователя на страницу с HTML-формой else printf("Location: %s\n\n",getenv("HTTP_REFERER")); LABEL_END: //закрываем соединение с базой данных mysql_close(pDB); //освобождаем память, выделенную под строки DeleteString(db); DeleteString(user); DeleteString(pwd); return 0; }Соберите и протестируйте данный CGI-скрипт в действии. В связи с тем, что основная часть приложений с MySQL создается в среде UNIX рассмотрим этот же скрипт и Makefile для него. #include <stdio.h> #include <stdlib.h> #include <mysql/mysql.h> #include <itcgi.h> int main() { MYSQL* pDB; MYSQL_RES* res; LString* db = CreateString(); LString* user = CreateString(); LString* pwd = CreateString(); LString* sql_query = CreateString(); pDB = mysql_init(NULL); if(!pDB) { printError("Внимание! Ошибка!!!", mysql_error(pDB)); return -1; } GetParamByName("user", user); GetParamByName("pwd", pwd); GetParamByName("db", db); GetParamByName("query", sql_query); if( !mysql_real_connect(pDB, NULL, *user, *pwd, *db, 0, NULL, 0) ) { printError("Внимание! Ошибка!!!", "mysql_real_connect: %s\n", mysql_error(pDB)); goto LABEL_END; } if( mysql_query(pDB, *sql_query) ) { printError("Внимание! Ошибка!!!", mysql_error(pDB)); goto LABEL_END; } res = mysql_store_result(pDB); if( res ) { MYSQL_ROW row; MYSQL_FIELD* field; int i; printf("Content-type: text/html\n\n"); printf("<table border=1>\n"); printf("<tr bgcolor=\"#CCCCCC\">\n"); while(field=mysql_fetch_field(res)) printf("<td>%s</td>", field->name); printf("</tr>\n"); while( (row = mysql_fetch_row(res))!=NULL ) { printf("<tr>\n"); for(i=0;i<(int)res->field_count;i++) printf("<td>%s</td>", row[i]); }//while printf("</table>"); mysql_free_result(res); } else printf("Location: %s\n\n",getenv("HTTP_REFERER")); LABEL_END: mysql_close(pDB); DeleteString(db); DeleteString(user); DeleteString(pwd); return 0; } ******Makefile******* all: sql_query2 sql_query2: sql_query2.c itcgi.a gcc sql_query2.c -L/usr/local/lib/mysql \ -L/usr/local/lib -I/usr/local/include \ -o sql_query2 -lmysqlclient /usr/lib/itcgi.a -Wall -O3 strip sql_query2Содержание функции main осталось неизменным. Мы убрали заголовочные файлы и директивы библиотеки MFC. Данная программа была собрана и оттестирована на платформе FreeBSD, но она также должна работать на любом клоне Unix. |