ВРЕМЕННЫЕ И РАБОЧИЕ ТАБЛИЦЫ

Для решения определенных задач, например для формирования отчета, в котором необходимо выводить данные из различных таблиц, удобно было бы сначала все данные собрать в отдельной таблице. Создавать подобные таблицы в базе данных крайне нецелесообразно. Для этого в OpenEdge ABL могут быть объявлены рабочие и временные таблицы. Данные таблицы создаются только на время выполнения процедуры в котором они были объявлены и доступны только в пределах клиентской сессии.


ВРЕМЕННЫЕ ТАБЛИЦЫ


Временные таблицы очень схожи с таблицами баз данных, но в отличие от них не поддерживают многопользовательский режим и SQL-запросы. Располагаются временные таблицы во временном файле, создаваемом в рабочем каталоге пользователя, или в каталоге указанном в параметре -T, если он был определен при старте базы данных.

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

Объявление статической временной таблицы:

DEFINE {[[NEW [GLOBAL]] SHARED] |
         [PRIVATE | PROTECTED ] [STATIC]}
  TEMP-TABLE temp-table-name [NO-UNDO]
  [NAMESPACE-URI namespace] [NAMESPACE-PREFIX prefix]
  [XML-NODE-NAME node-name] [SERIALIZE-NAME serialize-name]
  [REFERENCE-ONLY]
  [LIKE table-name
    [VALIDATE]
    [USE-INDEX index-name [AS PRIMARY]] ...]
  [LIKE-SEQUENTIAL table-name
    [VALIDATE]
    [USE-INDEX index-name [AS PRIMARY]] ...]
  [RCODE-INFORMATION ]
  [BEFORE-TABLE before-table-name]
  [FIELD field-name
    {AS data-type | LIKE field [VALIDATE]}
    [field-options]
  ] ...
  [INDEX index-name
    [[AS | IS] [UNIQUE] [PRIMARY] [WORD-INDEX]]
    {index-field [ ASCENDING | DESCENDING]} ...
  ] ...

  • temp-table-name - имя (идентификатор) таблицы;
  • field-name - имя поля таблицы;
  • data-type - тип данных поля;
  • field-options - атрибуты полей таблицы;
  • index-name - идентификатор индекса;
  • index-field - поле таблицы составляющее индекс.
DEF TEMP-TABLE tt-acct NO-UNDO
FIELD client-name AS CHAR
FIELD open-date AS DATE
FIELD close-date AS DATE
FIELD bal-acct AS INTEGER

   FIELD acct AS CHAR
FIELD amount AS DEC
.

Атрибуты, а также типы данных полей временных таблиц идентичны атрибутам и типам данных полей таблиц базы данных.

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

[INDEX index-name [AS | IS] [UNIQUE] [PRIMARY] [WORD-INDEX]
       index-field] [ASCENDING | DESCENDING]...

При этом задается идентификатор индекса index-name, его тип, а так же определяются поля, составляющие его.

DEF TEMP-TABLE tt-acct NO-UNDO
FIELD client-name AS CHAR
FIELD open-date AS DATE
FIELD close-date AS DATE
FIELD bal-acct AS INT
   FIELD acct AS CHAR
FIELD amount AS DEC
INDEX idx-open open-date
INDEX idx-amt bal-acct DESCENDING
amount
INDEX idx-bal bal-acct IS PRIMARY
.

Опции ASCENDING и DESCENDING поля составляющего индекс определяют сортировку записей по этому полю. ASCENDING определяет восходящий порядок сортировки, а DESCENDING - нисходящий.

Если опция сортировки не определена для поля индекса, то для этого поля будет применяться сортировка предыдущего поля индекса. Если предыдущего поля нет, то по умолчанию применяется восходящая сортировка. Так в индексе idx-amt для поля amount будет применятся сортировка DESCENDING с предыдущего ему поля bal-acct, а в индексе idx-open записи будут отсортированы в восходящем порядке по полю open-date.

Описание типов индекса UNIQUE, PRIMARY и WORD-INDEX подробно дано в статье Индексы. Отметим лишь то, что если для таблицы определен всего один индекс, то он по умолчанию будет являться PRIMARY индексом.

Временная таблица так же может быть объявлена подобием любой другой существующей таблицы.

DEF TEMP-TABLE temp-table-name LIKE table-name.

Таким образом, создается таблица temp-table-name, являющаяся подобием таблицы table-name и принимающая  все ее поля с их атрибутами, а так же все ее индексы.

Если при объявлении временной таблицы, подобием другой таблицы, необходимо копировать не все индексы, то опция USE-INDEX позволяет явно указать индексы, которые необходимо копировать, остальные индексы при этом скопированы не будут. Если при копировании индексов был скопирован PRIMARY индекс исходной таблицы, то он по умолчанию и будет являться PRIMARY индексом объявляемой таблицы. Для переопределения PRIMARY индекса можно явно указать любой другой копируемый индекс AS PRIMARY.

DEF TEMP-TABLE temp-table-name LIKE table-name
   
USE-INDEX index-name AS PRIMARY.

Помимо этого, возможно объявление временной таблицы содержащей одно или более полей, являющихся подобием полей другой таблицы.

DEF TEMP-TABLE temp-table-name
    FIELD field-name LIKE field
                ...
.

Изначально, временная таблица доступна только в процедуре, в которой она была определена. Для более широкого ее использования, в процедуре, в которой определяется таблица она должна объявляться как NEW SHARED, или как NEW GLOBAL SHARED, а в процедуре в которой она так же будет использоваться как SHARED.

Объявление таблицы как NEW SHARED позволяет использовать ее в процедурах, напрямую или косвенно, вызванных процедурой породившей эту таблицу. Данная таблица будет доступна им до момента завершения процедуры, в которой она была объявлена.

NEW GLOBAL SHARED объявление позволяет использовать таблицу более широко - в рамках клиентской сессии. При этом таблица будет доступна процедурам до завершения клиентской сессии.

В процедуре, где объявляется таблица:

DEF NEW [GLOBAL] SHARED TEMP-TABLE temp-table-name.

В процедурах, где данная таблица будет использоваться:

DEF SHARED TEMP-TABLE temp-table-name.


РАБОТА С ДАННЫМИ ВРЕМЕННОЙ ТАБЛИЦЫ


Добавление, изменение и удаление записей временной таблицы аналогично описанию данному в статье Создание, удаление и редактирование записей.

Кроме этого, временная таблица является объектом ООП с набором атрибутов и методов по работе с ней. Работа с временной таблицей как с объектом осуществляется посредством ее указателя, получить который можно следующим образом:

temp-table-handle = TEMP-TABLE temp-table-name:HANDLE

где temp-table-handle - указатель временной таблицы, тип HANDLE.

Работа с временной таблицей как с объектом осуществляется посредством ее атрибутов и методов:

temp-table-handle [:attribute | :method]

Атрибуты:

Атрибут Тип данных Доступ Описание
ADM-DATA CHARACTER чтение/запись
AFTER-TABLE HANDLE чтение Содержит указатель на after-image таблицу, соответствующую befor-image таблицы
BEFORE-TABLE HANDLE чтение Содержит указатель на таблицу befor-image
DATA-SOURCE-MODIFIED LOGICAL чтение/запись
DEFAULT-BUFFER-HANDLE HANDLE чтение Содержит указатель на  создаваемый AVM по умолчанию буфер записи
DINAMIC LOGICAL чтение Логическое значение, отражающее является таблица динамической (TRUE), или статической (FALSE)
ERROR
ERROR-STRING
HANDLE HANDLE чтение
HAS-RECORDS LOGICAL чтение Логическое значение TRUE если таблица содержит записи и FALSE, если таблица пустая
INSTANTIATING-PROCEDURE HANDLE чтение Содержит указатель на процедуру, в которой таблица была создана
MIN-SCHEMA-MARSHAL LOGICAL чтение/запись
NAME CHARACTER чтение/запись Идентификатор таблицы
NAMESPACE-PREFIX
NAMESPACE-URI
NO-SCHEMA-MARSHAL
NUM-REFERENCES INTEGER  чтение
ORIGIN-HANDLE  HANDLE  чтение
PREPARED
PRIMARY
PRIVATE-DATA
REJECTED  LOGICAL  чтение/запись
SCHEMA-MARSHAL
SERIALIZE-NAME
TRACKING-CHANGES  LOGICAL  чтение/запись
TYPE CHARACTER чтение Тип объекта, для временной таблицы значение "TEMP-TABLE"
UNDO  LOGICAL чтение/запись Значение TRUE для таблицы в режиме UNDO и FALSE если NO-UNDO
UNIQUE-ID INTEGER чтение ID таблицы
XML-NODE-NAME  

Методы:

Метод Описание
CLEAR()  
CREATE-LIKE() копирование метасхемы другой таблицы
CREATE-LIKE-SEQUENTIAL()  
COPY-TEMP-TABLE() копирование записей другой таблицы
READ-JSON() импорт данных из JSON
WRITE-JSON() экспорт данных в JSON
READ-XMLSCHEMA() импорт XML-схемы
WRITE-XMLSCHEMA() экспорт XML-схемы
READ-XML() импорт данных их XML
WRITE-XML() экспорт данных в XML

МЕТОД COPY-TEMP-TABLE() осуществляет копирование в таблицу записей другой временной таблицы. 

trg-tt-handle:COPY-TEMP-TABLE(src-tt-handle
                             [,append-mode
                             [,replace-mode
                             [,loose-copy-mode
                             [,name prefix]]]]).

  • trg-tt-handle - идентификатор целевой таблицы в которую осуществляется копирование данных;
  • src-tt-handle - идентификатор исходной таблицы из которой осуществляется копирование данных.

Для иллюстрирования копирования данных создадим две временных таблицы tt-src и tt-trg. В таблице tt-trg создадим PRIMARY индекс.

DEF VAR i  AS INTEGER NO-UNDO.
DEF trgHdl AS HANDLE NO-UNDO.
DEF srcHdl AS HANDLE NO-UNDO.

DEF TEMP-TABLE tt-trg NO-UNDO
   FIELD id   AS INTEGER
   FIELD city AS CHAR
   INDEX j    AS PRIMARY id  
.
trgHdl = TEMP-TABLE tt-trg:HANDLE.

DEF TEMP-TABLE tt-src NO-UNDO
   FIELD id   AS INTEGER
   FIELD city  AS CHAR
.
srcHdl = TEMP-TABLE:HANDLE.

Предположим, что наши таблицы заполнены и нам необходимо свести данные этих таблиц в одну:

tt-trg  tt-src
 id  city  id  city
58 Пенза   63 Samara
64 Саратов   68 Tambov
69 Тверь  69 Tver
70  Томск  70 Tomsk
77  Москва  77 Moscow

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


APPEND-MODE

Логическое значение включающее (TRUE), или выключающее (FALSE) режим слияния записей таблиц. По умолчанию имеет значение FALSE.

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

Осуществим копирование записей таблицы tt-src в таблицу tt-trg в режиме APPEND-MODE:

trgHdl:COPY-TEMP-TABLE(srcHdl, 
TRUE).

Результат:

tt-trg
id city
58 Пенза
63 Samara
64 Саратов
68 Tambov
69 Tver
69 Тверь
70 Tomsk
70 Томск
77 Moscow
77 Москва

Как мы видим, все записи исходной таблицы (tt-src) добавились в целевую таблицу (tt-trg). При этом в целевой таблице образовались задвоенные записи с одинаковыми значениями в поле ID.

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

Изменим в таблице tt-trg индекс j c PRIMARY на UNIQUE и повторим копирование.

Результат:

tt-trg
id city
58 Пенза
63 Samara
64 Саратов
68 Tambov
69 Тверь
70 Томск
77 Москва

Теперь в целевую таблицу добавились только те записи из исходной таблицы, у которых поле ID не совпадает ни с одной записью в целевой.

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


REPLACE-MODE

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

trgHdl:COPY-TEMP-TABLE(srcHdl,
FALSE,
TRUE).

Результат:

tt-trg
id city
58 Пенза
63 Samara
64 Саратов
68 Tambov
69 Tver
70 Tomsk
77 Moscow

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


LOOSE-COPY-MODE

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

Добавим и заполним в целевой таблице еще одно поле phonecode (телефонный код).

DEF VAR i  AS INTEGER NO-UNDO.
DEF trgHdl AS HANDLE NO-UNDO.
DEF srcHdl AS HANDLE NO-UNDO.

DEF TEMP-TABLE tt-trg NO-UNDO

   FIELD id   AS INTEGER
   FIELD city  AS CHAR
   FIELD phonecode AS CHAR
   INDEX j AS UNIQUE id    
.
trgHdl = TEMP-TABLE tt-trg:HANDLE.

DEF TEMP-TABLE tt-src NO-UNDO

   FIELD id   AS INTEGER
   FIELD city  AS CHAR
.
srcHdl = TEMP-TABLE:HANDLE.
    
trgHdl:COPY-TEMP-TABLE(srcHdl,
                       TRUE,
                       FALSE,
                       TRUE).

Результат:

tt-trg
id city phonecode
58 Пенза   8412
63 Samara  
64 Саратов   8452
68 Tambov  
69 Тверь   4822
70 Томск  3822
77 Москва  495

Таким образом, будет осуществлен мэпинг данных, совпадающих по именам полей исходной таблицы в целевую.           


РАБОЧИЕ ТАБЛИЦЫ


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

Еще одним недостатком рабочих таблиц по сравнению с временными таблицами является то, что рабочие таблицы не могут иметь индексов. В связи с этим оператор поиска FIND может использоваться только в сочетании с FIRST, LAST, NEXT и PREV.

Объявление рабочей таблицы:

DEF WORK-TABLE wt-name 
   FIELD field AS data-type
            ...
.

Как мы видим, объявление рабочей таблицы аналогично объявлению временной. Так же аналогично объявление рабочей таблицы и ее полей подобием другой таблицы и полей посредством LIKE.

DEF WORK-TABLE wt-name LIKE org-table-name.
                ...
.

DEF WORK-TABLE wt-name
   FIELD field LIKE org-table-name.field-name
                       ...
.

Для более широкого применения рабочей таблицы возможно ее определение как NEW SHARED. Область доступности рабочей таблицы объявленной как NEW SHARED аналогична области доступности NEW SHARED временной таблицы, но в отличие от временной таблицы, рабочая таблица не может быть объявлена как NEW GLOBAL SHARED.

Добавление, изменение и удаление записей рабочей таблицы аналогично описанию данному в статье Создание, удаление и редактирование записей.

Вы здесь: Главная Основы ABL ВРЕМЕННЫЕ И РАБОЧИЕ ТАБЛИЦЫ