Главная ]
5.Обработка ошибок
Программирование
Базы данных



Эта глава описывает, как устанавливать вектор состояния ошибки, где InterBase может сохранять информацию об ошибке во время выполнения, и как использовать функции API, чтобы обрабатывать ошибки и сообщать о них. Следующая таблица содержит функции API для обработки ошибок:

Функция

Что делает

isc_interprete()

Передает данные об ошибках IB в буфер

isc_print_sqlerror()

Выводит сообщение об SQL ошибке

isc_print_status()

Выводит сообщение об ошибке IB

isc_sqlcode()

Устанавливает значение SQLCODE

isc_sql_interprete()

Передает данные об ошибках SQL в буфер

5.1.Установка вектора состояния ошибки

Большинство функций API возвращает информацию о состоянии, которое показывает успех или неудачу. Возвращенная информация берется из второго элемента массива вектора состояния ошибки, где сообщает о состояниях ошибки. Вектор состояния ошибки объявлен в приложениях как массив 20 длинных целых чисел, используя следующий синтаксис:

#include <Ibase.h>

...

ISC_STATUS status_vector [20];

ISC_STATUS определен директивой#define в ibase.h, и предоставляет удобство программирования и независимость от платформы

5.2.Использование информации в векторе состояния

Происходит или нет ошибка в течение выполнения вызова API, InterBase загружает вектор состояния ошибки информацией о состоянии вызова. Информация состоит из одного или нескольких  кодов ошибки InterBase, и информации об ошибке  может использоваться, чтобы сформировать сообщение об ошибках.

Приложение может проверять вектор состояния после выполнения большинства вызовов API, чтобы определить их успех или неудачу. Если состояние ошибки возвращено, приложения могут:

- Отобразить сообщения об ошибках InterBase, используя isc_print_status ().

- Установить значение SQLCODE, соответствующее ошибке InterBase, используя isc_sqlcode (), и отобразить SQLCODE и сообщение об ошибках SQL, используя isc_print_sqlerror ().

- Формировать индивидуальные сообщения об ошибках InterBase в буфере используя isc_interprete (). Буфер должно предварительно создать приложение. Использование буфера позволяет приложению исполнить дополнительную обработку сообщения (например, сохранение сообщений в файле регистрации ошибок). Эта способность особенно полезна на системах управления окнами, которые не разрешают прямые экранные записи.

- Фиксировать сообщение об ошибках SQL в буфере с isc_sql_interprete (). Буфер должно предварительно создать приложение.

- Производить синтаксический анализ и реагировать на определенные ошибки InterBase в векторе состояния.

5.3.Проверка вектора состояния на ошибки

Функции API, которые возвращают информацию в векторе состояния, объявлены в ibase.h как возвращающие указатели на ISC_STATUS. Например,  прототип функции для isc_prepare_transaction () объявлен как:

ISC_STATUS ISC_EXPORT isc_prepare_transaction(ISC_STATUS ISC_FAR *,isc_tr_handle ISC_FAR *);

Чтобы проверить вектор состояния на состояние ошибки после выполнения функции, исследуйте первыйэлемент вектора состояния, чтобы узнать, установлен он в 1, и если так, исследуйте второй элемент, чтобы узнать, что он не 0. Значение отличное от нуля во втором элементе указывает на состояние ошибки. Следующий фрагмент кода на иллюстрирует, как проверить вектор состояния на состояния ошибки:

#include <ibase.h>

. . .

ISC_STATUS status_vector[20];

. . .

/* Здесь предполагаемый вызов API возвращающий  состояние ошибки. */

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

{

/*Здесь описание состояния ошибки */

;

}

Если ошибка обнаружена, Вы можете использовать функции API в подпрограмме обработки ошибок, чтобы отобразить сообщения об ошибках, фиксировать сообщения об ошибках в буфере, или анализировать вектор состояния для специфических кодов ошибки.

Вывод или сбор данных сообщений об ошибках - только одна часть подпрограммы обработки ошибок.

Обычно, эти подпрограммы делают откат транзакции, и иногда они могут повторять операцию.

5.4.Отображение сообщений об ошибках InterBase

Используйте isc_print_status ()чтобы отобразить сообщения об ошибках InterBase на экране. Эта функция анализирует вектор состояния, чтобы формировать все доступные сообщения об ошибках, затем использует C printf () функцию, чтобы вывести сообщения на дисплей. Isc_print_status () требует одного параметра, указателя на вектор состояния содержащий информацию об ошибке. Например, следующий фрагмент кода вызывает isc_print_status () и делает откат транзакции при ошибке

#include <ibase.h>.

. . .

ISC_STATUS status_vector[20];

isc_tr_handle trans;

. . .

trans= 0L;

. . .

/* Предполагаемая транзакция стартует здесь. */

/* Здесь предполагаемый вызов API возвращающий  состояние ошибки. */

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

{

isc_print_status(status_vector);

isc_rollback_transaction(status_vector,&trans);

}

На системах управления окнами, которые не разрешают, прямые экранные записи с printf (), используют isc_interprete () чтобы фиксировать сообщения об ошибках в буфере.

Для приложений, которые используют,  динамические функции SQL(DSQL) API, ошибки должны быть отображены, используя соглашения SQL. Используйте isc_sqlcode () и isc_print_sqlerror () вместо isc_print_status ().

5.5.Фиксация сообщений об ошибках InterBase

Используйте isc_interprete ()чтобы формировать сообщение об ошибках из информации в векторе состояния, и сохраните это в определенном приложением буфере, где  может далее использоваться. Фиксация сообщений в буфере полезна когда приложения:

- Работают под системами управления окнами, которые не разрешают прямые экранные записи.

- Требуют, чтобы большего контроля над выводом сообщения об ошибке чем это было возможно с isc_print_status ().

- Сохраняют отчет о всех об ошибках в журнале.

- Управляют сообщениями или форматируют сообщения об ошибках для вывода, или передают их  подпрограммам отображения системам работы с окнами.

Isc_interprete () возвращает и форматирует отдельное сообщение об ошибках, каждый раз когда она вызывается. Когда ошибка происходит, вектор состояния обычно содержит больше чем одно сообщение об ошибках. Чтобы отыскивать все уместные сообщения об ошибках, Вы должны выполнять повторные вызовы isc_interprete ().

Передайте адрес буфера и адрес вектора состояния в isc_interprete(), и  isc_interprete() сформирует сообщение об ошибках из информации в векторе состояния, поместит отформатированную строку в буфер, и приложение может управлять им, и переместит указатель вектора состояния на начало следующего кластера информации об ошибки. Isc_interprete () требует двух параметров, адрес буфера приложения, чтобы содержать отформатированный вывод сообщения, и указатель на массив векторов состояний.

Никогда не передавайте массив векторов состояний непосредственно isc_interprete (). Каждый раз при вызове, isc_interprete () продвигает указатель на вектор состояния к следующему элементу, содержащему новую информацию сообщения. Перед запросом isc_interprete (), убедитесь, что установили указатель на начальный адрес вектора состояния.

Следующий код демонстрирует подпрограмму обработки ошибок, которая делает повторные вызовы isc_interprete() чтобы получить сообщения об ошибках из вектора состояния по одной, так что они могут быть записаны в файл регистрации.

#include <ibase.h>

. . .

ISC_STATUS status_vector[20];

isc_tr_handle trans;

long *pvector;

char msg[512];

FILE*efile; /* Фрагмент кода предполагаемого открытия файла */

trans= 0L;

. . .

/*Здесь начинается подпрограмма обработки ошибок. */

/* Всегда настраивайте pvector на указатель на status_vector. */

pvector = status_vector;

/* Получаем первое сообщение */

isc_interprete(msg, &pvector);

/* Пишем первое сообщение из буфера в log файл. */

fprintf(efile, "%s\n", msg);

msg[0]= ’-’; /* Добавляем в конец дефис для второго сообщения */

/* Ищем другие сообщения в цикле*/

while(isc_interprete(msg + 1, &pvector)) /* Дальше? */

fprintf(efile,"%s\n", msg);/* Если так то пишем в log файл. */

fclose(efile);/* Все закончили закрываем Log файл */

isc_rollback(status_vector, &trans);

return(1);

. . .

5.6.Заполнение SQLCODE значением ошибки

стр. 176-178, (Не переведены так как SQLCODE не нужны и устарели)

5.7.Анализ вектора состояния ( статус-вектор )

InterBase сохраняет информацию об ошибке в векторе состояния во втором или третьем кластерах (каждый кластер это длинное целое, а фактически элемент массива статус вектора). Первый кластер в векторе состояния всегда указывает первичную причину ошибки. Последующие кластеры могут содержать служебную информацию относительно ошибки, например, строки или числа для вывода в сообщении об ошибках. Такое число кластеров используется для отчета, так как служебная информация  изменяется от ошибки к ошибке.

Во многих случаях, дополнительные ошибки могут быть переданы в векторе состояния. Дополнительные ошибки выводятся немедленно после первой же ошибки . Первый кластер для каждого дополнительного сообщения об ошибках идентифицирует ошибку. Последующие кластеры могут содержать служебную информацию об ошибке.

Как анализируется статус вектор

Подпрограммы обработки ошибок InterBase, isc_print_status () и isc_interprete (), используют подпрограммы, которые автоматически анализируют информацию сообщений об ошибках в векторе состояния без требования знаний о структуре статус вектора. Если Вы планируете писать ваши собственные подпрограммы, чтобы читать статус-вектор и реагировать на его содержание, то Вы должны знать, как интерпретировать это содержание.

The key toparsing the status vector is to decipher the meaning of the first long in eachcluster, beginning with the first cluster in the vector.

Значение первого длинного целого в кластере

Первое длинное целое в любом кластере - числовой дескриптор. Проверяя числовой дескриптор для любого кластера Вы можете всегда определять:

- Число длинных целых в кластере.

- Вид информации, содержащейся в оставшейся части кластера.

- Начальное местоположение следующего кластера в векторе состояния.

Интерпретация первого длинного целого числа

Длинное целое в

Значение

кластер

Интерпретация

0

-

Конец информации об ошибке в статус векторе

1

2

Второе long в коде ошибки

2

2

Второй long это адрес строки, используемой как переменный параметр в универсальном сообщении об ошибках InterBase

3

3

Второй long это длина, в байтах, строки переменной длины, предоставляемой операционной системой (наиболее часто эта строка - имя файла); третье long- адрес строки

4

2

Второй long это число используемое как переменный параметр в универсальном сообщении об ошибках

5

2

Второй long - адрес строки сообщения об ошибках не требующий никакой дальнейшей обработки перед выводом

6

2

Второе длинное есть код ошибки VAX/VMC

7

2

Второе длинное есть код ошибки UNIX

8

2

Второе длинное есть код ошибки ApolloDomain

9

2

Второе длинное есть код ошибки MS-DOSили OS/2

10

2

Второе длинное есть код ошибки HPMPE/XL

11

2

Второе длинное есть код ошибки HPMPE/XLIPC

12

2

Второе длинное есть код ошибки NeXT/Mach

Примечание: По мере адаптации InterBase к другим платформам и другому оборудованию в этот список добавятся новые значения

Включив ibase.h в начало вашего исходного текста, Вы можете использовать серии #defines, чтобы заменить на жестко закодированные числовые дескрипторы в векторе состояния для подпрограмм синтаксического анализа которые Вы напишите. Преимущества использования этих #defines следующие:

- Ваш код будет более легким для чтения.

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

- Следующая таблица перечисляет #define эквиваленты каждого числового дескриптора:

Значение

#define

Значение

#define

0

isc_arg_end

8

isc_arg_domain

1

isc_arg_gds

9

isc_arg_dos

2

isc_arg_string

10

isc_arg_mpexl

3

isc_arg_cstring

11

isc_arg_mpexl_ipc

4

isc_arg_number

12

isc_arg_next_mach

5

isc_arg_interpreted

13

isc_arg_netware

6

isc_arg_vms

14

isc_arg_win32

7

isc_arg_unix

 

 

5.8.Значение второго long в кластере

В  второй long в кластере -всегда один из пяти элементов:

- Код ошибки InterBase (1-ый long = 1).

- Адрес строки(1-ый long = 2 или 5).

- Длина строки(1-ый long = 3).

- Числовое значение (1-ый long = 4).

- Код ошибки операционной системы (1-ый long > 5).

5.8.1.Ошибочные коды Interbase

Коды ошибки InterBase имеют два применения. Сначала, они используются внутренними функциями InterBase, чтобы формировать и отображать  строки сообщения об ошибках. Например, isc_interprete () вызывает другую функцию, которая использует код ошибки InterBase, чтобы получить основное сообщение об ошибках из которого она уже формирует строку сообщения об ошибках, которую Вы можете отображать или сохранять в журнале.

Во-вторых, когда вы пишете вашу собственную подпрограмму обработки ошибок, Вы можете проверять вектор состояния, напрямую, обрабатывая и реагируя на определенные коды ошибок InterBase.

Когда во втором элементе кластера - код ошибки InterBase, тогда последующие кластеры могут содержать дополнительные параметры для строки сообщения об ошибках, связанной с кодом ошибки. Например, универсальное сообщение об ошибках InterBase может содержать переменный строковый параметр для имени таблицы, где ошибка произошла, или она может содержать переменный числовой параметр для кода триггера, который получил условие ошибки.

Если Вы пишите ваши собственные подпрограммы синтаксического анализа, Вы могут были должны исследовать и использовать эти дополнительные кластеры информации ошибки.

5.8.2.СТРОКОВЫЕ АДРЕСА

Строка адресуется указателем текста сообщения об ошибках. Когда первый элемент в кластере равен 2 (isc_arg_string), адрес указывает часто на имя базы данных, таблицы, или столбца, на который воздействует ошибка. В этих случаях, функции InterBase, которые формируют строку сообщения об ошибках заменяют параметр в универсальном сообщении об ошибках InterBase  строкой, указанной этим адресом. В других случаях адрес указывают на сообщение об ошибках, жестко закодированное в триггерах базы данных.

Когда первыйэлемент в кластере равен 5 (isc_arg_interpreted), то адрес указывает на текстовое сообщение, которое не требует никакой дальнейшей обработки перед вводом. Иногда это сообщение может быть жестко закодировано в InterBase непосредственно, и может быть сообщение об ошибках  системы.

В любом из этих случаев, функции InterBase типа isc_print_status () и isc_interprete () могут форматировать и отображать заканчивающееся сообщение об ошибках для Вас.

181-182 не переведена

5.9.Пример анализа статус вектора

Следующий пример C иллюстрирует простой пример, анализ  "в лоб" вектора состояния. При возникновении ошибки блок обработки ошибок анализирует кластер массива вектора состояния, печатая содержание каждого кластера и интерпретируя его для Вас.

#include <ibase.h>

. . .

ISC_STATUS status_vector[20];

main()

{

 int done, v; /* если аргументов нет то 1, есть 0?, индекс статус вектора */

 int c, extra; /* счетчик кластеров, 3 long cluster flag */

 static char *meaning[] = {"Endof error information",

                          "n InterBase error code",

                           "string address",

                           "string length",

                           "numeric value",

                           "system code"};

/* здесь устанавливается соединение с БД и начинается транзакция */

 if (status_vector[0] == 1 &&status_vector[1] > 0) error_exit();

  . . .

}

void error_exit(void)

{

 done = v = 0;

 c = 1;//анализ начинаем с первого кластера

 while (!done)

 {

  extra = 0;

  printf("Cluster%d:\n", c);//выводит номер кластера

    //выводит индекс и содержимое кластера по индексу

  printf("Status vector %d: %ld:", v, status_vector[v]);

  if (status_vector[v] !=gds_arg_end)//если не достигнут конец  аргументов, выводим сообщение

        printf("Next long isa");

  switch (status_vector[v++])

  {

   case gds_arg_end:

    printf("%s\n",meaning[0]);//если встретили конец аргументов, то покидаем цикл

    done = 1;

    break;

   case gds_arg_gds:

    printf("%s\n",meaning[1]);

    break;

   case gds_arg_string:

  case gds_arg_interpreted:

    break;

   case gds_arg_number:

    printf("%s\n",meaning[4]);

    break;

   case gds_arg_cstring:

    printf("%s\n",meaning[3]);

    extra = 1;

    break;

   default:

    printf("%s\n",meaning[5]);

    break;

  }

 if (!done)

 {

  printf("Status vector %d:%ld", v, status_vector[v]);

  v++;/* передвинуть указатель вектора */

  c++;/* увеличить счетчик кластера */

  if (extra)

  {

   printf(": Next long is a%s\n", meaning[2]);

   printf("Status vector:%d: %ld\n\n", v,

   status_vector[v]);

   v++;

  }

  else

   printf("\n\n");

 }

}

 isc_rollback_transaction(status_vector, &trans);

 isc_detach_database(&db1);

 return(1);

}

Здесь пример вывода результатов этой программы

Cluster 1:

Status vector 0: 1: Next long is an InterBase error code

Status vector 1: 335544342

Cluster 2:

Status vector 2: 4: Next long is a numeric value

Status vector 3: 1

Cluster 3:

Status vector 4: 1: Next long is an InterBase error code

Status vector 5: 335544382

Cluster 4:

Status vector 6: 2: Next long is a string address

Status vector 7: 156740

Cluster 5:

Status vector 8: 0: End of errorinformation

 

<< Назад ] Содержание ] Далее >> ]

 

Дизайн: Piton Alien
Rambler's Top100 Рейтинг@Mail.ru
Сайт создан в системе uCoz