Выполняем 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.
|