Выполняем 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-запросов при помощи этой программы.
|