Администрирование Оглавление Анализ посетителей веб-сайта.

Выполняем SQL-запросы к базе данных

В качестве первого примера CGI-скрипта, работающего с СУБД MySQL рассмотрим программу из предыдущей главы, которая выполняет SQL-запросы. Хотя MySQL наиболее часто используется под операционной системой UNIX, существует версия MySQL и для Windows. Мы начнем с версии CGI-скрипта под Windows, т.к. операционная система Windows знакома подавляющему большинству читателей. Вам необходимо установить библиотеку itcgimysql. itcgimysql - это версия ITCGI под Windows, с поддержкой функций для работы с СУБД MySQL. Данную версию библиотеки вы можете взять на нашем сайте http://itsoft.ru/.
HTML-форма для выполнения sql-запросов выглядит следующим образом:

База данных:
Пользователь:
Пароль:
HTML-код приведен ниже:
<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.