Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil
Шрифт:
<td>ADDED</tr> <cd>THEME</tr> </tr>");
}
Далее идет уже знакомая по предыдущему примеру обработка текстовых переменных:
b_index[osqlda->sqlvar[1].sqllen]='\0';
b_name.vary_string[b_name.vary_length]='\0';
b_author.vary_string[b_author.vary_length]='\0';
b_theme.vary_string[b_theme.vary_length]='\0';
и преобразование TIMESTAMP в удобочитаемое выражение:
isc_decode_timestamp(&b_added,&added_time);
strftime(decodedTime,sizeof(decodedTime),"%d-%b-%Y
%H: %M", &added_t ime) ;
printf("<tr bgcolor=white><td>%i</td> <td>%s</td> <td>%s</td>
<td>%s</td> <td>%s</td> <td>%s</td> </tr>",
b_id,
b_index,
b_name.vary_string,
b_author.vary_string,
decodedTime,
b_theme.vary_string);
}
if (status_vector[0] == 1 && status_vector[1]){
isc_print_status(status_vector);
return(1);
}
free(osqlda);
isc_dsql_free_statement(
status_vector,
&statement_handle,
DSQL_drop);
if (scacus_vector[0] == 1 && status_vector[1]){
isc_print_status(status_vector) ;
return(1);
}
Завершаем
if (transaction_handle){
isc_commit_transaction(status_vector, &transaction_handle); }
if (status_vector[0] == 1 && status_vector[1]){
isc_pnnt_status (status_vector) ;
return(1);
}
if (db_handle) isc_detach_database(status_vector, &db_handle);
if (status_vector[0] == 1 && status_vector[1]){
isc_print_status(status_vector);
return(1);
}
Завершаем документ HTML-формой для ввода данных:
if(hDisplayed){
printf("</table></center><br>");
}
else{
printf ("<br><brxbr><center><b>Table is
empty</b></center><brxbr><br>") ;
}
printf ( "<centerxtable border=0 width=%><tr
align=right><td><form name ='demo ' method=POST
action= ' example2 ' xtable border=0>") ;
printf("<tr><td align=left>Book index</td><td>
<input type=text name='b_index' size=16 maxlength=16></td></tr>") ;
printf("<tr><td align=left>Book name</td><td>
<input type=text name= ' b_name ' size=16 maxlength=80x/tdx/tr>");
printf ("<tr><td align=lef t>Book author</td><td>
<input type=text name='b_author' size=16 maxlength=80></td></tr>");
printf("<tr><td align=left>Book theme</td><td>
<input type=text name='b_theme' size=16 maxlength=60></td></tr>");
printf ("<trxtd colspan=2 align=right>
<input type= ' submit' value='Add data'></td></tr>"};
printf ("</table></form></td></tr></table></center></body></html>");
return(0);
}// end of main
Вот что мы получим при первом запуске приложения при пустой таблице данных (см. рис 3.2):
Рис 3.2.
После вставки какой-нибудь записи в таблицу при помощи формы справа снизу результат будет следующим (см. рис 3.3).
Рис 3.3. Результаты выполнения CCI-приложения
В этом приложении читается несколько переменных www-окружения, которые проверяются на ненулевую длину и передаются в качестве входящего параметра запроса. Переменные www-окружения читаются при помощи функций библиотеки CGIC (ее можно загрузить с сайта, однако вы можете воспользоваться любой удобной вам библиотекой. В качестве результата анализируется переменная res_code, и в зависимости от ее значения сообщается результат вызова процедуры. Неизвестные входные параметры, участвующие в запросе, передаются следующим образом: на местах неизвестных параметров ставится знак вопроса (?), а в соответствующей этому параметру переменной XSQLDA определяется тип и данные для передаваемой переменной, причем допускается смешивать родственные типы (int-smallint, char-varchar и т д ) При внимательном изучении примера видно, что запрос, выбирающий данные из таблицы, вызывается несколько отличным методом, нежели запрос вызывающий ХП. Первый запрос, состоит из следующих этапов:
* Резервирование ресурсов, требуемых для запроса библиотекой доступа к InterBase, - вызов функции isc_dsql_allocate_statement.
* Подготовка запроса к исполнению сервером - именно на этом этапе выдаются сообщения об ошибках в синтаксисе - вызов функции isc_dsql_prepare.
* Исполнение запроса сервером - вызов функции isc_dsql_execute2 (или isc_dsql_execute, отличие этих функций в том, что вызов isc_dsql_execute непременно требует вызова функции isc_dsql_fetch, если существуют исходящие параметры). На этом этапе могут быть выданы сообщения о несоответствии типов и/или количества элементов XSQLDA.
* Доставка данных приложению - вызов isc_dsql_fetch. В отличие от большинства остальных API-функций эта функция возвращает целое число, содержащее код ошибки, - пока это значение равно нулю, данные есть и их можно прочитать. Когда выбраны все данные, это значение становится отличным от нуля.
* Освобождение ресурсов, занятых на этапе 1, - вызов isc_dsql_free_statement. Инициализация структур XSQLDA обычно происходит до п. 2.
Второй запрос исполняется сразу, минуя все вышеперечисленные пункты, кроме п. 3. В данном случае используется функция isc_dsql_exec_immed2. Отличие данных методов заключается в том, что в случае первого запроса можно воспользоваться пп. 3 и 4 внутри цикла - это дает преимущество в скорости, при исполнении одного и того же запроса, но с разными значениями параметров, так как синтаксис уже проверен и запрос сразу исполняется. Метод, реализованный в исполнении второго запроса, обычно применяется при однократном вызове хранимых процедур или при исполнении команд, которые разрешается исполнять только в этих функциях (например, CREATE DATABASE разрешается использовать только в вызове функции isc_dsql_execute_immediate).