SQL- запросы
Далее мы рассмотрим sql -запросы, которые необходимы нам для восстановления утерянной информации.
select rdb$relation_fields.rdb$field_name, rdb$relation_fields.rdb$field_id, rdb$fields.rdb$field_length, rdb$types.rdb$type_name from rdb$relation_fields left join rdb$fields on rdb$relation_fields.rdb$field_source= rdb$fields.rdb$field_name left join rdb$types on rdb$types.rdb$type=rdb$fields.rdb$field_type where (rdb$relation_name=' MYTABLE ') and (rdb$types.rdb$field_name= 'RDB$FIELD_TYPE')
Данный запрос дает нам ответ на один из главных вопросов, как расположены поля в записи таблицы MYTABLE , какой имеют размер и тип
Пример выборки :
RDB$
FIELD_NAME
RDB$
FIELD_ID
RDB$
FIELD_LENGTH
RDB$
TYPE_NAME
field 1
0
4
long
field2
1
2
float
field3
3
8
double
field4
4
1
varying
В первом столбце указано название поля, во втором его порядок в записи, в третьем длина поля в байтах, а в четвертом тип поля.
Осталось только узнать в каких страницах расположена таблица, которую мы пытаемся восстановить.
select rdb$relation_id,rdb$relation_name, RDB$PAGE_NUMBER, rdb$page_type from rdb$pages left join RDB$relations on rdb$pages. RDB$RELATION_ID=RDB$relations.RDB$RELATION_ID where rdb$relation_name=' MYTABLE ';
Пример выборки:
RDB$
RELATION_ID
RDB$
RELATION_NAME
RDB$
PAGE_NUMBER
RDB$
PAGE_TYPE
145
MYTABLE
198
4
145
MYTABLE
199
6
В первой колонке указан номер отношения (таблицы), во второй название таблицы, в третьей страницы, на которых расположена таблица, а в четвертой тип таблицы.
На самом деле, <увы и ах>, мы только <добыли> из базы номера страниц указателя и индекса, а не полностью список всех страниц. Так что, засучим рукава и будем работать далее. Страница индексов для нас никоем образом не важна, а формат страницы указателя был вкратце описан выше.
Остановимся на нем более подробно.
typedef struct ppg {
struct pag ppg_header;
SLONG ppg_sequence; /* Sequence number in relation */
SLONG ppg_next; /* Next pointer page in relation */
USHORT ppg_count; /* Number of slots active */
USHORT ppg_relation; /* Relation id */
USHORT ppg_min_space;/* Lowest slot with space available */
USHORT ppg_max_space;/* Highest slot with space available */
SLONG ppg_page [1]; /* Data page vector */ } *PPG;
#define ppg_eof 1 /* Last pointer page in relation */
В стандартном заголовке для нас особо интересно поле flag , если как описано выше, оно установлено в <1>, то это значит что таблица указателей является последней для рассматриваемого отношения (таблицы), и соответственно мы можем узнать все необходимые нам данные.
За стандартным заголовком страницы, идет заголовок страницы указателей, где соответственно указывается: номер данной страницы, в последовательности страниц указателя для данного отношения (таблицы); номер следующей страницы для данного отношения; количество активных слотов (то есть записей о том, какие страницы используются); номер отношения (таблицы); наименьший доступный слот и максимальный доступный слот.
Далее идет вектор данных, в котором непосредственно и перечислены страницы.
Всё вышеописанное можно наглядно посмотреть с помощью программы IBSurgeon Viewer .
Итак, что мы знаем в данный момент:
• структуру таблицы - каким образом расположены в ней поля и их размер;
• номера страниц данных, в которых находится наша таблица;
• структуру страниц данных.
Таким образом, у нас выполнены необходимые и достаточные условия, чтобы попробовать восстановить утерянные данные.