Выполняем SQL-запросы к базе данных
База данных MS Access и многие другие локальные (или, как их еще называют, десктопные СУБД)
не позволяют подключаться к ним по сети, также бывает, что невозможно осуществить
соединение по порту базы данных из-за межсетевых экранов (firewall'ов, брендмауера или прокси-серверов).
В таких случаях
полезно иметь CGI-программу, которая позволит нам выполнять SQL-запросы через Internet.
Такая CGI-программа - просто незаменимый инструмент при разработке интерактивных веб-сайтов
на основе баз данных. HTML-форма для выполнения sql-запросов выглядит следующим образом:
HTML-код приведен ниже:
<form action="/cgi-bin/sql_query.exe">
<input type=hidden name=dsn value=gb>
<textarea name=query rows=10 cols=80></textarea>
<input type=submit value="Отправить запрос">
</form>
Данная программа соединяется с источником данных dsn, выполняет sql-запрос
query и возвращает пользователя на страницу с HTML-формой для SQL-запроса, в случае, если результатом
запроса не является таблица.
Создайте еще один проект в среде MS Visual Studio с именем sql_query.
Ниже приведен исходный код функции _tmain с комментариями:
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
return -1;
CString test;
CDatabase db;
CString dsn, query;
//получаем параметры из HTML-формы
GetParamByName("dsn", dsn);
GetParamByName("query", query);
//соединяемся с базой
try
{
db.OpenEx("DSN="+dsn, CDatabase::noOdbcDialog);
}
catch(CDBException* e)
{
printError("Error: %s\nState: %s\n", e->m_strError,
e->m_strStateNativeOrigin);
goto LABEL_END;
}
//определяем тип запроса
//если SELECT, то результатом будет таблица, которую мы и печатаем
//иначе просто выполняем запрос, ничего не печатая
test=query;
test.MakeUpper();
if( test.Find("SELECT",0)==0 )
{
CRecordset rs(&db);
//выполняем sql-запрос
try
{
rs.Open(CRecordset::dynaset,query);
}
catch(CDBException* e)
{
printError("%s\n%s\nquery=%s\n", e->m_strError,
e->m_strStateNativeOrigin, query);
goto LABEL_END;
}
//если запрос выполнен успешно, печатаем HTTP-заголовок
printf("Content-type: text/html\n\n");
//и выводим таблицу
printf("<table border=1><tr>\n");
CODBCFieldInfo info;
int i;
//печатаем названия колонок
for (i=0;i<rs.GetODBCFieldCount();i++)
{
rs.GetODBCFieldInfo(i,info);
printf("<td><font color=green>%s</font></td>\n",
info.m_strName);
}
printf("</tr>");
//печатаем записи таблицы
while (!rs.IsEOF())
{
printf("<tr>\n");
CString col;
for (int i=0;i<rs.GetODBCFieldCount();i++)
{
rs.GetFieldValue(i,col);
printf(" <td>%s\n",col);
}
rs.MoveNext();
}
printf("</table>\n");
if (rs.IsOpen())
rs.Close();
}
else
{
try
{
db.ExecuteSQL(query);
}
catch(CDBException* e)
{
printError("%s\n%s\nquery=%s", e->m_strError,
e->m_strStateNativeOrigin, query);
goto LABEL_END;
}
printf("Location: %s\n\n",getenv("HTTP_REFERER"));
}
LABEL_END:
if (db.IsOpen())
db.Close();
return 0;
}
Соберите этот проект и выполните несколько sql-запросов при помощи этой программы.
|