Работа с таблицами в памяти Назад В начало Вперед

При описании таблицы в секции from в VIP-е или при открытии таблицы при помощи функции OpenTable на Pascal-е можно указать режим открытия fmMemory. При этом ни какой загрузки данных не происходит.

create view V1 as select * from KatOrg(fmMemory);

Данные можно вставлять в таблицу в памяти, удалять и модифицировать стандартным образом, используя функции и операторы insert, update, delete. При этом никаких изменений в БД не происходит.

Обработка данных происходит стандарным способом с использованием:

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

<таблица-в-памяти> = [table] struct [local] <описание-таблицы> ;

table - необязательное ключевое слово, т.е. struct и table struct равнозначны.

local - таблица в памяти является локальной. Для каждого экземпляра интерфейса при выполнении будет создан свой экземпляр таблицы.

Если описание ТП находится внутри описания интерфейса, то такая ТП является локальной независимо от наличия атрибута local. Тем не менее атрибут local рекомендуется указывать для улучшения читаемости исходного текста и единообразия стиля.

<описание-таблицы> - синаксис конструкции индентичен таковому при описании словаря, включая описание индексов.

Уникальность имен структур таблиц отслеживается в пределах проекта, одного исходного файла, интерфейса. Использование таких таблиц аналогично обычным. Рекомендуется избегать пересечения имен словарных таблиц и структур таблиц в памяти для избежания ошибок при их использовании. Для этой цели имеет смысл давать всем структурам таблиц в памяти некий общий префикс, например "S" - SKatSopr.

При описании синонима на таблицу в памяти в секции from заводится новый блок позиций, а не экземпляр таблицы в памяти. Идентификация экземпляра таблицы идет по имени, куда добаваляется в виде префикса имя исходника и имя интерфейса. Т.е. если таблица описана в словаре, то любое повторное использование ее как таблицы в памяти приводит к использованию одного и того же экземпляра таблицы в памяти. Аналогично работают описания table struct, сделанные в проектном файле.

Описания таблиц, сделанные в пределах одного исходного файла или интерфейса имеют соответствующую область видимости. Т.е., например, если одно и то же описание таблицы включается #include внутрь разных исходников или интерфейсов, то будут заведены разные экземпляры таблицы в памяти для соответсвующих интерфейсов. Если есть необходимость завести разные экземпляры таблицы в памяти для глобально описанных таблиц необходимо использовать синтаксис:

<таблица-в-памяти> = [table] struct <имя-таблицы> = <имя-существующей-таблицы>;

Соответственно, на таблицы, описанные указанным образом распростаняются правила видимости экземпляров, описанные выше. Посему, надо осторожно относится к таблицам, описанным вне интерфейсов, если в данном исходном файле реализовано несколько интерфейсов.

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

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

Если программист хочет пересчитать заново данные в таблице в памяти он должен вызвать метод Retrieve этой таблицы.

Если таблица открыта стандартным образом, то существует возможность динамически включить режим работы в памяти. Аналогично, если таблица открыта в памяти, этот режим можно выключить. Это достигается путем применения функции ReinitTable.

Если программист хочет, чтобы при модификации данные сразу попадали на диск, при открытии таблицы необходимо указать дополнительный режим fmWriteThru. При этом флаги модифицированности записей не выставляются. При выполнении операций update и delete происходит проверка пассивных блокировок.

Если программист желает, чтобы при закрытии таблицы изменения автоматически были отражены в БД, при открытии таблицы следует указать дополнительный режим fmAutoFlush. В данном случае, изменения будут внедряться с применением транзакции. Следует заметить, однако, что тут программист лишается возможности обработать ошибки, которые могут возникнуть при внедрении изменений.

Если программист желает принудительно сбросить сделанные в таблице в памяти изменения на диск, то он должен вызвать метод mtFlush.

При выполнении операций update и delete происходит проверка пассивных блокировок. Если возникает какая-либо ошибка, и изменения проводились в транзакции, то вся транзакция откатывается, и флаги изменения у записей не сбрасываются. Если возникает какая-либо ошибка, и изменения проводились не в транзакции, и не выставлен флаг mfFull, то система отрабатывает до первой ошибки. В противном случае происходит проход по всем изменениям. В любом случае, флаги изменения сбрасываются у тех записей, которые были успешно изменены.

Для получения флага наличия изменений записи используется функция mtGetModify.

Для получения удаленных записей используются функции mtFirstDeleted и mtNextDeleted.

Режим сохранения удаленных записей (обработка функциями mtFirstDeleted и mtNextDeleted) для структур в памяти (созданных с помощью table struct) должен быть включен вызовом mtChangeOptions.

Для получения кода последней ошибки, произошедшей при операциях модификации необходимо использовать функцию GetLastError.

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

Или комбинацией функций mtFirstRecError и mtNextRecError. Эти две функции работают последовательным перебором и пользуются функцией mtGetRecError.

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

При наполнении таблицы в памяти данными посредством insert может возникнуть необходимость автоматического заполнения значениями некоторых полей. По умолчанию, драйвер таблицы в памяти заполняет эти поля значениями по своему усмотрению. В т.ч. стандартный заголовок не заполняется совсем, автоинкрементные поля заполняются по алгоритму: максимальное значение плюс 1, NRec'и заполняются по такому же алгоритму, без учета номера офиса.

Однако, если используется режим открытия fmWriteThru, то значения этих полей будут подсчитываться из БД. Так как все эти поля реально формируются сервером БД непосредственно в процессе выполнения insert, то не вставляя запись в БД нет возможности получить значения таких полей. Исключение составляет NRec, для которого существуют механизмы, позволяющие получить его значение перед вставкой записи. Для того, что бы формировать корректные значения NRec при вставке записи в таблицу в памяти, в соответствии с текущим офисом и реальными данными в БД, необходимо вызвать функцию mtGetNextNrec.

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

Версия

Атлантис 5.00.04.