Чтение онлайн

ЖАНРЫ

Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil

Востриков С М

Шрифт:

dpb_buffer) ;

Далее идет стандартная для большинства API-функций проверка и анализ результата:

if (status_vector[0] == 1 && status_vector[1]){

isc_print_status(status_vector) ;

return(1);

}

Если подключение к базе данных произошло удачно, начинается транзакция:

if (db_handle){

isc_start_transaction(

status_vector,

&transaction_handle,

1,

&db_handle,

0,

NULL);

if (status_vector[0] == 1 && status_vector[1]){

isc_print_status(status_vector);

return(1);

}

}

Далее

инициализируются структуры, которые будут заполняться результатами запроса:

osqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(6));

osqlda -> version = SQLDA_VERSION1;

osqlda -> sqln = 6;

osqlda->sqlvar[0].sqldata = (char *)&b_id;

osqlda->sqlvar[0].sqltype = SQL_LONG;

osqlaa->sqlvar[0].sqlind = &o_ind[0];

osqlda->sqlvar[1].sqldata = (char *)&b_index;

osqlda->sqlvar[1].sqltype = SQL_TEXT;

osqlda->sqlvar[1].sqlind = &o_ind[l];

osqlaa->sqlvar[2].sqldata = (char *)&b_name;

osqlda->sqlvar[2].sqltype = SQL_VARYING;

osqlda->sqlvar[2J .sqlind = ko_ind[2];

osqlda->sqlvar[3].sqldata = (char *)&b_author;

osqlda->sqlvar[3].sqltype = SQL_VARYING;

osqlda->sqlvar[3].sqlind = &o_ind[3];

osqlda->sqlvar[4].sqldata = (char *)&b_added;

osqlda->sqlvar[4].sqltype = SQL_TIMESTAMP;

osqlda->sqlvar[4].sqlind = &o_ind[4];

osqlda->sqlvar[5].sqldata = (char *)&b_theme;

osqlda->sqlvar[5].sqltype = SQL_VARYING;

osqlda->sqlvar[5].sqlind = &o_ind[5];

А вот здесь, собственно, и начинается подготовка к исполнению запроса сервером:

isc_dsql_allocate_statement(

status_vector,

&db_handle,

&statement_handle);

if (status_vector[0] == 1 && status_vector[1]){

isc_print_status(status_vector);

return(1);

}

isc_dsql_prepare(

status_vector,

&transaction_handle,

&scatement_handle,

0,

query,

SQL_DIALECT_V6,

osqlda);

if (status_vector[0] == 1 && status_vector[1]){

isc_print_status(status_vector);

return(1);

}

isc_dsql_execute2(

status_vector,

&transaction_handle,

&statement_handle,

1,

NULL,

NULL);

if (status_vector[0] == 1 && status_vector[1]){

isc_print_status(status_vector) ;

return(1);

}

Здесь начинается таблица HTML-документа. Ситуация, когда в базе данных может не оказаться данных, подробно анализируется во втором примере.

printf("<center><table border=0 bgcolor=black cellpadding=l

cellspacing=l><tr align=center bgcolor=#999999> <td>Book

ID</tr> <td>CODE</tr> <td>TITLE</tr> <td>AUTHOR</tr>

<td>ADDED</tr> <td>THEME</tr> </tr>");

После исполнения запроса сервер готов к передаче данных. "Доставкой" данных !лнимаегся функция isc_dsql_tetch'

while((fetch_code = isc_dsql_fetch(

status_vector,

&statement_handle,

1,

osqlda))= = 0) {

Для строковых переменных требуется

корректно установить длину, так как размер возвращаемых данных не всегда соответствуем максимально возможному, и если этого не сделать, то вместе с реальными данными можно получить' "мусор" из памяти или остатки предыдущих строк:

b_index[osqlda->sqlvar[1].sgllen]= ' \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, как и структуры DATE/TIME, перед выводом в документ можно преобразовать в строковый тип в нужном формате. Для этого сначала она декодируется в структуру tm, а затем в строку:

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_strxng,

b_author.vary_string,

decodedTime,

b_theme.vary_string);

}

После вывода всех данных необходимо завершить документ:

printf ("</table></center></body></html>") ;

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 (status_vector[0] == 1 && status_vector[1]){

isc_print_status(status_vector);

recurn(l);

}

Затем завершить транзакцию и отключиться от базы данных:

if (transaction_handle){isc_commit_transaction(status_vector,

&transaction_handle);}

if (status_vector[0] == 1 && status_vector[1]){

isc_print_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);

}

return(0);

}// end of main

Обратите внимание на маленькую разницу в работе с переменными SQLJVARYING и SQL_TEXT (это соответственно VARCHAR и CHAR языка SQL). Разница в том, что если в базе данных хранится меньше символов, чем максимально возможно для столбца (например, объявлено CHAR(16), а хранится строка "12345"), то сервер добавит N пробелов в конец строки, где N является' разницей между максимально возможным количеством символов и реально хра-1 нящимся в поле таблицы. Тип SQL_VARYING свободен от этого недостача,< однако при получении данных нужно учитывать, что только определенное зна-1 чение символов является реально полученными; остальное количество - это| случайные данные из памяти компьютера, на котором исполняется скрипт. Для | удобства работы с этим типом обычно определяют структуру, где член структу- \ ры SQL_VARCHAR vary_length указывает размер полученной строки,^ a vary_string собственно содержит строку.

Поделиться с друзьями: